])
#
+# 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 <linux/sched.h>
+],[
+ 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 <linux/sched.h>
+ #include <linux/fs_struct.h>
+],[
+ 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
# 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
])
#
*/
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);
#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 */
#ifdef __KERNEL__
#include <net/sock.h>
+#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))
*/
#include <linux/sched.h>
+#include <linux/fs_struct.h>
#define DEBUG_SUBSYSTEM S_LNET
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)
#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;
{
#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);
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)
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)
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);
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 ||
#endif
#include <linux/module.h>
#include <linux/kernel.h>
+#include <linux/fs_struct.h>
#include <libcfs/libcfs.h>
#if defined(CONFIG_KGDB)
}
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)
{