diff options
author | Steve French <sfrench@us.ibm.com> | 2008-02-06 11:04:00 -0500 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2008-02-06 11:04:00 -0500 |
commit | f315ccb3e679f271583f2a4f463ad9b65665b751 (patch) | |
tree | 44eb52102587d7b0bb592464cef6ec04bcac8b90 /include/linux/capability.h | |
parent | ead03e30b050d6dda769e7e9b071c5fa720bf8d2 (diff) | |
parent | 551e4fb2465b87de9d4aa1669b27d624435443bb (diff) |
Merge branch 'master' of /pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'include/linux/capability.h')
-rw-r--r-- | include/linux/capability.h | 251 |
1 files changed, 184 insertions, 67 deletions
diff --git a/include/linux/capability.h b/include/linux/capability.h index bb017edffd56..7d50ff6d269f 100644 --- a/include/linux/capability.h +++ b/include/linux/capability.h | |||
@@ -14,7 +14,6 @@ | |||
14 | #define _LINUX_CAPABILITY_H | 14 | #define _LINUX_CAPABILITY_H |
15 | 15 | ||
16 | #include <linux/types.h> | 16 | #include <linux/types.h> |
17 | #include <linux/compiler.h> | ||
18 | 17 | ||
19 | struct task_struct; | 18 | struct task_struct; |
20 | 19 | ||
@@ -23,13 +22,20 @@ struct task_struct; | |||
23 | kernel might be somewhat backwards compatible, but don't bet on | 22 | kernel might be somewhat backwards compatible, but don't bet on |
24 | it. */ | 23 | it. */ |
25 | 24 | ||
26 | /* XXX - Note, cap_t, is defined by POSIX to be an "opaque" pointer to | 25 | /* Note, cap_t, is defined by POSIX (draft) to be an "opaque" pointer to |
27 | a set of three capability sets. The transposition of 3*the | 26 | a set of three capability sets. The transposition of 3*the |
28 | following structure to such a composite is better handled in a user | 27 | following structure to such a composite is better handled in a user |
29 | library since the draft standard requires the use of malloc/free | 28 | library since the draft standard requires the use of malloc/free |
30 | etc.. */ | 29 | etc.. */ |
31 | 30 | ||
32 | #define _LINUX_CAPABILITY_VERSION 0x19980330 | 31 | #define _LINUX_CAPABILITY_VERSION_1 0x19980330 |
32 | #define _LINUX_CAPABILITY_U32S_1 1 | ||
33 | |||
34 | #define _LINUX_CAPABILITY_VERSION_2 0x20071026 | ||
35 | #define _LINUX_CAPABILITY_U32S_2 2 | ||
36 | |||
37 | #define _LINUX_CAPABILITY_VERSION _LINUX_CAPABILITY_VERSION_2 | ||
38 | #define _LINUX_CAPABILITY_U32S _LINUX_CAPABILITY_U32S_2 | ||
33 | 39 | ||
34 | typedef struct __user_cap_header_struct { | 40 | typedef struct __user_cap_header_struct { |
35 | __u32 version; | 41 | __u32 version; |
@@ -42,41 +48,42 @@ typedef struct __user_cap_data_struct { | |||
42 | __u32 inheritable; | 48 | __u32 inheritable; |
43 | } __user *cap_user_data_t; | 49 | } __user *cap_user_data_t; |
44 | 50 | ||
51 | |||
45 | #define XATTR_CAPS_SUFFIX "capability" | 52 | #define XATTR_CAPS_SUFFIX "capability" |
46 | #define XATTR_NAME_CAPS XATTR_SECURITY_PREFIX XATTR_CAPS_SUFFIX | 53 | #define XATTR_NAME_CAPS XATTR_SECURITY_PREFIX XATTR_CAPS_SUFFIX |
47 | 54 | ||
48 | #define XATTR_CAPS_SZ (3*sizeof(__le32)) | ||
49 | #define VFS_CAP_REVISION_MASK 0xFF000000 | 55 | #define VFS_CAP_REVISION_MASK 0xFF000000 |
56 | #define VFS_CAP_FLAGS_MASK ~VFS_CAP_REVISION_MASK | ||
57 | #define VFS_CAP_FLAGS_EFFECTIVE 0x000001 | ||
58 | |||
50 | #define VFS_CAP_REVISION_1 0x01000000 | 59 | #define VFS_CAP_REVISION_1 0x01000000 |
60 | #define VFS_CAP_U32_1 1 | ||
61 | #define XATTR_CAPS_SZ_1 (sizeof(__le32)*(1 + 2*VFS_CAP_U32_1)) | ||
51 | 62 | ||
52 | #define VFS_CAP_REVISION VFS_CAP_REVISION_1 | 63 | #define VFS_CAP_REVISION_2 0x02000000 |
64 | #define VFS_CAP_U32_2 2 | ||
65 | #define XATTR_CAPS_SZ_2 (sizeof(__le32)*(1 + 2*VFS_CAP_U32_2)) | ||
66 | |||
67 | #define XATTR_CAPS_SZ XATTR_CAPS_SZ_2 | ||
68 | #define VFS_CAP_U32 VFS_CAP_U32_2 | ||
69 | #define VFS_CAP_REVISION VFS_CAP_REVISION_2 | ||
53 | 70 | ||
54 | #define VFS_CAP_FLAGS_MASK ~VFS_CAP_REVISION_MASK | ||
55 | #define VFS_CAP_FLAGS_EFFECTIVE 0x000001 | ||
56 | 71 | ||
57 | struct vfs_cap_data { | 72 | struct vfs_cap_data { |
58 | __u32 magic_etc; /* Little endian */ | 73 | __le32 magic_etc; /* Little endian */ |
59 | __u32 permitted; /* Little endian */ | 74 | struct { |
60 | __u32 inheritable; /* Little endian */ | 75 | __le32 permitted; /* Little endian */ |
76 | __le32 inheritable; /* Little endian */ | ||
77 | } data[VFS_CAP_U32]; | ||
61 | }; | 78 | }; |
62 | 79 | ||
63 | #ifdef __KERNEL__ | 80 | #ifdef __KERNEL__ |
64 | 81 | ||
65 | /* #define STRICT_CAP_T_TYPECHECKS */ | ||
66 | |||
67 | #ifdef STRICT_CAP_T_TYPECHECKS | ||
68 | |||
69 | typedef struct kernel_cap_struct { | 82 | typedef struct kernel_cap_struct { |
70 | __u32 cap; | 83 | __u32 cap[_LINUX_CAPABILITY_U32S]; |
71 | } kernel_cap_t; | 84 | } kernel_cap_t; |
72 | 85 | ||
73 | #else | 86 | #define _USER_CAP_HEADER_SIZE (sizeof(struct __user_cap_header_struct)) |
74 | |||
75 | typedef __u32 kernel_cap_t; | ||
76 | |||
77 | #endif | ||
78 | |||
79 | #define _USER_CAP_HEADER_SIZE (2*sizeof(__u32)) | ||
80 | #define _KERNEL_CAP_T_SIZE (sizeof(kernel_cap_t)) | 87 | #define _KERNEL_CAP_T_SIZE (sizeof(kernel_cap_t)) |
81 | 88 | ||
82 | #endif | 89 | #endif |
@@ -119,10 +126,6 @@ typedef __u32 kernel_cap_t; | |||
119 | 126 | ||
120 | #define CAP_FSETID 4 | 127 | #define CAP_FSETID 4 |
121 | 128 | ||
122 | /* Used to decide between falling back on the old suser() or fsuser(). */ | ||
123 | |||
124 | #define CAP_FS_MASK 0x1f | ||
125 | |||
126 | /* Overrides the restriction that the real or effective user ID of a | 129 | /* Overrides the restriction that the real or effective user ID of a |
127 | process sending a signal must match the real or effective user ID | 130 | process sending a signal must match the real or effective user ID |
128 | of the process receiving the signal. */ | 131 | of the process receiving the signal. */ |
@@ -145,8 +148,14 @@ typedef __u32 kernel_cap_t; | |||
145 | ** Linux-specific capabilities | 148 | ** Linux-specific capabilities |
146 | **/ | 149 | **/ |
147 | 150 | ||
148 | /* Transfer any capability in your permitted set to any pid, | 151 | /* Without VFS support for capabilities: |
149 | remove any capability in your permitted set from any pid */ | 152 | * Transfer any capability in your permitted set to any pid, |
153 | * remove any capability in your permitted set from any pid | ||
154 | * With VFS support for capabilities (neither of above, but) | ||
155 | * Add any capability from current's capability bounding set | ||
156 | * to the current process' inheritable set | ||
157 | * Allow taking bits out of capability bounding set | ||
158 | */ | ||
150 | 159 | ||
151 | #define CAP_SETPCAP 8 | 160 | #define CAP_SETPCAP 8 |
152 | 161 | ||
@@ -195,7 +204,6 @@ typedef __u32 kernel_cap_t; | |||
195 | #define CAP_IPC_OWNER 15 | 204 | #define CAP_IPC_OWNER 15 |
196 | 205 | ||
197 | /* Insert and remove kernel modules - modify kernel without limit */ | 206 | /* Insert and remove kernel modules - modify kernel without limit */ |
198 | /* Modify cap_bset */ | ||
199 | #define CAP_SYS_MODULE 16 | 207 | #define CAP_SYS_MODULE 16 |
200 | 208 | ||
201 | /* Allow ioperm/iopl access */ | 209 | /* Allow ioperm/iopl access */ |
@@ -307,74 +315,183 @@ typedef __u32 kernel_cap_t; | |||
307 | 315 | ||
308 | #define CAP_SETFCAP 31 | 316 | #define CAP_SETFCAP 31 |
309 | 317 | ||
318 | /* Override MAC access. | ||
319 | The base kernel enforces no MAC policy. | ||
320 | An LSM may enforce a MAC policy, and if it does and it chooses | ||
321 | to implement capability based overrides of that policy, this is | ||
322 | the capability it should use to do so. */ | ||
323 | |||
324 | #define CAP_MAC_OVERRIDE 32 | ||
325 | |||
326 | /* Allow MAC configuration or state changes. | ||
327 | The base kernel requires no MAC configuration. | ||
328 | An LSM may enforce a MAC policy, and if it does and it chooses | ||
329 | to implement capability based checks on modifications to that | ||
330 | policy or the data required to maintain it, this is the | ||
331 | capability it should use to do so. */ | ||
332 | |||
333 | #define CAP_MAC_ADMIN 33 | ||
334 | |||
335 | #define CAP_LAST_CAP CAP_MAC_ADMIN | ||
336 | |||
337 | #define cap_valid(x) ((x) >= 0 && (x) <= CAP_LAST_CAP) | ||
338 | |||
339 | /* | ||
340 | * Bit location of each capability (used by user-space library and kernel) | ||
341 | */ | ||
342 | |||
343 | #define CAP_TO_INDEX(x) ((x) >> 5) /* 1 << 5 == bits in __u32 */ | ||
344 | #define CAP_TO_MASK(x) (1 << ((x) & 31)) /* mask for indexed __u32 */ | ||
345 | |||
310 | #ifdef __KERNEL__ | 346 | #ifdef __KERNEL__ |
311 | 347 | ||
312 | /* | 348 | /* |
313 | * Internal kernel functions only | 349 | * Internal kernel functions only |
314 | */ | 350 | */ |
315 | 351 | ||
316 | #ifdef STRICT_CAP_T_TYPECHECKS | 352 | #define CAP_FOR_EACH_U32(__capi) \ |
353 | for (__capi = 0; __capi < _LINUX_CAPABILITY_U32S; ++__capi) | ||
354 | |||
355 | # define CAP_FS_MASK_B0 (CAP_TO_MASK(CAP_CHOWN) \ | ||
356 | | CAP_TO_MASK(CAP_DAC_OVERRIDE) \ | ||
357 | | CAP_TO_MASK(CAP_DAC_READ_SEARCH) \ | ||
358 | | CAP_TO_MASK(CAP_FOWNER) \ | ||
359 | | CAP_TO_MASK(CAP_FSETID)) | ||
360 | |||
361 | # define CAP_FS_MASK_B1 (CAP_TO_MASK(CAP_MAC_OVERRIDE)) | ||
362 | |||
363 | #if _LINUX_CAPABILITY_U32S != 2 | ||
364 | # error Fix up hand-coded capability macro initializers | ||
365 | #else /* HAND-CODED capability initializers */ | ||
366 | |||
367 | # define CAP_EMPTY_SET {{ 0, 0 }} | ||
368 | # define CAP_FULL_SET {{ ~0, ~0 }} | ||
369 | # define CAP_INIT_EFF_SET {{ ~CAP_TO_MASK(CAP_SETPCAP), ~0 }} | ||
370 | # define CAP_FS_SET {{ CAP_FS_MASK_B0, CAP_FS_MASK_B1 } } | ||
371 | # define CAP_NFSD_SET {{ CAP_FS_MASK_B0|CAP_TO_MASK(CAP_SYS_RESOURCE), \ | ||
372 | CAP_FS_MASK_B1 } } | ||
373 | |||
374 | #endif /* _LINUX_CAPABILITY_U32S != 2 */ | ||
375 | |||
376 | #define CAP_INIT_INH_SET CAP_EMPTY_SET | ||
377 | |||
378 | # define cap_clear(c) do { (c) = __cap_empty_set; } while (0) | ||
379 | # define cap_set_full(c) do { (c) = __cap_full_set; } while (0) | ||
380 | # define cap_set_init_eff(c) do { (c) = __cap_init_eff_set; } while (0) | ||
381 | |||
382 | #define cap_raise(c, flag) ((c).cap[CAP_TO_INDEX(flag)] |= CAP_TO_MASK(flag)) | ||
383 | #define cap_lower(c, flag) ((c).cap[CAP_TO_INDEX(flag)] &= ~CAP_TO_MASK(flag)) | ||
384 | #define cap_raised(c, flag) ((c).cap[CAP_TO_INDEX(flag)] & CAP_TO_MASK(flag)) | ||
385 | |||
386 | #define CAP_BOP_ALL(c, a, b, OP) \ | ||
387 | do { \ | ||
388 | unsigned __capi; \ | ||
389 | CAP_FOR_EACH_U32(__capi) { \ | ||
390 | c.cap[__capi] = a.cap[__capi] OP b.cap[__capi]; \ | ||
391 | } \ | ||
392 | } while (0) | ||
393 | |||
394 | #define CAP_UOP_ALL(c, a, OP) \ | ||
395 | do { \ | ||
396 | unsigned __capi; \ | ||
397 | CAP_FOR_EACH_U32(__capi) { \ | ||
398 | c.cap[__capi] = OP a.cap[__capi]; \ | ||
399 | } \ | ||
400 | } while (0) | ||
401 | |||
402 | static inline kernel_cap_t cap_combine(const kernel_cap_t a, | ||
403 | const kernel_cap_t b) | ||
404 | { | ||
405 | kernel_cap_t dest; | ||
406 | CAP_BOP_ALL(dest, a, b, |); | ||
407 | return dest; | ||
408 | } | ||
317 | 409 | ||
318 | #define to_cap_t(x) { x } | 410 | static inline kernel_cap_t cap_intersect(const kernel_cap_t a, |
319 | #define cap_t(x) (x).cap | 411 | const kernel_cap_t b) |
412 | { | ||
413 | kernel_cap_t dest; | ||
414 | CAP_BOP_ALL(dest, a, b, &); | ||
415 | return dest; | ||
416 | } | ||
320 | 417 | ||
321 | #else | 418 | static inline kernel_cap_t cap_drop(const kernel_cap_t a, |
419 | const kernel_cap_t drop) | ||
420 | { | ||
421 | kernel_cap_t dest; | ||
422 | CAP_BOP_ALL(dest, a, drop, &~); | ||
423 | return dest; | ||
424 | } | ||
322 | 425 | ||
323 | #define to_cap_t(x) (x) | 426 | static inline kernel_cap_t cap_invert(const kernel_cap_t c) |
324 | #define cap_t(x) (x) | 427 | { |
428 | kernel_cap_t dest; | ||
429 | CAP_UOP_ALL(dest, c, ~); | ||
430 | return dest; | ||
431 | } | ||
325 | 432 | ||
326 | #endif | 433 | static inline int cap_isclear(const kernel_cap_t a) |
434 | { | ||
435 | unsigned __capi; | ||
436 | CAP_FOR_EACH_U32(__capi) { | ||
437 | if (a.cap[__capi] != 0) | ||
438 | return 0; | ||
439 | } | ||
440 | return 1; | ||
441 | } | ||
327 | 442 | ||
328 | #define CAP_EMPTY_SET to_cap_t(0) | 443 | static inline int cap_issubset(const kernel_cap_t a, const kernel_cap_t set) |
329 | #define CAP_FULL_SET to_cap_t(~0) | 444 | { |
330 | #define CAP_INIT_EFF_SET to_cap_t(~0 & ~CAP_TO_MASK(CAP_SETPCAP)) | 445 | kernel_cap_t dest; |
331 | #define CAP_INIT_INH_SET to_cap_t(0) | 446 | dest = cap_drop(a, set); |
447 | return cap_isclear(dest); | ||
448 | } | ||
332 | 449 | ||
333 | #define CAP_TO_MASK(x) (1 << (x)) | 450 | /* Used to decide between falling back on the old suser() or fsuser(). */ |
334 | #define cap_raise(c, flag) (cap_t(c) |= CAP_TO_MASK(flag)) | ||
335 | #define cap_lower(c, flag) (cap_t(c) &= ~CAP_TO_MASK(flag)) | ||
336 | #define cap_raised(c, flag) (cap_t(c) & CAP_TO_MASK(flag)) | ||
337 | 451 | ||
338 | static inline kernel_cap_t cap_combine(kernel_cap_t a, kernel_cap_t b) | 452 | static inline int cap_is_fs_cap(int cap) |
339 | { | 453 | { |
340 | kernel_cap_t dest; | 454 | const kernel_cap_t __cap_fs_set = CAP_FS_SET; |
341 | cap_t(dest) = cap_t(a) | cap_t(b); | 455 | return !!(CAP_TO_MASK(cap) & __cap_fs_set.cap[CAP_TO_INDEX(cap)]); |
342 | return dest; | ||
343 | } | 456 | } |
344 | 457 | ||
345 | static inline kernel_cap_t cap_intersect(kernel_cap_t a, kernel_cap_t b) | 458 | static inline kernel_cap_t cap_drop_fs_set(const kernel_cap_t a) |
346 | { | 459 | { |
347 | kernel_cap_t dest; | 460 | const kernel_cap_t __cap_fs_set = CAP_FS_SET; |
348 | cap_t(dest) = cap_t(a) & cap_t(b); | 461 | return cap_drop(a, __cap_fs_set); |
349 | return dest; | ||
350 | } | 462 | } |
351 | 463 | ||
352 | static inline kernel_cap_t cap_drop(kernel_cap_t a, kernel_cap_t drop) | 464 | static inline kernel_cap_t cap_raise_fs_set(const kernel_cap_t a, |
465 | const kernel_cap_t permitted) | ||
353 | { | 466 | { |
354 | kernel_cap_t dest; | 467 | const kernel_cap_t __cap_fs_set = CAP_FS_SET; |
355 | cap_t(dest) = cap_t(a) & ~cap_t(drop); | 468 | return cap_combine(a, |
356 | return dest; | 469 | cap_intersect(permitted, __cap_fs_set)); |
357 | } | 470 | } |
358 | 471 | ||
359 | static inline kernel_cap_t cap_invert(kernel_cap_t c) | 472 | static inline kernel_cap_t cap_drop_nfsd_set(const kernel_cap_t a) |
360 | { | 473 | { |
361 | kernel_cap_t dest; | 474 | const kernel_cap_t __cap_fs_set = CAP_NFSD_SET; |
362 | cap_t(dest) = ~cap_t(c); | 475 | return cap_drop(a, __cap_fs_set); |
363 | return dest; | ||
364 | } | 476 | } |
365 | 477 | ||
366 | #define cap_isclear(c) (!cap_t(c)) | 478 | static inline kernel_cap_t cap_raise_nfsd_set(const kernel_cap_t a, |
367 | #define cap_issubset(a,set) (!(cap_t(a) & ~cap_t(set))) | 479 | const kernel_cap_t permitted) |
368 | 480 | { | |
369 | #define cap_clear(c) do { cap_t(c) = 0; } while(0) | 481 | const kernel_cap_t __cap_nfsd_set = CAP_NFSD_SET; |
370 | #define cap_set_full(c) do { cap_t(c) = ~0; } while(0) | 482 | return cap_combine(a, |
371 | #define cap_mask(c,mask) do { cap_t(c) &= cap_t(mask); } while(0) | 483 | cap_intersect(permitted, __cap_nfsd_set)); |
484 | } | ||
372 | 485 | ||
373 | #define cap_is_fs_cap(c) (CAP_TO_MASK(c) & CAP_FS_MASK) | 486 | extern const kernel_cap_t __cap_empty_set; |
487 | extern const kernel_cap_t __cap_full_set; | ||
488 | extern const kernel_cap_t __cap_init_eff_set; | ||
374 | 489 | ||
375 | int capable(int cap); | 490 | int capable(int cap); |
376 | int __capable(struct task_struct *t, int cap); | 491 | int __capable(struct task_struct *t, int cap); |
377 | 492 | ||
493 | extern long cap_prctl_drop(unsigned long cap); | ||
494 | |||
378 | #endif /* __KERNEL__ */ | 495 | #endif /* __KERNEL__ */ |
379 | 496 | ||
380 | #endif /* !_LINUX_CAPABILITY_H */ | 497 | #endif /* !_LINUX_CAPABILITY_H */ |