From 9b82013c3d4083faeb33ffbd775b7f9b16857a34 Mon Sep 17 00:00:00 2001 From: vitaly Date: Mon, 15 Sep 2008 18:44:54 +0000 Subject: [PATCH] Branch b1_6 b=15949 i=adilger i=shadow mds_body.capability fix --- lnet/include/libcfs/curproc.h | 33 +++++++++++++++- lnet/include/libcfs/darwin/darwin-prim.h | 4 -- lnet/include/libcfs/darwin/libcfs.h | 2 +- lnet/include/libcfs/winnt/winnt-prim.h | 5 --- lnet/libcfs/darwin/darwin-curproc.c | 19 +++++++-- lnet/libcfs/linux/linux-curproc.c | 67 +++++++++++++++++++++++++++++--- lnet/libcfs/linux/linux-module.c | 4 +- lnet/libcfs/lwt.c | 6 +-- lnet/libcfs/winnt/winnt-curproc.c | 47 +++++++++++++++++++--- lnet/libcfs/winnt/winnt-module.c | 4 +- lnet/utils/wirecheck.c | 14 +++++++ 11 files changed, 170 insertions(+), 35 deletions(-) diff --git a/lnet/include/libcfs/curproc.h b/lnet/include/libcfs/curproc.h index 3506201..0b9ae29 100644 --- a/lnet/include/libcfs/curproc.h +++ b/lnet/include/libcfs/curproc.h @@ -70,10 +70,39 @@ char *cfs_curproc_comm(void); * * cfs_kernel_cap_t */ -cfs_kernel_cap_t cfs_curproc_cap_get(void); -void cfs_curproc_cap_set(cfs_kernel_cap_t cap); #endif +typedef __u32 cfs_cap_t; + +#define CFS_CAP_CHOWN 0 +#define CFS_CAP_DAC_OVERRIDE 1 +#define CFS_CAP_DAC_READ_SEARCH 2 +#define CFS_CAP_FOWNER 3 +#define CFS_CAP_FSETID 4 +#define CFS_CAP_LINUX_IMMUTABLE 9 +#define CFS_CAP_SYS_ADMIN 21 +#define CFS_CAP_SYS_BOOT 23 +#define CFS_CAP_SYS_RESOURCE 24 + +#define CFS_CAP_FS_MASK ((1 << CFS_CAP_CHOWN) | \ + (1 << CFS_CAP_DAC_OVERRIDE) | \ + (1 << CFS_CAP_DAC_READ_SEARCH) | \ + (1 << CFS_CAP_FOWNER) | \ + (1 << CFS_CAP_FSETID ) | \ + (1 << CFS_CAP_LINUX_IMMUTABLE) | \ + (1 << CFS_CAP_SYS_ADMIN) | \ + (1 << CFS_CAP_SYS_BOOT) | \ + (1 << CFS_CAP_SYS_RESOURCE)) + +void cfs_cap_raise(cfs_cap_t cap); +void cfs_cap_lower(cfs_cap_t cap); +int cfs_cap_raised(cfs_cap_t cap); +void cfs_kernel_cap_pack(cfs_kernel_cap_t kcap, cfs_cap_t *cap); +void cfs_kernel_cap_unpack(cfs_kernel_cap_t *kcap, cfs_cap_t cap); +cfs_cap_t cfs_curproc_cap_pack(void); +void cfs_curproc_cap_unpack(cfs_cap_t cap); +int cfs_capable(cfs_cap_t cap); + /* __LIBCFS_CURPROC_H__ */ #endif /* diff --git a/lnet/include/libcfs/darwin/darwin-prim.h b/lnet/include/libcfs/darwin/darwin-prim.h index 2aa4450..1e5f639 100644 --- a/lnet/include/libcfs/darwin/darwin-prim.h +++ b/lnet/include/libcfs/darwin/darwin-prim.h @@ -438,10 +438,6 @@ extern int is_suser(void); #define lock_kernel() do {} while(0) #define unlock_kernel() do {} while(0) -#define CAP_SYS_BOOT 0 -#define CAP_SYS_ADMIN 1 -#define capable(a) ((a) == CAP_SYS_BOOT ? is_suser(): is_suser1()) - #define USERMODEHELPER(path, argv, envp) (0) #define cfs_module(name, version, init, fini) \ diff --git a/lnet/include/libcfs/darwin/libcfs.h b/lnet/include/libcfs/darwin/libcfs.h index 830c2e6..ccf4cfe 100644 --- a/lnet/include/libcfs/darwin/libcfs.h +++ b/lnet/include/libcfs/darwin/libcfs.h @@ -203,7 +203,7 @@ __entry_nesting(&__cdd); /* * XNU has no capabilities */ -typedef int cfs_kernel_cap_t; +typedef __u32 cfs_kernel_cap_t; #ifdef __KERNEL__ enum { diff --git a/lnet/include/libcfs/winnt/winnt-prim.h b/lnet/include/libcfs/winnt/winnt-prim.h index 83795a9..4163306 100644 --- a/lnet/include/libcfs/winnt/winnt-prim.h +++ b/lnet/include/libcfs/winnt/winnt-prim.h @@ -709,11 +709,6 @@ libcfs_arch_cleanup(void); #define lock_kernel() do {} while(0) #define unlock_kernel() do {} while(0) -#define CAP_SYS_ADMIN 0 -#define CAP_SYS_ROOT 1 - -#define capable(a) (TRUE) - #define USERMODEHELPER(path, argv, envp) (0) diff --git a/lnet/libcfs/darwin/darwin-curproc.c b/lnet/libcfs/darwin/darwin-curproc.c index c9620f7..0028f39 100644 --- a/lnet/libcfs/darwin/darwin-curproc.c +++ b/lnet/libcfs/darwin/darwin-curproc.c @@ -164,17 +164,28 @@ char *cfs_curproc_comm(void) #endif } -cfs_kernel_cap_t cfs_curproc_cap_get(void) +void cfs_cap_raise(cfs_cap_t cap) {} +void cfs_cap_lower(cfs_cap_t cap) {} + +int cfs_cap_raised(cfs_cap_t cap) { + return 1; +} + +void cfs_kernel_cap_pack(kernel_cap_t *kcap, cfs_cap_t cap) {} +void cfs_kernel_cap_unpack(kernel_cap_t *kcap, cfs_cap_t cap) {} + +cfs_cap_t cfs_curproc_cap_pack(void) { return -1; } -void cfs_curproc_cap_set(cfs_kernel_cap_t cap) +void cfs_curproc_cap_unpack(cfs_cap_t cap) {} + +int cfs_capable(cfs_cap_t cap) { - return; + return cap == CFS_CAP_SYS_BOOT ? is_suser(): is_suser1(); } - /* * Local variables: * c-indentation-style: "K&R" diff --git a/lnet/libcfs/linux/linux-curproc.c b/lnet/libcfs/linux/linux-curproc.c index ef85ba8..77a16d8 100644 --- a/lnet/libcfs/linux/linux-curproc.c +++ b/lnet/libcfs/linux/linux-curproc.c @@ -121,14 +121,63 @@ char *cfs_curproc_comm(void) return current->comm; } -cfs_kernel_cap_t cfs_curproc_cap_get(void) +/* Currently all the CFS_CAP_* defines match CAP_* ones. */ +#define cfs_cap_pack(cap) (cap) +#define cfs_cap_unpack(cap) (cap) + +void cfs_cap_raise(cfs_cap_t cap) +{ + cap_raise(cfs_current()->cap_effective, cfs_cap_unpack(cap)); +} + +void cfs_cap_lower(cfs_cap_t cap) +{ + cap_lower(cfs_current()->cap_effective, cfs_cap_unpack(cap)); +} + +int cfs_cap_raised(cfs_cap_t cap) +{ + return cap_raised(cfs_current()->cap_effective, cfs_cap_unpack(cap)); +} + +void cfs_kernel_cap_pack(cfs_kernel_cap_t kcap, cfs_cap_t *cap) +{ +#if _LINUX_CAPABILITY_VERSION == 0x19980330 + *cap = cfs_cap_pack(kcap); +#elif _LINUX_CAPABILITY_VERSION == 0x20071026 + *cap = cfs_cap_pack(kcap[0]); +#else + #error "need correct _LINUX_CAPABILITY_VERSION " +#endif +} + +void cfs_kernel_cap_unpack(cfs_kernel_cap_t *kcap, cfs_cap_t cap) +{ +#if _LINUX_CAPABILITY_VERSION == 0x19980330 + *kcap = cfs_cap_unpack(cap); +#elif _LINUX_CAPABILITY_VERSION == 0x20071026 + (*kcap)[0] = cfs_cap_unpack(cap); +#else + #error "need correct _LINUX_CAPABILITY_VERSION " +#endif + +} + +cfs_cap_t cfs_curproc_cap_pack(void) +{ + cfs_cap_t cap; + cfs_kernel_cap_pack(current->cap_effective, &cap); + return cap; +} + +void cfs_curproc_cap_unpack(cfs_cap_t cap) { - return current->cap_effective; + cfs_kernel_cap_unpack(¤t->cap_effective, cap); } -void cfs_curproc_cap_set(cfs_kernel_cap_t cap) +int cfs_capable(cfs_cap_t cap) { - current->cap_effective = cap; + return capable(cfs_cap_unpack(cap)); } EXPORT_SYMBOL(cfs_curproc_uid); @@ -141,8 +190,14 @@ EXPORT_SYMBOL(cfs_curproc_comm); EXPORT_SYMBOL(cfs_curproc_groups_nr); EXPORT_SYMBOL(cfs_curproc_groups_dump); EXPORT_SYMBOL(cfs_curproc_is_in_groups); -EXPORT_SYMBOL(cfs_curproc_cap_get); -EXPORT_SYMBOL(cfs_curproc_cap_set); +EXPORT_SYMBOL(cfs_cap_raise); +EXPORT_SYMBOL(cfs_cap_lower); +EXPORT_SYMBOL(cfs_cap_raised); +EXPORT_SYMBOL(cfs_kernel_cap_pack); +EXPORT_SYMBOL(cfs_kernel_cap_unpack); +EXPORT_SYMBOL(cfs_curproc_cap_pack); +EXPORT_SYMBOL(cfs_curproc_cap_unpack); +EXPORT_SYMBOL(cfs_capable); /* * Local variables: diff --git a/lnet/libcfs/linux/linux-module.c b/lnet/libcfs/linux/linux-module.c index c44eb84..b6381c9 100644 --- a/lnet/libcfs/linux/linux-module.c +++ b/lnet/libcfs/linux/linux-module.c @@ -153,12 +153,12 @@ libcfs_ioctl(struct inode *inode, struct file *file, /* Handle platform-dependent IOC requests */ switch (cmd) { case IOC_LIBCFS_PANIC: - if (!capable (CAP_SYS_BOOT)) + if (!cfs_capable(CFS_CAP_SYS_BOOT)) return (-EPERM); panic("debugctl-invoked panic"); return (0); case IOC_LIBCFS_MEMHOG: - if (!capable (CAP_SYS_ADMIN)) + if (!cfs_capable(CFS_CAP_SYS_ADMIN)) return -EPERM; /* go thought */ } diff --git a/lnet/libcfs/lwt.c b/lnet/libcfs/lwt.c index ed3b235..9bbdfa9 100644 --- a/lnet/libcfs/lwt.c +++ b/lnet/libcfs/lwt.c @@ -86,7 +86,7 @@ lwt_lookup_string (int *size, char *knl_ptr, * trying to determine the string length, so we're trusting our * caller... */ - if (!capable(CAP_SYS_ADMIN)) + if (!cfs_capable(CFS_CAP_SYS_ADMIN)) return (-EPERM); if (user_size > 0 && @@ -117,7 +117,7 @@ lwt_control (int enable, int clear) int i; int j; - if (!capable(CAP_SYS_ADMIN)) + if (!cfs_capable(CFS_CAP_SYS_ADMIN)) return (-EPERM); if (!enable) { @@ -164,7 +164,7 @@ lwt_snapshot (cycles_t *now, int *ncpu, int *total_size, int i; int j; - if (!capable(CAP_SYS_ADMIN)) + if (!cfs_capable(CFS_CAP_SYS_ADMIN)) return (-EPERM); *ncpu = num_online_cpus(); diff --git a/lnet/libcfs/winnt/winnt-curproc.c b/lnet/libcfs/winnt/winnt-curproc.c index 55bfc20..40c5f5f 100644 --- a/lnet/libcfs/winnt/winnt-curproc.c +++ b/lnet/libcfs/winnt/winnt-curproc.c @@ -107,16 +107,45 @@ char *cfs_curproc_comm(void) return this_task.comm; } -cfs_kernel_cap_t cfs_curproc_cap_get(void) +void cfs_cap_raise(cfs_cap_t cap) { - return this_task.cap_effective; + this_task.cap_effective |= (1 << cap); } -void cfs_curproc_cap_set(cfs_kernel_cap_t cap) +void cfs_cap_lower(cfs_cap_t cap) { - this_task.cap_effective = cap; + this_task.cap_effective &= ~(1 << cap); } +int cfs_cap_raised(cfs_cap_t cap) +{ + return this_task.cap_effective & (1 << cap); +} + +void cfs_kernel_cap_pack(cfs_kernel_cap_t kcap, cfs_cap_t *cap) +{ + *cap = kcap; +} + +void cfs_kernel_cap_unpack(cfs_kernel_cap_t *kcap, cfs_cap_t cap) +{ + *kcap = cap; +} + +cfs_cap_t cfs_curproc_cap_pack(void) { + cfs_cap_t cap; + cfs_kernel_cap_pack(this_task.cap_effective, &cap); + return cap; +} + +void cfs_curproc_cap_unpack(cfs_cap_t cap) { + cfs_kernel_cap_unpack(&this_task.cap_effective, cap); +} + +int cfs_capable(cfs_cap_t cap) +{ + return TRUE; +} /* * Implementation of linux task management routines @@ -469,5 +498,11 @@ EXPORT_SYMBOL(cfs_curproc_comm); EXPORT_SYMBOL(cfs_curproc_groups_nr); EXPORT_SYMBOL(cfs_curproc_groups_dump); EXPORT_SYMBOL(cfs_curproc_is_in_groups); -EXPORT_SYMBOL(cfs_curproc_cap_get); -EXPORT_SYMBOL(cfs_curproc_cap_set); +EXPORT_SYMBOL(cfs_cap_raise); +EXPORT_SYMBOL(cfs_cap_lower); +EXPORT_SYMBOL(cfs_cap_raised); +EXPORT_SYMBOL(cfs_kernel_cap_pack); +EXPORT_SYMBOL(cfs_kernel_cap_unpack); +EXPORT_SYMBOL(cfs_curproc_cap_pack); +EXPORT_SYMBOL(cfs_curproc_cap_unpack); +EXPORT_SYMBOL(cfs_capable); diff --git a/lnet/libcfs/winnt/winnt-module.c b/lnet/libcfs/winnt/winnt-module.c index 87e4c26..5dd151a 100644 --- a/lnet/libcfs/winnt/winnt-module.c +++ b/lnet/libcfs/winnt/winnt-module.c @@ -138,7 +138,7 @@ libcfs_ioctl(cfs_file_t * file, unsigned int cmd, ulong_ptr arg) /* Handle platform-dependent IOC requests */ switch (cmd) { case IOC_LIBCFS_PANIC: - if (!capable (CAP_SYS_BOOT)) + if (!cfs_capable(CFS_CAP_SYS_BOOT)) return (-EPERM); CERROR(("debugctl-invoked panic")); KeBugCheckEx('LUFS', (ULONG_PTR)libcfs_ioctl, (ULONG_PTR)NULL, (ULONG_PTR)NULL, (ULONG_PTR)NULL); @@ -146,7 +146,7 @@ libcfs_ioctl(cfs_file_t * file, unsigned int cmd, ulong_ptr arg) return (0); case IOC_LIBCFS_MEMHOG: - if (!capable (CAP_SYS_ADMIN)) + if (!cfs_capable(CFS_CAP_SYS_ADMIN)) return -EPERM; break; } diff --git a/lnet/utils/wirecheck.c b/lnet/utils/wirecheck.c index 6d44ea1..6afd4dc 100644 --- a/lnet/utils/wirecheck.c +++ b/lnet/utils/wirecheck.c @@ -203,6 +203,19 @@ system_string (char *cmdline, char *str, int len) } } +static void check_lnet_cap() +{ + CLASSERT(CFS_CAP_CHOWN == 0); + CLASSERT(CFS_CAP_DAC_OVERRIDE == 1); + CLASSERT(CFS_CAP_DAC_READ_SEARCH == 2); + CLASSERT(CFS_CAP_FOWNER == 3); + CLASSERT(CFS_CAP_FSETID == 4); + CLASSERT(CFS_CAP_LINUX_IMMUTABLE == 9); + CLASSERT(CFS_CAP_SYS_ADMIN == 21); + CLASSERT(CFS_CAP_SYS_BOOT == 23); + CLASSERT(CFS_CAP_SYS_RESOURCE == 24); +} + int main (int argc, char **argv) { @@ -239,6 +252,7 @@ main (int argc, char **argv) check_lnet_handle_wire (); check_lnet_magicversion (); check_lnet_hdr (); + check_lnet_cap(); printf ("}\n\n"); -- 1.8.3.1