From: James Simmons Date: Wed, 12 Feb 2014 21:27:17 +0000 (-0500) Subject: LU-4476 kernel: support process namespace containers X-Git-Tag: 2.5.58~41 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=99727c7a1a4f4100361f79bf185cb34b70b67d99 LU-4476 kernel: support process namespace containers PID namespace was introduce to linux to allow the migration of containers between hosts. This way running processes could be migrated to a new machine without interruption due to pid collisions. User namespace creates a new enviroment for a exist process where in this new namespace it will have different uid/gid. Outside that namespace the default uid/gid. For example a unprivileged application can create user namespace for itself which has root privilages. Those privilages don't exist outside of the created namespace. Both of these changed the traditonal one to one kernel mapping for pids/gids has changed. Since userland can now have multiple PID namespaces this means that each namespace in userland could have the same pid assigned. This is possible since each namespace will be isolated from each other. In the case of User namespace the application can report to the kernel its namespace uid/gid instead of its real uid/gid. Since the same running kernel is used between all namespaces on a host the pid/gid data that is pushed into a kernel context will have to map to a unique pid/gid in kernel space to avoid collisions. This very similar to Lustre using FIDs to avoid inode collisions. An example of where the mapping needs to take place are when pid/gid data is pushed via a ioctl. Also the internal structures of the kernel store uid/gid in the kernel internal format. Lastly even with lustre userland uid/gid namespace being consistant to applications the transmitted uid/gid will be represented in the kernel differently from server to server. Lustre wire protocols transmitting uid/gid must handle these cases. Change-Id: I207492b9a8a762e43ac2dd8fd1fb1b7397505304 Signed-off-by: James Simmons Reviewed-on: http://review.whamcloud.com/8817 Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Yang Sheng Reviewed-by: Niu Yawei Reviewed-by: Bob Glossman Reviewed-by: Oleg Drokin --- diff --git a/libcfs/autoconf/lustre-libcfs.m4 b/libcfs/autoconf/lustre-libcfs.m4 index cb86497..815f082 100644 --- a/libcfs/autoconf/lustre-libcfs.m4 +++ b/libcfs/autoconf/lustre-libcfs.m4 @@ -233,6 +233,13 @@ LB_LINUX_TRY_COMPILE([ ]) ]) +# 3.4 introduced process namespace +AC_DEFUN([LIBCFS_PROCESS_NAMESPACE],[ +LB_CHECK_LINUX_HEADER([linux/uidgid.h], [ + AC_DEFINE(HAVE_UIDGID_HEADER, 1, [uidgid.h is present]) +]) +]) + # # FC18 3.7.2-201 unexport sock_map_fd() change to # use sock_alloc_file(). @@ -312,6 +319,8 @@ LIBCFS_DUMP_TRACE_ADDRESS LC_SHRINK_CONTROL # 3.0 LIBCFS_STACKTRACE_WARNING +# 3.4 +LIBCFS_PROCESS_NAMESPACE # 3.7 LIBCFS_SOCK_ALLOC_FILE # 3.8 diff --git a/libcfs/include/libcfs/curproc.h b/libcfs/include/libcfs/curproc.h index 106cbc8..fc18b12 100644 --- a/libcfs/include/libcfs/curproc.h +++ b/libcfs/include/libcfs/curproc.h @@ -43,6 +43,68 @@ #ifndef __LIBCFS_CURPROC_H__ #define __LIBCFS_CURPROC_H__ +#if !defined(HAVE_UIDGID_HEADER) || !defined(__KERNEL__) + +typedef uid_t kuid_t; +typedef gid_t kgid_t; + +#define INVALID_UID -1 +#define INVALID_GID -1 + +#ifndef __KERNEL__ +struct user_namespace { + unsigned int pad; +}; + +extern struct user_namespace init_user_ns; +#endif + +static inline uid_t __kuid_val(kuid_t uid) +{ + return uid; +} + +static inline gid_t __kgid_val(kgid_t gid) +{ + return gid; +} + +static inline kuid_t make_kuid(struct user_namespace *from, uid_t uid) +{ + return uid; +} + +static inline kgid_t make_kgid(struct user_namespace *from, gid_t gid) +{ + return gid; +} + +static inline uid_t from_kuid(struct user_namespace *to, kuid_t uid) +{ + return uid; +} + +static inline gid_t from_kgid(struct user_namespace *to, kgid_t gid) +{ + return gid; +} + +static inline bool uid_eq(kuid_t left, kuid_t right) +{ + return left == right; +} + +static inline bool uid_valid(kuid_t uid) +{ + return (uid != INVALID_UID); +} + +static inline bool gid_valid(kgid_t gid) +{ + return (gid != INVALID_GID); +} +#endif + int cfs_get_environ(const char *key, char *value, int *val_len); typedef __u32 cfs_cap_t; diff --git a/libcfs/include/libcfs/linux/linux-prim.h b/libcfs/include/libcfs/linux/linux-prim.h index 56a990c..4c27905 100644 --- a/libcfs/include/libcfs/linux/linux-prim.h +++ b/libcfs/include/libcfs/linux/linux-prim.h @@ -62,7 +62,10 @@ #ifdef HAVE_LINUX_RANDOM_H #include #endif - +#ifdef HAVE_UIDGID_HEADER +#include +#endif +#include #include #include #include diff --git a/libcfs/libcfs/darwin/darwin-curproc.c b/libcfs/libcfs/darwin/darwin-curproc.c index c2ced51..b0ac7ad 100644 --- a/libcfs/libcfs/darwin/darwin-curproc.c +++ b/libcfs/libcfs/darwin/darwin-curproc.c @@ -143,6 +143,9 @@ char *current_comm(void) #endif } +struct user_namespace init_user_ns __read_mostly; +EXPORT_SYMBOL(init_user_ns); + void cfs_cap_raise(cfs_cap_t cap) {} void cfs_cap_lower(cfs_cap_t cap) {} diff --git a/libcfs/libcfs/linux/linux-module.c b/libcfs/libcfs/linux/linux-module.c index 1294537..f98ba64 100644 --- a/libcfs/libcfs/linux/linux-module.c +++ b/libcfs/libcfs/linux/linux-module.c @@ -137,7 +137,7 @@ static long libcfs_ioctl(struct file *file, struct cfs_psdev_file pfile; int rc = 0; - if (current_fsuid() != 0) + if (!capable(CAP_SYS_ADMIN)) return -EACCES; if ( _IOC_TYPE(cmd) != IOC_LIBCFS_TYPE || diff --git a/libcfs/libcfs/user-prim.c b/libcfs/libcfs/user-prim.c index 1a6fdd9..f616e9d 100644 --- a/libcfs/libcfs/user-prim.c +++ b/libcfs/libcfs/user-prim.c @@ -245,6 +245,9 @@ void *kthread_run(cfs_thread_t func, void *arg, const char namefmt[], ...) } #endif +struct user_namespace init_user_ns __read_mostly; +EXPORT_SYMBOL(init_user_ns); + uid_t current_uid(void) { return getuid(); diff --git a/libcfs/libcfs/winnt/winnt-curproc.c b/libcfs/libcfs/winnt/winnt-curproc.c index 6d6ab58..6347827 100644 --- a/libcfs/libcfs/winnt/winnt-curproc.c +++ b/libcfs/libcfs/winnt/winnt-curproc.c @@ -58,6 +58,8 @@ struct task_struct this_task = /* journal_info */ NULL }; +struct user_namespace init_user_ns __read_mostly; +EXPORT_SYMBOL(init_user_ns); uid_t current_uid(void) { diff --git a/lustre/llite/dir.c b/lustre/llite/dir.c index 1b3473c..9189cbd 100644 --- a/lustre/llite/dir.c +++ b/lustre/llite/dir.c @@ -402,7 +402,8 @@ static int ll_dir_setdirstripe(struct inode *dir, struct lmv_user_md *lump, op_data->op_cli_flags |= CLI_SET_MEA; err = md_create(sbi->ll_md_exp, op_data, lump, sizeof(*lump), mode, - current_fsuid(), current_fsgid(), + from_kuid(&init_user_ns, current_fsuid()), + from_kgid(&init_user_ns, current_fsgid()), cfs_curproc_cap_pack(), 0, &request); ll_finish_md_op_data(op_data); if (err) @@ -854,8 +855,10 @@ static int quotactl_ioctl(struct ll_sb_info *sbi, struct if_quotactl *qctl) RETURN(-EPERM); break; case Q_GETQUOTA: - if (((type == USRQUOTA && current_euid() != id) || - (type == GRPQUOTA && !in_egroup_p(id))) && + if (((type == USRQUOTA && + !uid_eq(current_euid(), make_kuid(&init_user_ns, id))) || + (type == GRPQUOTA && + !in_egroup_p(make_kgid(&init_user_ns, id)))) && (!cfs_capable(CFS_CAP_SYS_ADMIN) || sbi->ll_flags & LL_SBI_RMT_CLIENT)) RETURN(-EPERM); diff --git a/lustre/llite/file.c b/lustre/llite/file.c index 0abafda..e92a510 100644 --- a/lustre/llite/file.c +++ b/lustre/llite/file.c @@ -2269,8 +2269,8 @@ static int ll_hsm_import(struct inode *inode, struct file *file, attr->ia_mode = hui->hui_mode & (S_IRWXU | S_IRWXG | S_IRWXO); attr->ia_mode |= S_IFREG; - attr->ia_uid = hui->hui_uid; - attr->ia_gid = hui->hui_gid; + attr->ia_uid = make_kuid(&init_user_ns, hui->hui_uid); + attr->ia_gid = make_kgid(&init_user_ns, hui->hui_gid); attr->ia_size = hui->hui_size; attr->ia_mtime.tv_sec = hui->hui_mtime; attr->ia_mtime.tv_nsec = hui->hui_mtime_ns; diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index f8b9519..1acce03 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -1697,7 +1697,7 @@ int ll_setattr_raw(struct dentry *dentry, struct iattr *attr, bool hsm_import) /* POSIX: check before ATTR_*TIME_SET set (from inode_change_ok) */ if (attr->ia_valid & TIMES_SET_FLAGS) { - if (current_fsuid() != inode->i_uid && + if ((!uid_eq(current_fsuid(), inode->i_uid)) && !cfs_capable(CFS_CAP_FOWNER)) RETURN(-EPERM); } @@ -2033,9 +2033,9 @@ void ll_update_inode(struct inode *inode, struct lustre_md *md) inode->i_blkbits = inode->i_sb->s_blocksize_bits; } if (body->valid & OBD_MD_FLUID) - inode->i_uid = body->uid; + inode->i_uid = make_kuid(&init_user_ns, body->uid); if (body->valid & OBD_MD_FLGID) - inode->i_gid = body->gid; + inode->i_gid = make_kgid(&init_user_ns, body->gid); if (body->valid & OBD_MD_FLFLAGS) inode->i_flags = ll_ext_to_inode_flags(body->flags); if (body->valid & OBD_MD_FLNLINK) @@ -2305,7 +2305,8 @@ int ll_flush_ctx(struct inode *inode) { struct ll_sb_info *sbi = ll_i2sbi(inode); - CDEBUG(D_SEC, "flush context for user %d\n", current_uid()); + CDEBUG(D_SEC, "flush context for user %d\n", + from_kuid(&init_user_ns, current_uid())); obd_set_info_async(NULL, sbi->ll_md_exp, sizeof(KEY_FLUSH_CTX), KEY_FLUSH_CTX, @@ -2589,8 +2590,8 @@ struct md_op_data * ll_prep_md_op_data(struct md_op_data *op_data, op_data->op_namelen = namelen; op_data->op_mode = mode; op_data->op_mod_time = cfs_time_current_sec(); - op_data->op_fsuid = current_fsuid(); - op_data->op_fsgid = current_fsgid(); + op_data->op_fsuid = from_kuid(&init_user_ns, current_fsuid()); + op_data->op_fsgid = from_kgid(&init_user_ns, current_fsgid()); op_data->op_cap = cfs_curproc_cap_pack(); op_data->op_bias = 0; op_data->op_cli_flags = 0; diff --git a/lustre/llite/lproc_llite.c b/lustre/llite/lproc_llite.c index 9f59cdc..8c4a148 100644 --- a/lustre/llite/lproc_llite.c +++ b/lustre/llite/lproc_llite.c @@ -953,7 +953,8 @@ void ll_stats_ops_tally(struct ll_sb_info *sbi, int op, int count) sbi->ll_stats_track_id == current->parent->pid) lprocfs_counter_add(sbi->ll_stats, op, count); else if (sbi->ll_stats_track_type == STATS_TRACK_GID && - sbi->ll_stats_track_id == current_gid()) + sbi->ll_stats_track_id == + from_kgid(&init_user_ns, current_gid())) lprocfs_counter_add(sbi->ll_stats, op, count); } EXPORT_SYMBOL(ll_stats_ops_tally); diff --git a/lustre/llite/namei.c b/lustre/llite/namei.c index 9149182..b47df73 100644 --- a/lustre/llite/namei.c +++ b/lustre/llite/namei.c @@ -350,9 +350,9 @@ int ll_md_blocking_ast(struct ldlm_lock *lock, struct ldlm_lock_desc *desc, __u32 ll_i2suppgid(struct inode *i) { if (in_group_p(i->i_gid)) - return (__u32)i->i_gid; + return (__u32)from_kgid(&init_user_ns, i->i_gid); else - return (__u32)(-1); + return (__u32) __kgid_val(INVALID_GID); } /* Pack the required supplementary groups into the supplied groups array. @@ -361,35 +361,15 @@ __u32 ll_i2suppgid(struct inode *i) * array in case it might be useful. Not needed if doing an MDS-side upcall. */ void ll_i2gids(__u32 *suppgids, struct inode *i1, struct inode *i2) { -#if 0 - int i; -#endif - - LASSERT(i1 != NULL); - LASSERT(suppgids != NULL); - - suppgids[0] = ll_i2suppgid(i1); + LASSERT(i1 != NULL); + LASSERT(suppgids != NULL); - if (i2) - suppgids[1] = ll_i2suppgid(i2); - else - suppgids[1] = -1; + suppgids[0] = ll_i2suppgid(i1); -#if 0 - for (i = 0; i < current_ngroups; i++) { - if (suppgids[0] == -1) { - if (current_groups[i] != suppgids[1]) - suppgids[0] = current_groups[i]; - continue; - } - if (suppgids[1] == -1) { - if (current_groups[i] != suppgids[0]) - suppgids[1] = current_groups[i]; - continue; - } - break; - } -#endif + if (i2) + suppgids[1] = ll_i2suppgid(i2); + else + suppgids[1] = -1; } /* @@ -948,7 +928,8 @@ static int ll_new_node(struct inode *dir, struct qstr *name, GOTO(err_exit, err = PTR_ERR(op_data)); err = md_create(sbi->ll_md_exp, op_data, tgt, tgt_len, mode, - current_fsuid(), current_fsgid(), + from_kuid(&init_user_ns, current_fsuid()), + from_kgid(&init_user_ns, current_fsgid()), cfs_curproc_cap_pack(), rdev, &request); ll_finish_md_op_data(op_data); if (err) diff --git a/lustre/llite/remote_perm.c b/lustre/llite/remote_perm.c index 8cc8c65..038a766 100644 --- a/lustre/llite/remote_perm.c +++ b/lustre/llite/remote_perm.c @@ -130,17 +130,18 @@ static int do_check_remote_perm(struct ll_inode_info *lli, int mask) if (!lli->lli_remote_perms) RETURN(-ENOENT); - head = lli->lli_remote_perms + remote_perm_hashfunc(current_uid()); + head = lli->lli_remote_perms + + remote_perm_hashfunc(from_kuid(&init_user_ns, current_uid())); spin_lock(&lli->lli_lock); cfs_hlist_for_each_entry(lrp, node, head, lrp_list) { - if (lrp->lrp_uid != current_uid()) + if (lrp->lrp_uid != from_kuid(&init_user_ns, current_uid())) continue; - if (lrp->lrp_gid != current_gid()) + if (lrp->lrp_gid != from_kgid(&init_user_ns, current_gid())) continue; - if (lrp->lrp_fsuid != current_fsuid()) + if (lrp->lrp_fsuid != from_kuid(&init_user_ns, current_fsuid())) continue; - if (lrp->lrp_fsgid != current_fsgid()) + if (lrp->lrp_fsgid != from_kgid(&init_user_ns, current_fsgid())) continue; found = 1; break; diff --git a/lustre/llite/vvp_object.c b/lustre/llite/vvp_object.c index 6df7eb1..2efa270 100644 --- a/lustre/llite/vvp_object.c +++ b/lustre/llite/vvp_object.c @@ -81,46 +81,46 @@ static int vvp_object_print(const struct lu_env *env, void *cookie, static int vvp_attr_get(const struct lu_env *env, struct cl_object *obj, struct cl_attr *attr) { - struct inode *inode = ccc_object_inode(obj); - - /* - * lov overwrites most of these fields in - * lov_attr_get()->...lov_merge_lvb_kms(), except when inode - * attributes are newer. - */ - - attr->cat_size = i_size_read(inode); - attr->cat_mtime = LTIME_S(inode->i_mtime); - attr->cat_atime = LTIME_S(inode->i_atime); - attr->cat_ctime = LTIME_S(inode->i_ctime); - attr->cat_blocks = inode->i_blocks; - attr->cat_uid = inode->i_uid; - attr->cat_gid = inode->i_gid; - /* KMS is not known by this layer */ - return 0; /* layers below have to fill in the rest */ + struct inode *inode = ccc_object_inode(obj); + + /* + * lov overwrites most of these fields in + * lov_attr_get()->...lov_merge_lvb_kms(), except when inode + * attributes are newer. + */ + + attr->cat_size = i_size_read(inode); + attr->cat_mtime = LTIME_S(inode->i_mtime); + attr->cat_atime = LTIME_S(inode->i_atime); + attr->cat_ctime = LTIME_S(inode->i_ctime); + attr->cat_blocks = inode->i_blocks; + attr->cat_uid = from_kuid(&init_user_ns, inode->i_uid); + attr->cat_gid = from_kgid(&init_user_ns, inode->i_gid); + /* KMS is not known by this layer */ + return 0; /* layers below have to fill in the rest */ } static int vvp_attr_set(const struct lu_env *env, struct cl_object *obj, const struct cl_attr *attr, unsigned valid) { - struct inode *inode = ccc_object_inode(obj); - - if (valid & CAT_UID) - inode->i_uid = attr->cat_uid; - if (valid & CAT_GID) - inode->i_gid = attr->cat_gid; - if (valid & CAT_ATIME) - LTIME_S(inode->i_atime) = attr->cat_atime; - if (valid & CAT_MTIME) - LTIME_S(inode->i_mtime) = attr->cat_mtime; - if (valid & CAT_CTIME) - LTIME_S(inode->i_ctime) = attr->cat_ctime; - if (0 && valid & CAT_SIZE) - cl_isize_write_nolock(inode, attr->cat_size); - /* not currently necessary */ - if (0 && valid & (CAT_UID|CAT_GID|CAT_SIZE)) - mark_inode_dirty(inode); - return 0; + struct inode *inode = ccc_object_inode(obj); + + if (valid & CAT_UID) + inode->i_uid = make_kuid(&init_user_ns, attr->cat_uid); + if (valid & CAT_GID) + inode->i_gid = make_kgid(&init_user_ns, attr->cat_gid); + if (valid & CAT_ATIME) + LTIME_S(inode->i_atime) = attr->cat_atime; + if (valid & CAT_MTIME) + LTIME_S(inode->i_mtime) = attr->cat_mtime; + if (valid & CAT_CTIME) + LTIME_S(inode->i_ctime) = attr->cat_ctime; + if (0 && valid & CAT_SIZE) + cl_isize_write_nolock(inode, attr->cat_size); + /* not currently necessary */ + if (0 && valid & (CAT_UID|CAT_GID|CAT_SIZE)) + mark_inode_dirty(inode); + return 0; } int vvp_conf_set(const struct lu_env *env, struct cl_object *obj, diff --git a/lustre/lmv/lmv_obd.c b/lustre/lmv/lmv_obd.c index 8f26e6c..b7a9544 100644 --- a/lustre/lmv/lmv_obd.c +++ b/lustre/lmv/lmv_obd.c @@ -2118,8 +2118,8 @@ static int lmv_link(struct obd_export *exp, struct md_op_data *op_data, PFID(&op_data->op_fid2), op_data->op_namelen, op_data->op_name, PFID(&op_data->op_fid1)); - op_data->op_fsuid = current_fsuid(); - op_data->op_fsgid = current_fsgid(); + op_data->op_fsuid = from_kuid(&init_user_ns, current_fsuid()); + op_data->op_fsgid = from_kgid(&init_user_ns, current_fsgid()); op_data->op_cap = cfs_curproc_cap_pack(); if (op_data->op_mea2 != NULL) { struct lmv_stripe_md *lsm = op_data->op_mea2; @@ -2173,8 +2173,8 @@ static int lmv_rename(struct obd_export *exp, struct md_op_data *op_data, if (rc) RETURN(rc); - op_data->op_fsuid = current_fsuid(); - op_data->op_fsgid = current_fsgid(); + op_data->op_fsuid = from_kuid(&init_user_ns, current_fsuid()); + op_data->op_fsgid = from_kgid(&init_user_ns, current_fsgid()); op_data->op_cap = cfs_curproc_cap_pack(); if (op_data->op_cli_flags & CLI_MIGRATE) { LASSERTF(fid_is_sane(&op_data->op_fid3), "invalid FID "DFID"\n", @@ -2556,8 +2556,8 @@ retry: RETURN(PTR_ERR(tgt)); } - op_data->op_fsuid = current_fsuid(); - op_data->op_fsgid = current_fsgid(); + op_data->op_fsuid = from_kuid(&init_user_ns, current_fsuid()); + op_data->op_fsgid = from_kgid(&init_user_ns, current_fsgid()); op_data->op_cap = cfs_curproc_cap_pack(); /* diff --git a/lustre/mdc/mdc_lib.c b/lustre/mdc/mdc_lib.c index c55dd8c..2d8a09d 100644 --- a/lustre/mdc/mdc_lib.c +++ b/lustre/mdc/mdc_lib.c @@ -59,10 +59,10 @@ static void __mdc_pack_body(struct mdt_body *b, __u32 suppgid) LASSERT (b != NULL); b->suppgid = suppgid; - b->uid = current_uid(); - b->gid = current_gid(); - b->fsuid = current_fsuid(); - b->fsgid = current_fsgid(); + b->uid = from_kuid(&init_user_ns, current_uid()); + b->gid = from_kgid(&init_user_ns, current_gid()); + b->fsuid = from_kuid(&init_user_ns, current_fsuid()); + b->fsgid = from_kgid(&init_user_ns, current_fsgid()); b->capability = cfs_curproc_cap_pack(); } @@ -234,8 +234,8 @@ void mdc_open_pack(struct ptlrpc_request *req, struct md_op_data *op_data, /* XXX do something about time, uid, gid */ rec->cr_opcode = REINT_OPEN; - rec->cr_fsuid = current_fsuid(); - rec->cr_fsgid = current_fsgid(); + rec->cr_fsuid = from_kuid(&init_user_ns, current_fsuid()); + rec->cr_fsgid = from_kgid(&init_user_ns, current_fsgid()); rec->cr_cap = cfs_curproc_cap_pack(); rec->cr_mode = mode; cr_flags = mds_pack_open_flags(flags, mode); @@ -319,25 +319,27 @@ static void mdc_setattr_pack_rec(struct mdt_rec_setattr *rec, struct md_op_data *op_data) { rec->sa_opcode = REINT_SETATTR; - rec->sa_fsuid = current_fsuid(); - rec->sa_fsgid = current_fsgid(); + rec->sa_fsuid = from_kuid(&init_user_ns, current_fsuid()); + rec->sa_fsgid = from_kgid(&init_user_ns, current_fsgid()); rec->sa_cap = cfs_curproc_cap_pack(); rec->sa_suppgid = -1; - rec->sa_fid = op_data->op_fid1; - rec->sa_valid = attr_pack(op_data->op_attr.ia_valid); - rec->sa_mode = op_data->op_attr.ia_mode; - rec->sa_uid = op_data->op_attr.ia_uid; - rec->sa_gid = op_data->op_attr.ia_gid; - rec->sa_size = op_data->op_attr.ia_size; - rec->sa_blocks = op_data->op_attr_blocks; - rec->sa_atime = LTIME_S(op_data->op_attr.ia_atime); - rec->sa_mtime = LTIME_S(op_data->op_attr.ia_mtime); - rec->sa_ctime = LTIME_S(op_data->op_attr.ia_ctime); - rec->sa_attr_flags = ((struct ll_iattr *)&op_data->op_attr)->ia_attr_flags; + rec->sa_fid = op_data->op_fid1; + rec->sa_valid = attr_pack(op_data->op_attr.ia_valid); + rec->sa_mode = op_data->op_attr.ia_mode; + rec->sa_uid = from_kuid(&init_user_ns, op_data->op_attr.ia_uid); + rec->sa_gid = from_kgid(&init_user_ns, op_data->op_attr.ia_gid); + rec->sa_size = op_data->op_attr.ia_size; + rec->sa_blocks = op_data->op_attr_blocks; + rec->sa_atime = LTIME_S(op_data->op_attr.ia_atime); + rec->sa_mtime = LTIME_S(op_data->op_attr.ia_mtime); + rec->sa_ctime = LTIME_S(op_data->op_attr.ia_ctime); + rec->sa_attr_flags = + ((struct ll_iattr *)&op_data->op_attr)->ia_attr_flags; if ((op_data->op_attr.ia_valid & ATTR_GID) && - in_group_p(op_data->op_attr.ia_gid)) - rec->sa_suppgid = op_data->op_attr.ia_gid; + in_group_p(op_data->op_attr.ia_gid)) + rec->sa_suppgid = + from_kgid(&init_user_ns, op_data->op_attr.ia_gid); else rec->sa_suppgid = op_data->op_suppgids[0]; diff --git a/lustre/mdc/mdc_request.c b/lustre/mdc/mdc_request.c index ee3a654..cae3942 100644 --- a/lustre/mdc/mdc_request.c +++ b/lustre/mdc/mdc_request.c @@ -405,8 +405,8 @@ static int mdc_xattr_common(struct obd_export *exp,const struct req_format *fmt, sizeof(struct mdt_rec_reint)); rec = req_capsule_client_get(&req->rq_pill, &RMF_REC_REINT); rec->sx_opcode = REINT_SETXATTR; - rec->sx_fsuid = current_fsuid(); - rec->sx_fsgid = current_fsgid(); + rec->sx_fsuid = from_kuid(&init_user_ns, current_fsuid()); + rec->sx_fsgid = from_kgid(&init_user_ns, current_fsgid()); rec->sx_cap = cfs_curproc_cap_pack(); rec->sx_suppgid1 = suppgid; rec->sx_suppgid2 = -1; diff --git a/lustre/mdt/mdt_idmap.c b/lustre/mdt/mdt_idmap.c index e6b8c46..17295ee 100644 --- a/lustre/mdt/mdt_idmap.c +++ b/lustre/mdt/mdt_idmap.c @@ -161,7 +161,7 @@ int mdt_handle_idmap(struct tgt_session_info *tsi) RETURN(-EACCES); } - if (req->rq_auth_mapped_uid == INVALID_UID) { + if (!uid_valid(make_kuid(&init_user_ns, req->rq_auth_mapped_uid))) { CDEBUG(D_SEC, "invalid authorized mapped uid, please check " "/etc/lustre/idmap.conf!\n"); RETURN(-EACCES); diff --git a/lustre/mdt/mdt_lib.c b/lustre/mdt/mdt_lib.c index f0427e4..0b0339c 100644 --- a/lustre/mdt/mdt_lib.c +++ b/lustre/mdt/mdt_lib.c @@ -159,15 +159,16 @@ static int new_init_ucred(struct mdt_thread_info *info, ucred_init_type_t type, ucred->uc_suppgids[1] = -1; } - /* sanity check: we expect the uid which client claimed is true */ - if (remote) { - if (req->rq_auth_mapped_uid == INVALID_UID) { - CDEBUG(D_SEC, "remote user not mapped, deny access!\n"); - RETURN(-EACCES); - } + /* sanity check: we expect the uid which client claimed is true */ + if (remote) { + if (!uid_valid(make_kuid(&init_user_ns, req->rq_auth_mapped_uid))) { + CDEBUG(D_SEC, "remote user not mapped, deny access!\n"); + CDEBUG(D_SEC, "remote user not mapped, deny access!\n"); + RETURN(-EACCES); + } - if (ptlrpc_user_desc_do_idmap(req, pud)) - RETURN(-EACCES); + if (ptlrpc_user_desc_do_idmap(req, pud)) + RETURN(-EACCES); if (req->rq_auth_mapped_uid != pud->pud_uid) { CDEBUG(D_SEC, "remote client %s: auth/mapped uid %u/%u " @@ -331,7 +332,7 @@ int mdt_check_ucred(struct mdt_thread_info *info) /* sanity check: if we use strong authentication, we expect the * uid which client claimed is true */ if (remote) { - if (req->rq_auth_mapped_uid == INVALID_UID) { + if (!uid_valid(make_kuid(&init_user_ns, req->rq_auth_mapped_uid))) { CDEBUG(D_SEC, "remote user not mapped, deny access!\n"); RETURN(-EACCES); } diff --git a/lustre/obdclass/class_obd.c b/lustre/obdclass/class_obd.c index 71b479a..7ea460e 100644 --- a/lustre/obdclass/class_obd.c +++ b/lustre/obdclass/class_obd.c @@ -145,7 +145,8 @@ int lustre_get_jobid(char *jobid) /* Use process name + fsuid as jobid */ if (strcmp(obd_jobid_var, JOBSTATS_PROCNAME_UID) == 0) { snprintf(jobid, JOBSTATS_JOBID_SIZE, "%s.%u", - current_comm(), current_fsuid()); + current_comm(), + from_kuid(&init_user_ns, current_fsuid())); RETURN(0); } diff --git a/lustre/obdclass/idmap.c b/lustre/obdclass/idmap.c index afd2f03..146b40e 100644 --- a/lustre/obdclass/idmap.c +++ b/lustre/obdclass/idmap.c @@ -73,7 +73,8 @@ static int lustre_groups_search(struct group_info *group_info, right = group_info->ngroups; while (left < right) { int mid = (left + right) / 2; - int cmp = grp - CFS_GROUP_AT(group_info, mid); + int cmp = grp - + from_kgid(&init_user_ns, CFS_GROUP_AT(group_info, mid)); if (cmp > 0) left = mid + 1; @@ -113,24 +114,27 @@ void lustre_groups_sort(struct group_info *group_info) ; /* nothing */ stride /= 3; - while (stride) { - max = gidsetsize - stride; - for (base = 0; base < max; base++) { - int left = base; - int right = left + stride; - gid_t tmp = CFS_GROUP_AT(group_info, right); - - while (left >= 0 && - CFS_GROUP_AT(group_info, left) > tmp) { - CFS_GROUP_AT(group_info, right) = - CFS_GROUP_AT(group_info, left); - right = left; - left -= stride; - } - CFS_GROUP_AT(group_info, right) = tmp; - } - stride /= 3; - } + while (stride) { + max = gidsetsize - stride; + for (base = 0; base < max; base++) { + int left = base; + int right = left + stride; + gid_t tmp = from_kgid(&init_user_ns, + CFS_GROUP_AT(group_info, right)); + + while (left >= 0 && + tmp < from_kgid(&init_user_ns, + CFS_GROUP_AT(group_info, left))) { + CFS_GROUP_AT(group_info, right) = + CFS_GROUP_AT(group_info, left); + right = left; + left -= stride; + } + CFS_GROUP_AT(group_info, right) = + make_kgid(&init_user_ns, tmp); + } + stride /= 3; + } } EXPORT_SYMBOL(lustre_groups_sort); diff --git a/lustre/obdclass/linux/linux-obdo.c b/lustre/obdclass/linux/linux-obdo.c index 386e73f..033f6b0 100644 --- a/lustre/obdclass/linux/linux-obdo.c +++ b/lustre/obdclass/linux/linux-obdo.c @@ -199,30 +199,29 @@ void obdo_to_inode(struct inode *dst, struct obdo *src, obd_flag valid) src->o_valid, LTIME_S(dst->i_mtime), LTIME_S(dst->i_ctime), src->o_mtime, src->o_ctime); - if (valid & OBD_MD_FLATIME) - LTIME_S(dst->i_atime) = src->o_atime; - if (valid & OBD_MD_FLMTIME) - LTIME_S(dst->i_mtime) = src->o_mtime; - if (valid & OBD_MD_FLCTIME && src->o_ctime > LTIME_S(dst->i_ctime)) - LTIME_S(dst->i_ctime) = src->o_ctime; - if (valid & OBD_MD_FLSIZE) - i_size_write(dst, src->o_size); - if (valid & OBD_MD_FLBLOCKS) { /* allocation of space */ - dst->i_blocks = src->o_blocks; - if (dst->i_blocks < src->o_blocks) /* overflow */ - dst->i_blocks = -1; - - } + if (valid & OBD_MD_FLATIME) + LTIME_S(dst->i_atime) = src->o_atime; + if (valid & OBD_MD_FLMTIME) + LTIME_S(dst->i_mtime) = src->o_mtime; + if (valid & OBD_MD_FLCTIME && src->o_ctime > LTIME_S(dst->i_ctime)) + LTIME_S(dst->i_ctime) = src->o_ctime; + if (valid & OBD_MD_FLSIZE) + i_size_write(dst, src->o_size); + if (valid & OBD_MD_FLBLOCKS) { /* allocation of space */ + dst->i_blocks = src->o_blocks; + if (dst->i_blocks < src->o_blocks) /* overflow */ + dst->i_blocks = -1; + } if (valid & OBD_MD_FLBLKSZ) dst->i_blkbits = ffs(src->o_blksize)-1; - if (valid & OBD_MD_FLMODE) - dst->i_mode = (dst->i_mode & S_IFMT) | (src->o_mode & ~S_IFMT); - if (valid & OBD_MD_FLUID) - dst->i_uid = src->o_uid; - if (valid & OBD_MD_FLGID) - dst->i_gid = src->o_gid; - if (valid & OBD_MD_FLFLAGS) - dst->i_flags = src->o_flags; + if (valid & OBD_MD_FLMODE) + dst->i_mode = (dst->i_mode & S_IFMT) | (src->o_mode & ~S_IFMT); + if (valid & OBD_MD_FLUID) + dst->i_uid = make_kuid(&init_user_ns, src->o_uid); + if (valid & OBD_MD_FLGID) + dst->i_gid = make_kgid(&init_user_ns, src->o_gid); + if (valid & OBD_MD_FLFLAGS) + dst->i_flags = src->o_flags; } EXPORT_SYMBOL(obdo_to_inode); #endif diff --git a/lustre/obdclass/obdo.c b/lustre/obdclass/obdo.c index e99b17a..5604600 100644 --- a/lustre/obdclass/obdo.c +++ b/lustre/obdclass/obdo.c @@ -103,19 +103,19 @@ void obdo_from_inode(struct obdo *dst, struct inode *src, obd_flag valid) (src->i_mode & S_IALLUGO); newvalid |= OBD_MD_FLMODE; } - if (valid & OBD_MD_FLUID) { - dst->o_uid = src->i_uid; - newvalid |= OBD_MD_FLUID; - } - if (valid & OBD_MD_FLGID) { - dst->o_gid = src->i_gid; - newvalid |= OBD_MD_FLGID; - } - if (valid & OBD_MD_FLFLAGS) { - dst->o_flags = ll_inode_flags(src); - newvalid |= OBD_MD_FLFLAGS; - } - dst->o_valid |= newvalid; + if (valid & OBD_MD_FLUID) { + dst->o_uid = from_kuid(&init_user_ns, src->i_uid); + newvalid |= OBD_MD_FLUID; + } + if (valid & OBD_MD_FLGID) { + dst->o_gid = from_kgid(&init_user_ns, src->i_gid); + newvalid |= OBD_MD_FLGID; + } + if (valid & OBD_MD_FLFLAGS) { + dst->o_flags = ll_inode_flags(src); + newvalid |= OBD_MD_FLFLAGS; + } + dst->o_valid |= newvalid; } EXPORT_SYMBOL(obdo_from_inode); @@ -231,25 +231,25 @@ void obdo_from_iattr(struct obdo *oa, struct iattr *attr, unsigned int ia_valid) oa->o_ctime = LTIME_S(attr->ia_ctime); oa->o_valid |= OBD_MD_FLCTIME; } - if (ia_valid & ATTR_SIZE) { - oa->o_size = attr->ia_size; - oa->o_valid |= OBD_MD_FLSIZE; - } + if (ia_valid & ATTR_SIZE) { + oa->o_size = attr->ia_size; + oa->o_valid |= OBD_MD_FLSIZE; + } if (ia_valid & ATTR_MODE) { oa->o_mode = attr->ia_mode; oa->o_valid |= OBD_MD_FLTYPE | OBD_MD_FLMODE; - if (!in_group_p(oa->o_gid) && + if (!in_group_p(make_kgid(&init_user_ns, oa->o_gid)) && !cfs_capable(CFS_CAP_FSETID)) oa->o_mode &= ~S_ISGID; } - if (ia_valid & ATTR_UID) { - oa->o_uid = attr->ia_uid; - oa->o_valid |= OBD_MD_FLUID; - } - if (ia_valid & ATTR_GID) { - oa->o_gid = attr->ia_gid; - oa->o_valid |= OBD_MD_FLGID; - } + if (ia_valid & ATTR_UID) { + oa->o_uid = from_kuid(&init_user_ns, attr->ia_uid); + oa->o_valid |= OBD_MD_FLUID; + } + if (ia_valid & ATTR_GID) { + oa->o_gid = from_kgid(&init_user_ns, attr->ia_gid); + oa->o_valid |= OBD_MD_FLGID; + } } EXPORT_SYMBOL(obdo_from_iattr); @@ -287,16 +287,16 @@ void iattr_from_obdo(struct iattr *attr, struct obdo *oa, obd_flag valid) if (valid & OBD_MD_FLMODE) { attr->ia_mode = (attr->ia_mode & S_IFMT)|(oa->o_mode & ~S_IFMT); attr->ia_valid |= ATTR_MODE; - if (!in_group_p(oa->o_gid) && + if (!in_group_p(make_kgid(&init_user_ns, oa->o_gid)) && !cfs_capable(CFS_CAP_FSETID)) attr->ia_mode &= ~S_ISGID; } if (valid & OBD_MD_FLUID) { - attr->ia_uid = oa->o_uid; + attr->ia_uid = make_kuid(&init_user_ns, oa->o_uid); attr->ia_valid |= ATTR_UID; } if (valid & OBD_MD_FLGID) { - attr->ia_gid = oa->o_gid; + attr->ia_gid = make_kgid(&init_user_ns, oa->o_gid); attr->ia_valid |= ATTR_GID; } } diff --git a/lustre/obdecho/echo_client.c b/lustre/obdecho/echo_client.c index 38cff00..1dc8e63 100644 --- a/lustre/obdecho/echo_client.c +++ b/lustre/obdecho/echo_client.c @@ -2091,11 +2091,15 @@ static void echo_ucred_init(struct lu_env *env) ucred->uc_suppgids[0] = -1; ucred->uc_suppgids[1] = -1; - ucred->uc_uid = ucred->uc_o_uid = current_uid(); - ucred->uc_gid = ucred->uc_o_gid = current_gid(); - ucred->uc_fsuid = ucred->uc_o_fsuid = current_fsuid(); - ucred->uc_fsgid = ucred->uc_o_fsgid = current_fsgid(); - ucred->uc_cap = cfs_curproc_cap_pack(); + ucred->uc_uid = ucred->uc_o_uid = + from_kuid(&init_user_ns, current_uid()); + ucred->uc_gid = ucred->uc_o_gid = + from_kgid(&init_user_ns, current_gid()); + ucred->uc_fsuid = ucred->uc_o_fsuid = + from_kuid(&init_user_ns, current_fsuid()); + ucred->uc_fsgid = ucred->uc_o_fsgid = + from_kgid(&init_user_ns, current_fsgid()); + ucred->uc_cap = cfs_curproc_cap_pack(); /* remove fs privilege for non-root user. */ if (ucred->uc_fsuid) diff --git a/lustre/ptlrpc/sec.c b/lustre/ptlrpc/sec.c index 04dde8d..4d93aa4 100644 --- a/lustre/ptlrpc/sec.c +++ b/lustre/ptlrpc/sec.c @@ -286,8 +286,8 @@ struct ptlrpc_cli_ctx *get_my_ctx(struct ptlrpc_sec *sec) remove_dead = 0; } } else { - vcred.vc_uid = current_uid(); - vcred.vc_gid = current_gid(); + vcred.vc_uid = from_kuid(&init_user_ns, current_uid()); + vcred.vc_gid = from_kgid(&init_user_ns, current_gid()); } return sec->ps_policy->sp_cops->lookup_ctx(sec, &vcred, create, @@ -1540,7 +1540,8 @@ void sptlrpc_import_flush_root_ctx(struct obd_import *imp) void sptlrpc_import_flush_my_ctx(struct obd_import *imp) { - import_flush_ctx_common(imp, current_uid(), 1, 1); + import_flush_ctx_common(imp, from_kuid(&init_user_ns, current_uid()), + 1, 1); } EXPORT_SYMBOL(sptlrpc_import_flush_my_ctx); @@ -2072,8 +2073,8 @@ int sptlrpc_svc_unwrap_request(struct ptlrpc_request *req) req->rq_flvr.sf_rpc = WIRE_FLVR(msg->lm_secflvr); req->rq_sp_from = LUSTRE_SP_ANY; - req->rq_auth_uid = INVALID_UID; - req->rq_auth_mapped_uid = INVALID_UID; + req->rq_auth_uid = -1; /* set to INVALID_UID */ + req->rq_auth_mapped_uid = -1; policy = sptlrpc_wireflavor2policy(req->rq_flvr.sf_rpc); if (!policy) { @@ -2428,10 +2429,10 @@ int sptlrpc_pack_user_desc(struct lustre_msg *msg, int offset) pud = lustre_msg_buf(msg, offset, 0); - pud->pud_uid = current_uid(); - pud->pud_gid = current_gid(); - pud->pud_fsuid = current_fsuid(); - pud->pud_fsgid = current_fsgid(); + pud->pud_uid = from_kuid(&init_user_ns, current_uid()); + pud->pud_gid = from_kgid(&init_user_ns, current_gid()); + pud->pud_fsuid = from_kuid(&init_user_ns, current_fsuid()); + pud->pud_fsgid = from_kgid(&init_user_ns, current_fsgid()); pud->pud_cap = cfs_curproc_cap_pack(); pud->pud_ngroups = (msg->lm_buflens[offset] - sizeof(*pud)) / 4; diff --git a/lustre/target/tgt_handler.c b/lustre/target/tgt_handler.c index 3d3c690..3109f9c 100644 --- a/lustre/target/tgt_handler.c +++ b/lustre/target/tgt_handler.c @@ -797,7 +797,7 @@ static int tgt_init_sec_level(struct ptlrpc_request *req) RETURN(-EACCES); } } else { - if (req->rq_auth_uid == INVALID_UID) { + if (!uid_valid(make_kuid(&init_user_ns, req->rq_auth_uid))) { CDEBUG(D_SEC, "client %s -> target %s: user is not " "authenticated!\n", client, tgt_name(tgt)); RETURN(-EACCES);