From ee8f0cf91af2a9d5248e3c440111fd6807d5100c Mon Sep 17 00:00:00 2001 From: yangsheng Date: Tue, 28 Jul 2009 12:42:05 +0000 Subject: [PATCH] Branch b1_8 b=19808 i=adilger, shadow, green Landed for 2.6.30 kernel patchless support. --- lnet/autoconf/lustre-lnet.m4 | 48 ++++++++++++++++++++++++++++++++ lnet/include/libcfs/curproc.h | 2 ++ lnet/include/libcfs/linux/libcfs.h | 29 +++++++++++++++++++ lnet/include/libcfs/linux/linux-tcpip.h | 15 ++++++++++ lnet/libcfs/linux/linux-curproc.c | 49 +++++++++++++++++++++++++-------- lnet/libcfs/linux/linux-module.c | 2 +- lnet/libcfs/linux/linux-prim.c | 12 ++++++-- 7 files changed, 141 insertions(+), 16 deletions(-) diff --git a/lnet/autoconf/lustre-lnet.m4 b/lnet/autoconf/lustre-lnet.m4 index 4301227..fd624a8 100644 --- a/lnet/autoconf/lustre-lnet.m4 +++ b/lnet/autoconf/lustre-lnet.m4 @@ -1451,6 +1451,50 @@ LN_USER__U64_LONG_LONG ]) # +# LN_STRUCT_CRED_IN_TASK +# +# struct cred was introduced in 2.6.29 to streamline credentials in task struct +# +AC_DEFUN([LN_STRUCT_CRED_IN_TASK], +[AC_MSG_CHECKING([if kernel has struct cred]) +LB_LINUX_TRY_COMPILE([ + #include +],[ + struct task_struct *tsk = NULL; + tsk->real_cred = NULL; +],[ + AC_MSG_RESULT([yes]) + AC_DEFINE(HAVE_STRUCT_CRED, 1, [struct cred found]) +],[ + AC_MSG_RESULT([no]) +]) +]) + +# +# LN_FUNC_UNSHARE_FS_STRUCT +# +# unshare_fs_struct was introduced in 2.6.30 to prevent others to directly +# mess with copy_fs_struct +# +AC_DEFUN([LN_FUNC_UNSHARE_FS_STRUCT], +[AC_MSG_CHECKING([if kernel defines unshare_fs_struct()]) +tmp_flags="$EXTRA_KCFLAGS" +EXTRA_KCFLAGS="-Werror" +LB_LINUX_TRY_COMPILE([ + #include + #include +],[ + unshare_fs_struct(); +],[ + AC_MSG_RESULT([yes]) + AC_DEFINE(HAVE_UNSHARE_FS_STRUCT, 1, [unshare_fs_struct found]) +],[ + AC_MSG_RESULT([no]) +]) +EXTRA_KCFLAGS="$tmp_flags" +]) + +# # LN_PROG_LINUX # # LNet linux kernel checks @@ -1502,6 +1546,10 @@ LN_SEM_COUNT # 2.6.27 LN_SOCK_MAP_FD_2ARG LN_FUNC_DUMP_TRACE +#2.6.29 +LN_STRUCT_CRED_IN_TASK +# 2.6.30 +LN_FUNC_UNSHARE_FS_STRUCT ]) # diff --git a/lnet/include/libcfs/curproc.h b/lnet/include/libcfs/curproc.h index 0b9ae29..38492a9 100644 --- a/lnet/include/libcfs/curproc.h +++ b/lnet/include/libcfs/curproc.h @@ -51,6 +51,8 @@ */ uid_t cfs_curproc_uid(void); gid_t cfs_curproc_gid(void); +uid_t cfs_curproc_euid(void); +gid_t cfs_curproc_egid(void); uid_t cfs_curproc_fsuid(void); gid_t cfs_curproc_fsgid(void); pid_t cfs_curproc_pid(void); diff --git a/lnet/include/libcfs/linux/libcfs.h b/lnet/include/libcfs/linux/libcfs.h index bf51ea1..ea4b79c 100644 --- a/lnet/include/libcfs/linux/libcfs.h +++ b/lnet/include/libcfs/linux/libcfs.h @@ -201,6 +201,35 @@ struct cfs_stack_trace { #define WITH_WATCHDOG #endif + +#ifndef HAVE_STRUCT_CRED + +#define current_cred() (current) + +#define current_cred_xxx(xxx) \ +({ \ + current->xxx; \ +}) + +#define current_uid() (current_cred_xxx(uid)) +#define current_gid() (current_cred_xxx(gid)) +#define current_euid() (current_cred_xxx(euid)) +#define current_egid() (current_cred_xxx(egid)) +#define current_suid() (current_cred_xxx(suid)) +#define current_sgid() (current_cred_xxx(sgid)) +#define current_fsuid() (current_cred_xxx(fsuid)) +#define current_fsgid() (current_cred_xxx(fsgid)) +#define current_cap() (current_cred_xxx(cap_effective)) +#define current_user() (current_cred_xxx(user)) +#define current_user_ns() (current_cred_xxx(user)->user_ns) +#define current_security() (current_cred_xxx(security)) + +#define cred task_struct + +#define prepare_creds() (current) +#define commit_creds(a) +#endif + #endif #endif /* _LINUX_LIBCFS_H */ diff --git a/lnet/include/libcfs/linux/linux-tcpip.h b/lnet/include/libcfs/linux/linux-tcpip.h index 1f918ea..90f86e8 100644 --- a/lnet/include/libcfs/linux/linux-tcpip.h +++ b/lnet/include/libcfs/linux/linux-tcpip.h @@ -48,6 +48,21 @@ #ifdef __KERNEL__ #include +#ifndef HIPQUAD +// XXX Should just kill all users +#if defined(__LITTLE_ENDIAN) +#define HIPQUAD(addr) \ + ((unsigned char *)&addr)[3], \ + ((unsigned char *)&addr)[2], \ + ((unsigned char *)&addr)[1], \ + ((unsigned char *)&addr)[0] +#elif defined(__BIG_ENDIAN) +#define HIPQUAD NIPQUAD +#else +#error "Please fix asm/byteorder.h" +#endif /* __LITTLE_ENDIAN */ +#endif + typedef struct socket cfs_socket_t; #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,72)) diff --git a/lnet/libcfs/linux/linux-curproc.c b/lnet/libcfs/linux/linux-curproc.c index 045f262..b82e310 100644 --- a/lnet/libcfs/linux/linux-curproc.c +++ b/lnet/libcfs/linux/linux-curproc.c @@ -41,6 +41,7 @@ */ #include +#include #define DEBUG_SUBSYSTEM S_LNET @@ -54,22 +55,32 @@ uid_t cfs_curproc_uid(void) { - return current->uid; + return current_uid(); } gid_t cfs_curproc_gid(void) { - return current->gid; + return current_gid(); } uid_t cfs_curproc_fsuid(void) { - return current->fsuid; + return current_fsuid(); +} + +uid_t cfs_curproc_euid(void) +{ + return current_egid(); +} + +uid_t cfs_curproc_egid(void) +{ + return current_egid(); } gid_t cfs_curproc_fsgid(void) { - return current->fsgid; + return current_fsgid(); } pid_t cfs_curproc_pid(void) @@ -83,7 +94,7 @@ int cfs_curproc_groups_nr(void) #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,4) task_lock(current); - nr = current->group_info->ngroups; + nr = current_cred()->group_info->ngroups; task_unlock(current); #else nr = current->ngroups; @@ -95,8 +106,8 @@ void cfs_curproc_groups_dump(gid_t *array, int size) { #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,4) task_lock(current); - size = min_t(int, size, current->group_info->ngroups); - memcpy(array, current->group_info->blocks[0], size * sizeof(__u32)); + size = min_t(int, size, current_cred()->group_info->ngroups); + memcpy(array, current_cred()->group_info->blocks[0], size * sizeof(__u32)); task_unlock(current); #else LASSERT(size <= NGROUPS); @@ -127,17 +138,25 @@ char *cfs_curproc_comm(void) void cfs_cap_raise(cfs_cap_t cap) { - cap_raise(cfs_current()->cap_effective, cfs_cap_unpack(cap)); + struct cred *cred; + if ((cred = prepare_creds())) { + cap_raise(cred->cap_effective, cfs_cap_unpack(cap)); + commit_creds(cred); + } } void cfs_cap_lower(cfs_cap_t cap) { - cap_lower(cfs_current()->cap_effective, cfs_cap_unpack(cap)); + struct cred *cred; + if ((cred = prepare_creds())) { + cap_lower(cred->cap_effective, cfs_cap_unpack(cap)); + commit_creds(cred); + } } int cfs_cap_raised(cfs_cap_t cap) { - return cap_raised(cfs_current()->cap_effective, cfs_cap_unpack(cap)); + return cap_raised(current_cap(), cfs_cap_unpack(cap)); } void cfs_kernel_cap_pack(cfs_kernel_cap_t kcap, cfs_cap_t *cap) @@ -170,13 +189,17 @@ void cfs_kernel_cap_unpack(cfs_kernel_cap_t *kcap, cfs_cap_t cap) cfs_cap_t cfs_curproc_cap_pack(void) { cfs_cap_t cap; - cfs_kernel_cap_pack(current->cap_effective, &cap); + cfs_kernel_cap_pack(current_cap(), &cap); return cap; } void cfs_curproc_cap_unpack(cfs_cap_t cap) { - cfs_kernel_cap_unpack(¤t->cap_effective, cap); + struct cred *cred; + if ((cred = prepare_creds())) { + cfs_kernel_cap_unpack(&cred->cap_effective, cap); + commit_creds(cred); + } } int cfs_capable(cfs_cap_t cap) @@ -186,7 +209,9 @@ int cfs_capable(cfs_cap_t cap) EXPORT_SYMBOL(cfs_curproc_uid); EXPORT_SYMBOL(cfs_curproc_pid); +EXPORT_SYMBOL(cfs_curproc_euid); EXPORT_SYMBOL(cfs_curproc_gid); +EXPORT_SYMBOL(cfs_curproc_egid); EXPORT_SYMBOL(cfs_curproc_fsuid); EXPORT_SYMBOL(cfs_curproc_fsgid); EXPORT_SYMBOL(cfs_curproc_umask); diff --git a/lnet/libcfs/linux/linux-module.c b/lnet/libcfs/linux/linux-module.c index b6381c9..1eedd26 100644 --- a/lnet/libcfs/linux/linux-module.c +++ b/lnet/libcfs/linux/linux-module.c @@ -139,7 +139,7 @@ libcfs_ioctl(struct inode *inode, struct file *file, struct cfs_psdev_file pfile; int rc = 0; - if (current->fsuid != 0) + if (current_fsuid() != 0) return -EACCES; if ( _IOC_TYPE(cmd) != IOC_LIBCFS_TYPE || diff --git a/lnet/libcfs/linux/linux-prim.c b/lnet/libcfs/linux/linux-prim.c index ea8ca00..5aada1d 100644 --- a/lnet/libcfs/linux/linux-prim.c +++ b/lnet/libcfs/linux/linux-prim.c @@ -40,6 +40,7 @@ #endif #include #include +#include #include #if defined(CONFIG_KGDB) @@ -70,19 +71,24 @@ void cfs_daemonize(char *str) { } int cfs_daemonize_ctxt(char *str) { - struct task_struct *tsk = current; - struct fs_struct *fs = NULL; cfs_daemonize(str); +#ifndef HAVE_UNSHARE_FS_STRUCT + { + struct task_struct *tsk = current; + struct fs_struct *fs = NULL; fs = copy_fs_struct(tsk->fs); if (fs == NULL) return -ENOMEM; exit_fs(tsk); tsk->fs = fs; + } +#else + unshare_fs_struct(); +#endif return 0; } - sigset_t cfs_get_blockedsigs(void) { -- 1.8.3.1