The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/kern/subr_capability.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 2013 FreeBSD Foundation
    3  * All rights reserved.
    4  *
    5  * This software was developed by Pawel Jakub Dawidek under sponsorship from
    6  * the FreeBSD Foundation.
    7  *
    8  * Redistribution and use in source and binary forms, with or without
    9  * modification, are permitted provided that the following conditions
   10  * are met:
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice, this list of conditions and the following disclaimer.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in the
   15  *    documentation and/or other materials provided with the distribution.
   16  *
   17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   27  * SUCH DAMAGE.
   28  */
   29 
   30 #include <sys/cdefs.h>
   31 __FBSDID("$FreeBSD: releng/11.2/sys/kern/subr_capability.c 291553 2015-12-01 02:48:42Z mjg $");
   32 
   33 /*
   34  * Note that this file is compiled into the kernel and into libc.
   35  */
   36 
   37 #include <sys/types.h>
   38 #include <sys/capsicum.h>
   39 
   40 #ifdef _KERNEL
   41 #include <sys/systm.h>
   42 
   43 #include <machine/stdarg.h>
   44 #else   /* !_KERNEL */
   45 #include <assert.h>
   46 #include <stdarg.h>
   47 #include <stdbool.h>
   48 #include <stdint.h>
   49 #include <string.h>
   50 #endif
   51 
   52 #ifdef _KERNEL
   53 #define assert(exp)     KASSERT((exp), ("%s:%u", __func__, __LINE__))
   54 #endif
   55 
   56 #define CAPARSIZE_MIN   (CAP_RIGHTS_VERSION_00 + 2)
   57 #define CAPARSIZE_MAX   (CAP_RIGHTS_VERSION + 2)
   58 
   59 static __inline int
   60 right_to_index(uint64_t right)
   61 {
   62         static const int bit2idx[] = {
   63                 -1, 0, 1, -1, 2, -1, -1, -1, 3, -1, -1, -1, -1, -1, -1, -1,
   64                 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
   65         };
   66         int idx;
   67 
   68         idx = CAPIDXBIT(right);
   69         assert(idx >= 0 && idx < sizeof(bit2idx) / sizeof(bit2idx[0]));
   70         return (bit2idx[idx]);
   71 }
   72 
   73 static void
   74 cap_rights_vset(cap_rights_t *rights, va_list ap)
   75 {
   76         uint64_t right;
   77         int i, n;
   78 
   79         assert(CAPVER(rights) == CAP_RIGHTS_VERSION_00);
   80 
   81         n = CAPARSIZE(rights);
   82         assert(n >= CAPARSIZE_MIN && n <= CAPARSIZE_MAX);
   83 
   84         for (;;) {
   85                 right = (uint64_t)va_arg(ap, unsigned long long);
   86                 if (right == 0)
   87                         break;
   88                 assert(CAPRVER(right) == 0);
   89                 i = right_to_index(right);
   90                 assert(i >= 0);
   91                 assert(i < n);
   92                 assert(CAPIDXBIT(rights->cr_rights[i]) == CAPIDXBIT(right));
   93                 rights->cr_rights[i] |= right;
   94                 assert(CAPIDXBIT(rights->cr_rights[i]) == CAPIDXBIT(right));
   95         }
   96 }
   97 
   98 static void
   99 cap_rights_vclear(cap_rights_t *rights, va_list ap)
  100 {
  101         uint64_t right;
  102         int i, n;
  103 
  104         assert(CAPVER(rights) == CAP_RIGHTS_VERSION_00);
  105 
  106         n = CAPARSIZE(rights);
  107         assert(n >= CAPARSIZE_MIN && n <= CAPARSIZE_MAX);
  108 
  109         for (;;) {
  110                 right = (uint64_t)va_arg(ap, unsigned long long);
  111                 if (right == 0)
  112                         break;
  113                 assert(CAPRVER(right) == 0);
  114                 i = right_to_index(right);
  115                 assert(i >= 0);
  116                 assert(i < n);
  117                 assert(CAPIDXBIT(rights->cr_rights[i]) == CAPIDXBIT(right));
  118                 rights->cr_rights[i] &= ~(right & 0x01FFFFFFFFFFFFFFULL);
  119                 assert(CAPIDXBIT(rights->cr_rights[i]) == CAPIDXBIT(right));
  120         }
  121 }
  122 
  123 static bool
  124 cap_rights_is_vset(const cap_rights_t *rights, va_list ap)
  125 {
  126         uint64_t right;
  127         int i, n;
  128 
  129         assert(CAPVER(rights) == CAP_RIGHTS_VERSION_00);
  130 
  131         n = CAPARSIZE(rights);
  132         assert(n >= CAPARSIZE_MIN && n <= CAPARSIZE_MAX);
  133 
  134         for (;;) {
  135                 right = (uint64_t)va_arg(ap, unsigned long long);
  136                 if (right == 0)
  137                         break;
  138                 assert(CAPRVER(right) == 0);
  139                 i = right_to_index(right);
  140                 assert(i >= 0);
  141                 assert(i < n);
  142                 assert(CAPIDXBIT(rights->cr_rights[i]) == CAPIDXBIT(right));
  143                 if ((rights->cr_rights[i] & right) != right)
  144                         return (false);
  145         }
  146 
  147         return (true);
  148 }
  149 
  150 cap_rights_t *
  151 __cap_rights_init(int version, cap_rights_t *rights, ...)
  152 {
  153         unsigned int n;
  154         va_list ap;
  155 
  156         assert(version == CAP_RIGHTS_VERSION_00);
  157 
  158         n = version + 2;
  159         assert(n >= CAPARSIZE_MIN && n <= CAPARSIZE_MAX);
  160         CAP_NONE(rights);
  161         va_start(ap, rights);
  162         cap_rights_vset(rights, ap);
  163         va_end(ap);
  164 
  165         return (rights);
  166 }
  167 
  168 cap_rights_t *
  169 __cap_rights_set(cap_rights_t *rights, ...)
  170 {
  171         va_list ap;
  172 
  173         assert(CAPVER(rights) == CAP_RIGHTS_VERSION_00);
  174 
  175         va_start(ap, rights);
  176         cap_rights_vset(rights, ap);
  177         va_end(ap);
  178 
  179         return (rights);
  180 }
  181 
  182 cap_rights_t *
  183 __cap_rights_clear(cap_rights_t *rights, ...)
  184 {
  185         va_list ap;
  186 
  187         assert(CAPVER(rights) == CAP_RIGHTS_VERSION_00);
  188 
  189         va_start(ap, rights);
  190         cap_rights_vclear(rights, ap);
  191         va_end(ap);
  192 
  193         return (rights);
  194 }
  195 
  196 bool
  197 __cap_rights_is_set(const cap_rights_t *rights, ...)
  198 {
  199         va_list ap;
  200         bool ret;
  201 
  202         assert(CAPVER(rights) == CAP_RIGHTS_VERSION_00);
  203 
  204         va_start(ap, rights);
  205         ret = cap_rights_is_vset(rights, ap);
  206         va_end(ap);
  207 
  208         return (ret);
  209 }
  210 
  211 bool
  212 cap_rights_is_valid(const cap_rights_t *rights)
  213 {
  214         cap_rights_t allrights;
  215         int i, j;
  216 
  217         if (CAPVER(rights) != CAP_RIGHTS_VERSION_00)
  218                 return (false);
  219         if (CAPARSIZE(rights) < CAPARSIZE_MIN ||
  220             CAPARSIZE(rights) > CAPARSIZE_MAX) {
  221                 return (false);
  222         }
  223         CAP_ALL(&allrights);
  224         if (!cap_rights_contains(&allrights, rights))
  225                 return (false);
  226         for (i = 0; i < CAPARSIZE(rights); i++) {
  227                 j = right_to_index(rights->cr_rights[i]);
  228                 if (i != j)
  229                         return (false);
  230                 if (i > 0) {
  231                         if (CAPRVER(rights->cr_rights[i]) != 0)
  232                                 return (false);
  233                 }
  234         }
  235 
  236         return (true);
  237 }
  238 
  239 cap_rights_t *
  240 cap_rights_merge(cap_rights_t *dst, const cap_rights_t *src)
  241 {
  242         unsigned int i, n;
  243 
  244         assert(CAPVER(dst) == CAP_RIGHTS_VERSION_00);
  245         assert(CAPVER(src) == CAP_RIGHTS_VERSION_00);
  246         assert(CAPVER(dst) == CAPVER(src));
  247         assert(cap_rights_is_valid(src));
  248         assert(cap_rights_is_valid(dst));
  249 
  250         n = CAPARSIZE(dst);
  251         assert(n >= CAPARSIZE_MIN && n <= CAPARSIZE_MAX);
  252 
  253         for (i = 0; i < n; i++)
  254                 dst->cr_rights[i] |= src->cr_rights[i];
  255 
  256         assert(cap_rights_is_valid(src));
  257         assert(cap_rights_is_valid(dst));
  258 
  259         return (dst);
  260 }
  261 
  262 cap_rights_t *
  263 cap_rights_remove(cap_rights_t *dst, const cap_rights_t *src)
  264 {
  265         unsigned int i, n;
  266 
  267         assert(CAPVER(dst) == CAP_RIGHTS_VERSION_00);
  268         assert(CAPVER(src) == CAP_RIGHTS_VERSION_00);
  269         assert(CAPVER(dst) == CAPVER(src));
  270         assert(cap_rights_is_valid(src));
  271         assert(cap_rights_is_valid(dst));
  272 
  273         n = CAPARSIZE(dst);
  274         assert(n >= CAPARSIZE_MIN && n <= CAPARSIZE_MAX);
  275 
  276         for (i = 0; i < n; i++) {
  277                 dst->cr_rights[i] &=
  278                     ~(src->cr_rights[i] & 0x01FFFFFFFFFFFFFFULL);
  279         }
  280 
  281         assert(cap_rights_is_valid(src));
  282         assert(cap_rights_is_valid(dst));
  283 
  284         return (dst);
  285 }
  286 
  287 bool
  288 cap_rights_contains(const cap_rights_t *big, const cap_rights_t *little)
  289 {
  290         unsigned int i, n;
  291 
  292         assert(CAPVER(big) == CAP_RIGHTS_VERSION_00);
  293         assert(CAPVER(little) == CAP_RIGHTS_VERSION_00);
  294         assert(CAPVER(big) == CAPVER(little));
  295 
  296         n = CAPARSIZE(big);
  297         assert(n >= CAPARSIZE_MIN && n <= CAPARSIZE_MAX);
  298 
  299         for (i = 0; i < n; i++) {
  300                 if ((big->cr_rights[i] & little->cr_rights[i]) !=
  301                     little->cr_rights[i]) {
  302                         return (false);
  303                 }
  304         }
  305 
  306         return (true);
  307 }

Cache object: 071d87b7533429c7dbdf334d5cc777c9


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.