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$");
   32 
   33 /*
   34  * Note that this file is compiled into the kernel and into libc.
   35  */
   36 
   37 #ifdef _KERNEL
   38 #include <sys/types.h>
   39 #include <sys/capsicum.h>
   40 #include <sys/systm.h>
   41 
   42 #include <machine/stdarg.h>
   43 #else   /* !_KERNEL */
   44 #include <sys/types.h>
   45 #include <sys/capsicum.h>
   46 
   47 #include <assert.h>
   48 #include <stdarg.h>
   49 #include <stdbool.h>
   50 #include <stdint.h>
   51 #include <string.h>
   52 #endif
   53 
   54 #ifdef _KERNEL
   55 #define assert(exp)     KASSERT((exp), ("%s:%u", __func__, __LINE__))
   56 #endif
   57 
   58 #define CAPARSIZE_MIN   (CAP_RIGHTS_VERSION_00 + 2)
   59 #define CAPARSIZE_MAX   (CAP_RIGHTS_VERSION + 2)
   60 
   61 static __inline int
   62 right_to_index(uint64_t right)
   63 {
   64         static const int bit2idx[] = {
   65                 -1, 0, 1, -1, 2, -1, -1, -1, 3, -1, -1, -1, -1, -1, -1, -1,
   66                 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
   67         };
   68         int idx;
   69 
   70         idx = CAPIDXBIT(right);
   71         assert(idx >= 0 && idx < sizeof(bit2idx) / sizeof(bit2idx[0]));
   72         return (bit2idx[idx]);
   73 }
   74 
   75 static void
   76 cap_rights_vset(cap_rights_t *rights, va_list ap)
   77 {
   78         uint64_t right;
   79         int i, n;
   80 
   81         assert(CAPVER(rights) == CAP_RIGHTS_VERSION_00);
   82 
   83         n = CAPARSIZE(rights);
   84         assert(n >= CAPARSIZE_MIN && n <= CAPARSIZE_MAX);
   85 
   86         for (;;) {
   87                 right = (uint64_t)va_arg(ap, unsigned long long);
   88                 if (right == 0)
   89                         break;
   90                 assert(CAPRVER(right) == 0);
   91                 i = right_to_index(right);
   92                 assert(i >= 0);
   93                 assert(i < n);
   94                 assert(CAPIDXBIT(rights->cr_rights[i]) == CAPIDXBIT(right));
   95                 rights->cr_rights[i] |= right;
   96                 assert(CAPIDXBIT(rights->cr_rights[i]) == CAPIDXBIT(right));
   97         }
   98 }
   99 
  100 static void
  101 cap_rights_vclear(cap_rights_t *rights, va_list ap)
  102 {
  103         uint64_t right;
  104         int i, n;
  105 
  106         assert(CAPVER(rights) == CAP_RIGHTS_VERSION_00);
  107 
  108         n = CAPARSIZE(rights);
  109         assert(n >= CAPARSIZE_MIN && n <= CAPARSIZE_MAX);
  110 
  111         for (;;) {
  112                 right = (uint64_t)va_arg(ap, unsigned long long);
  113                 if (right == 0)
  114                         break;
  115                 assert(CAPRVER(right) == 0);
  116                 i = right_to_index(right);
  117                 assert(i >= 0);
  118                 assert(i < n);
  119                 assert(CAPIDXBIT(rights->cr_rights[i]) == CAPIDXBIT(right));
  120                 rights->cr_rights[i] &= ~(right & 0x01FFFFFFFFFFFFFFULL);
  121                 assert(CAPIDXBIT(rights->cr_rights[i]) == CAPIDXBIT(right));
  122         }
  123 }
  124 
  125 static bool
  126 cap_rights_is_vset(const cap_rights_t *rights, va_list ap)
  127 {
  128         uint64_t right;
  129         int i, n;
  130 
  131         assert(CAPVER(rights) == CAP_RIGHTS_VERSION_00);
  132 
  133         n = CAPARSIZE(rights);
  134         assert(n >= CAPARSIZE_MIN && n <= CAPARSIZE_MAX);
  135 
  136         for (;;) {
  137                 right = (uint64_t)va_arg(ap, unsigned long long);
  138                 if (right == 0)
  139                         break;
  140                 assert(CAPRVER(right) == 0);
  141                 i = right_to_index(right);
  142                 assert(i >= 0);
  143                 assert(i < n);
  144                 assert(CAPIDXBIT(rights->cr_rights[i]) == CAPIDXBIT(right));
  145                 if ((rights->cr_rights[i] & right) != right)
  146                         return (false);
  147         }
  148 
  149         return (true);
  150 }
  151 
  152 cap_rights_t *
  153 __cap_rights_init(int version, cap_rights_t *rights, ...)
  154 {
  155         unsigned int n;
  156         va_list ap;
  157 
  158         assert(version == CAP_RIGHTS_VERSION_00);
  159 
  160         n = version + 2;
  161         assert(n >= CAPARSIZE_MIN && n <= CAPARSIZE_MAX);
  162         memset(rights->cr_rights, 0, sizeof(rights->cr_rights[0]) * n);
  163         CAP_NONE(rights);
  164         va_start(ap, rights);
  165         cap_rights_vset(rights, ap);
  166         va_end(ap);
  167 
  168         return (rights);
  169 }
  170 
  171 cap_rights_t *
  172 __cap_rights_set(cap_rights_t *rights, ...)
  173 {
  174         va_list ap;
  175 
  176         assert(CAPVER(rights) == CAP_RIGHTS_VERSION_00);
  177 
  178         va_start(ap, rights);
  179         cap_rights_vset(rights, ap);
  180         va_end(ap);
  181 
  182         return (rights);
  183 }
  184 
  185 cap_rights_t *
  186 __cap_rights_clear(cap_rights_t *rights, ...)
  187 {
  188         va_list ap;
  189 
  190         assert(CAPVER(rights) == CAP_RIGHTS_VERSION_00);
  191 
  192         va_start(ap, rights);
  193         cap_rights_vclear(rights, ap);
  194         va_end(ap);
  195 
  196         return (rights);
  197 }
  198 
  199 bool
  200 __cap_rights_is_set(const cap_rights_t *rights, ...)
  201 {
  202         va_list ap;
  203         bool ret;
  204 
  205         assert(CAPVER(rights) == CAP_RIGHTS_VERSION_00);
  206 
  207         va_start(ap, rights);
  208         ret = cap_rights_is_vset(rights, ap);
  209         va_end(ap);
  210 
  211         return (ret);
  212 }
  213 
  214 bool
  215 cap_rights_is_valid(const cap_rights_t *rights)
  216 {
  217         cap_rights_t allrights;
  218         int i, j;
  219 
  220         if (CAPVER(rights) != CAP_RIGHTS_VERSION_00)
  221                 return (false);
  222         if (CAPARSIZE(rights) < CAPARSIZE_MIN ||
  223             CAPARSIZE(rights) > CAPARSIZE_MAX) {
  224                 return (false);
  225         }
  226         CAP_ALL(&allrights);
  227         if (!cap_rights_contains(&allrights, rights))
  228                 return (false);
  229         for (i = 0; i < CAPARSIZE(rights); i++) {
  230                 j = right_to_index(rights->cr_rights[i]);
  231                 if (i != j)
  232                         return (false);
  233                 if (i > 0) {
  234                         if (CAPRVER(rights->cr_rights[i]) != 0)
  235                                 return (false);
  236                 }
  237         }
  238 
  239         return (true);
  240 }
  241 
  242 cap_rights_t *
  243 cap_rights_merge(cap_rights_t *dst, const cap_rights_t *src)
  244 {
  245         unsigned int i, n;
  246 
  247         assert(CAPVER(dst) == CAP_RIGHTS_VERSION_00);
  248         assert(CAPVER(src) == CAP_RIGHTS_VERSION_00);
  249         assert(CAPVER(dst) == CAPVER(src));
  250         assert(cap_rights_is_valid(src));
  251         assert(cap_rights_is_valid(dst));
  252 
  253         n = CAPARSIZE(dst);
  254         assert(n >= CAPARSIZE_MIN && n <= CAPARSIZE_MAX);
  255 
  256         for (i = 0; i < n; i++)
  257                 dst->cr_rights[i] |= src->cr_rights[i];
  258 
  259         assert(cap_rights_is_valid(src));
  260         assert(cap_rights_is_valid(dst));
  261 
  262         return (dst);
  263 }
  264 
  265 cap_rights_t *
  266 cap_rights_remove(cap_rights_t *dst, const cap_rights_t *src)
  267 {
  268         unsigned int i, n;
  269 
  270         assert(CAPVER(dst) == CAP_RIGHTS_VERSION_00);
  271         assert(CAPVER(src) == CAP_RIGHTS_VERSION_00);
  272         assert(CAPVER(dst) == CAPVER(src));
  273         assert(cap_rights_is_valid(src));
  274         assert(cap_rights_is_valid(dst));
  275 
  276         n = CAPARSIZE(dst);
  277         assert(n >= CAPARSIZE_MIN && n <= CAPARSIZE_MAX);
  278 
  279         for (i = 0; i < n; i++) {
  280                 dst->cr_rights[i] &=
  281                     ~(src->cr_rights[i] & 0x01FFFFFFFFFFFFFFULL);
  282         }
  283 
  284         assert(cap_rights_is_valid(src));
  285         assert(cap_rights_is_valid(dst));
  286 
  287         return (dst);
  288 }
  289 
  290 bool
  291 cap_rights_contains(const cap_rights_t *big, const cap_rights_t *little)
  292 {
  293         unsigned int i, n;
  294 
  295         assert(CAPVER(big) == CAP_RIGHTS_VERSION_00);
  296         assert(CAPVER(little) == CAP_RIGHTS_VERSION_00);
  297         assert(CAPVER(big) == CAPVER(little));
  298 
  299         n = CAPARSIZE(big);
  300         assert(n >= CAPARSIZE_MIN && n <= CAPARSIZE_MAX);
  301 
  302         for (i = 0; i < n; i++) {
  303                 if ((big->cr_rights[i] & little->cr_rights[i]) !=
  304                     little->cr_rights[i]) {
  305                         return (false);
  306                 }
  307         }
  308 
  309         return (true);
  310 }

Cache object: 153fa2a7ab6b0322404c50c91c9a74c7


[ 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.