From a5b01b08734dbe2de0df673a1c0e198e5130023e Mon Sep 17 00:00:00 2001 From: fanyong Date: Fri, 17 Nov 2006 09:24:34 +0000 Subject: [PATCH] Fix about remote acl operation: (1) push_ctxt can not switch user space context (uid / gid), do not use it any more. (2) ship user info (uid / gid) as argv[] to user space by upcall, switch user by setuid / setgid in user space. (3) do not cache for remote acl upcall, do not use fid as key for remote acl upcall, it maybe cause wrong result when concurrent remote acl operations. (4) remove unused code. --- lustre/include/lustre/lustre_user.h | 2 +- lustre/include/lustre_ucache.h | 5 ++- lustre/mdt/mdt_handler.c | 10 +---- lustre/mdt/mdt_internal.h | 3 +- lustre/mdt/mdt_lproc.c | 6 +-- lustre/mdt/mdt_rmtacl.c | 81 ++++++++++++++++++++++--------------- lustre/mdt/mdt_xattr.c | 21 ++++------ lustre/utils/l_facl.c | 35 ++++++++++++---- 8 files changed, 94 insertions(+), 69 deletions(-) diff --git a/lustre/include/lustre/lustre_user.h b/lustre/include/lustre/lustre_user.h index 158be62..46babf9 100644 --- a/lustre/include/lustre/lustre_user.h +++ b/lustre/include/lustre/lustre_user.h @@ -206,7 +206,7 @@ struct identity_downcall_data { struct rmtacl_downcall_data { __u32 add_magic; __u32 add_handle; - __u64 add_ino; + __u64 add_key; __u32 add_buflen; __u8 add_buf[0]; }; diff --git a/lustre/include/lustre_ucache.h b/lustre/include/lustre_ucache.h index 32705bf..3fde667 100644 --- a/lustre/include/lustre_ucache.h +++ b/lustre/include/lustre_ucache.h @@ -50,11 +50,14 @@ struct mdt_identity { }; struct rmtacl_upcall_data { + uid_t aud_uid; + gid_t aud_gid; char *aud_cmd; }; struct mdt_rmtacl { - unsigned long ra_ino; + uid_t ra_uid; + gid_t ra_gid; __u32 ra_handle; char *ra_cmd; char *ra_buf; diff --git a/lustre/mdt/mdt_handler.c b/lustre/mdt/mdt_handler.c index b1db8e0..d99fc27 100644 --- a/lustre/mdt/mdt_handler.c +++ b/lustre/mdt/mdt_handler.c @@ -3588,7 +3588,6 @@ static int mdt_init0(const struct lu_env *env, struct mdt_device *m, const char *num = lustre_cfg_string(cfg, 2); struct lustre_mount_info *lmi; struct lustre_sb_info *lsi; - struct vfsmount *mnt; struct lu_site *s; int rc; ENTRY; @@ -3613,14 +3612,7 @@ static int mdt_init0(const struct lu_env *env, struct mdt_device *m, } else { lsi = s2lsi(lmi->lmi_sb); fsoptions_to_mdt_flags(m, lsi->lsi_lmd->lmd_opts); - - mnt = lmi->lmi_mnt; - OBD_SET_CTXT_MAGIC(&obd->obd_lvfs_ctxt); - obd->obd_lvfs_ctxt.pwdmnt = mnt; - obd->obd_lvfs_ctxt.pwd = mnt->mnt_root; - obd->obd_lvfs_ctxt.fs = get_ds(); - - server_put_mount_2(dev, mnt); + server_put_mount_2(dev, lmi->lmi_mnt); } spin_lock_init(&m->mdt_ioepoch_lock); diff --git a/lustre/mdt/mdt_internal.h b/lustre/mdt/mdt_internal.h index 1cd6068..583ebf3 100644 --- a/lustre/mdt/mdt_internal.h +++ b/lustre/mdt/mdt_internal.h @@ -613,8 +613,7 @@ int mdt_pack_remote_perm(struct mdt_thread_info *, struct mdt_object *, void *); extern struct upcall_cache_ops mdt_rmtacl_upcall_cache_ops; -int mdt_rmtacl_upcall(struct mdt_thread_info *, unsigned long, - char *, struct lu_buf *); +int mdt_rmtacl_upcall(struct mdt_thread_info *, char *, struct lu_buf *); extern struct lu_context_key mdt_thread_key; /* debug issues helper starts here*/ diff --git a/lustre/mdt/mdt_lproc.c b/lustre/mdt/mdt_lproc.c index 527c9b6..bd01582 100644 --- a/lustre/mdt/mdt_lproc.c +++ b/lustre/mdt/mdt_lproc.c @@ -446,19 +446,19 @@ static int lprocfs_wr_rmtacl_info(struct file *file, const char *buffer, OBD_ALLOC(param, size); if (!param) { CERROR("%s: fail to alloc %d bytes for ino "LPU64"\n", - obd->obd_name, size, sparam.add_ino); + obd->obd_name, size, sparam.add_key); param = &sparam; param->add_buflen = 0; } else if (copy_from_user(param, buffer, size)) { CERROR("%s: ino "LPU64" bad remote acl data\n", - obd->obd_name, sparam.add_ino); + obd->obd_name, sparam.add_key); OBD_FREE(param, size); param = &sparam; param->add_buflen = 0; } } - rc = upcall_cache_downcall(mdt->mdt_rmtacl_cache, 0, param->add_ino, + rc = upcall_cache_downcall(mdt->mdt_rmtacl_cache, 0, param->add_key, param); out: diff --git a/lustre/mdt/mdt_rmtacl.c b/lustre/mdt/mdt_rmtacl.c index c973679..7586076 100644 --- a/lustre/mdt/mdt_rmtacl.c +++ b/lustre/mdt/mdt_rmtacl.c @@ -58,12 +58,32 @@ #define MAX_CMD_LEN 256 +static __u64 rmtacl_key = 0; +static spinlock_t rmtacl_key_lock = SPIN_LOCK_UNLOCKED; + +/* + * For remote acl operation, do NOT cache! + * Use different key for each remote acl operation. + */ +static __u64 mdt_rmtacl_getkey(void) +{ + __u64 key; + + spin_lock(&rmtacl_key_lock); + key = ++rmtacl_key; + spin_unlock(&rmtacl_key_lock); + + return key; +} + static void mdt_rmtacl_entry_init(struct upcall_cache_entry *entry, void *args) { struct rmtacl_upcall_data *data = args; struct mdt_rmtacl *acl = &entry->u.acl; char *cmd; + acl->ra_uid = data->aud_uid; + acl->ra_gid = data->aud_gid; /* we use address of this cache entry as handle */ acl->ra_handle = (__u32)entry; OBD_ALLOC(cmd, strlen(data->aud_cmd) + 1); @@ -71,7 +91,7 @@ static void mdt_rmtacl_entry_init(struct upcall_cache_entry *entry, void *args) return; /* upcall will fail later! */ strcpy(cmd, data->aud_cmd); - entry->u.acl.ra_cmd = cmd; + acl->ra_cmd = cmd; } static void mdt_rmtacl_entry_free(struct upcall_cache *cache, @@ -115,15 +135,19 @@ static int mdt_rmtacl_do_upcall(struct upcall_cache *cache, struct upcall_cache_entry *entry) { struct mdt_rmtacl *acl = &entry->u.acl; + char uidstr[8] = ""; + char gidstr[8] = ""; char handle[20] = ""; char keystr[20] = ""; char *argv[] = { [0] = cache->uc_upcall, - [1] = cache->uc_name, - [2] = keystr, - [3] = handle, - [4] = acl->ra_cmd, - [5] = NULL + [1] = uidstr, + [2] = gidstr, + [3] = cache->uc_name, + [4] = keystr, + [5] = handle, + [6] = acl->ra_cmd, + [7] = NULL }; char *envp[] = { [0] = "HOME=/", @@ -136,24 +160,27 @@ static int mdt_rmtacl_do_upcall(struct upcall_cache *cache, if (!acl->ra_cmd) RETURN(-ENOMEM); + snprintf(uidstr, sizeof(uidstr), "%u", acl->ra_uid); + snprintf(gidstr, sizeof(gidstr), "%u", acl->ra_gid); snprintf(keystr, sizeof(keystr), LPU64, entry->ue_key); snprintf(handle, sizeof(handle), "%u", acl->ra_handle); LASSERTF(strcmp(cache->uc_upcall, "NONE"), "no upcall set!"); - CDEBUG(D_INFO, "%s: remote acl upcall %s %s %s %s %s\n", - cache->uc_name, argv[0], argv[1], argv[2], argv[3], argv[4]); + CDEBUG(D_INFO, "%s: remote acl upcall %s %s %s %s %s %s %s\n", + cache->uc_name, argv[0], argv[1], argv[2], argv[3], argv[4], + argv[5], argv[6]); rc = USERMODEHELPER(argv[0], argv, envp); if (rc < 0) { - CERROR("%s: error invoking upcall %s %s %s %s %s: rc %d; " + CERROR("%s: error invoking upcall %s %s %s %s %s %s %s: rc %d; " "check /proc/fs/lustre/mdt/%s/rmtacl_upcall\n", cache->uc_name, argv[0], argv[1], argv[2], argv[3], - argv[4], rc, cache->uc_name); + argv[4], argv[5], argv[6], rc, cache->uc_name); } else { - CDEBUG(D_HA, "%s: invoked upcall %s %s %s %s %s\n", + CDEBUG(D_HA, "%s: invoked upcall %s %s %s %s %s %s %s\n", cache->uc_name, argv[0], argv[1], argv[2], argv[3], - argv[4]); + argv[4], argv[5], argv[6]); rc = 0; } RETURN(rc); @@ -195,41 +222,29 @@ struct upcall_cache_ops mdt_rmtacl_upcall_cache_ops = { .parse_downcall = mdt_rmtacl_parse_downcall, }; -int mdt_rmtacl_upcall(struct mdt_thread_info *info, unsigned long key, - char *cmd, struct lu_buf *buf) +int mdt_rmtacl_upcall(struct mdt_thread_info *info, char *cmd, + struct lu_buf *buf) { - struct ptlrpc_request *req = mdt_info_req(info); - struct obd_device *obd = req->rq_export->exp_obd; struct mdt_device *mdt = info->mti_mdt; - struct lvfs_ucred uc; - struct md_ucred *uc0 = mdt_ucred(info); - struct lvfs_run_ctxt saved; + struct md_ucred *uc = mdt_ucred(info); struct rmtacl_upcall_data data; struct upcall_cache_entry *entry; + __u64 key; char *tmp = NULL; - int rc = 0; + int rc = 0; ENTRY; OBD_ALLOC(tmp, PAGE_SIZE); if (!tmp) RETURN(-ENOMEM); + data.aud_uid = uc->mu_fsuid; + data.aud_gid = uc->mu_fsgid; data.aud_cmd = cmd; - uc.luc_uid = uc0->mu_uid; - uc.luc_gid = uc0->mu_gid; - uc.luc_fsuid = uc0->mu_fsuid; - uc.luc_fsgid = uc0->mu_fsgid; - uc.luc_cap = uc0->mu_cap; - uc.luc_umask = uc0->mu_umask; - uc.luc_ginfo = uc0->mu_ginfo; - uc.luc_identity = uc0->mu_identity; - - push_ctxt(&saved, &obd->obd_lvfs_ctxt, &uc); - entry = upcall_cache_get_entry(mdt->mdt_rmtacl_cache, (__u64)key, - &data); - pop_ctxt(&saved, &obd->obd_lvfs_ctxt, &uc); + key = mdt_rmtacl_getkey(); + entry = upcall_cache_get_entry(mdt->mdt_rmtacl_cache, key, &data); if (IS_ERR(entry)) GOTO(out, rc = PTR_ERR(entry)); diff --git a/lustre/mdt/mdt_xattr.c b/lustre/mdt/mdt_xattr.c index 4f414b7..97cd57d 100644 --- a/lustre/mdt/mdt_xattr.c +++ b/lustre/mdt/mdt_xattr.c @@ -108,8 +108,7 @@ static int mdt_getxattr_pack_reply(struct mdt_thread_info * info) RETURN(size); } -static int do_remote_getfacl(struct mdt_thread_info *info, - struct lu_fid *fid, struct lu_buf *buf) +static int do_remote_getfacl(struct mdt_thread_info *info, struct lu_buf *buf) { struct ptlrpc_request *req = mdt_info_req(info); char *cmd; @@ -125,7 +124,7 @@ static int do_remote_getfacl(struct mdt_thread_info *info, RETURN(-EFAULT); } - rc = mdt_rmtacl_upcall(info, fid_oid(fid), cmd, buf); + rc = mdt_rmtacl_upcall(info, cmd, buf); if (rc) CERROR("remote acl upcall failed: %d\n", rc); @@ -176,14 +175,10 @@ int mdt_getxattr(struct mdt_thread_info *info) &RMF_NAME); CDEBUG(D_INODE, "getxattr %s\n", xattr_name); - if (!strcmp(xattr_name, XATTR_NAME_LUSTRE_ACL)) { - struct mdt_body *body = - (struct mdt_body *)info->mti_body; - - rc = do_remote_getfacl(info, &body->fid1, buf); - } else { + if (!strcmp(xattr_name, XATTR_NAME_LUSTRE_ACL)) + rc = do_remote_getfacl(info, buf); + else rc = mo_xattr_get(info->mti_env, next, buf, xattr_name); - } if (rc < 0) CERROR("getxattr failed: %d\n", rc); @@ -231,7 +226,7 @@ static int mdt_setxattr_pack_reply(struct mdt_thread_info * info) return rc = rc1 ? rc1 : rc; } -static int do_remote_setfacl(struct mdt_thread_info *info, struct lu_fid *fid) +static int do_remote_setfacl(struct mdt_thread_info *info) { struct ptlrpc_request *req = mdt_info_req(info); struct lu_buf *buf = &info->mti_buf; @@ -249,7 +244,7 @@ static int do_remote_setfacl(struct mdt_thread_info *info, struct lu_fid *fid) LASSERT(buf->lb_buf); buf->lb_len = RMTACL_SIZE_MAX; - rc = mdt_rmtacl_upcall(info, fid_oid(fid), cmd, buf); + rc = mdt_rmtacl_upcall(info, cmd, buf); if (rc) CERROR("remote acl upcall failed: %d\n", rc); @@ -304,7 +299,7 @@ int mdt_setxattr(struct mdt_thread_info *info) if (((valid & OBD_MD_FLXATTR) == OBD_MD_FLXATTR) && (!strcmp(xattr_name, XATTR_NAME_LUSTRE_ACL))) { - rc = do_remote_setfacl(info, &body->fid1); + rc = do_remote_setfacl(info); GOTO(out, rc); } diff --git a/lustre/utils/l_facl.c b/lustre/utils/l_facl.c index ed2c0a9..828b622 100644 --- a/lustre/utils/l_facl.c +++ b/lustre/utils/l_facl.c @@ -46,7 +46,7 @@ static char *progname; static void usage(void) { fprintf(stderr, - "\nusage: %s {mdtname} {ino} {handle} {cmd}\n" + "\nusage: %s {uid} {gid} {mdtname} {ino} {handle} {cmd}\n" "Normally invoked as an upcall from Lustre, set via:\n" " /proc/fs/lustre/mdt/{mdtname}/rmtacl_upcall\n", progname); @@ -109,7 +109,7 @@ int main(int argc, char **argv) progname = basename(argv[0]); - if (argc != 5) { + if (argc != 7) { usage(); return 1; } @@ -122,8 +122,8 @@ int main(int argc, char **argv) } memset(data, 0, size); data->add_magic = RMTACL_DOWNCALL_MAGIC; - data->add_ino = strtoll(argv[2], NULL, 10); - data->add_handle = strtoul(argv[3], NULL, 10); + data->add_key = strtoll(argv[4], NULL, 10); + data->add_handle = strtoul(argv[5], NULL, 10); buf = data->add_buf; mntpath = get_lustre_mount(); @@ -142,6 +142,9 @@ int main(int argc, char **argv) errlog(buf, MDS_ERR"(fork failed): %s\n", strerror(errno)); goto downcall; } else if (pid == 0) { + uid_t uid; + gid_t gid; + close(out_pipe[0]); if (out_pipe[1] != STDOUT_FILENO) { dup2(out_pipe[1], STDOUT_FILENO); @@ -160,9 +163,27 @@ int main(int argc, char **argv) return 1; } - execl("/bin/sh", "sh", "-c", argv[4], NULL); + gid = (gid_t)atoi(argv[2]); + if (gid) { + if (setgid(gid) == -1) { + fprintf(stderr, "setgid %u failed: %s\n", + gid, strerror(errno)); + return 1; + } + } + + uid = (uid_t)atoi(argv[1]); + if (uid) { + if (setuid(uid) == -1) { + fprintf(stderr, "setuid %u failed: %s\n", + uid, strerror(errno)); + return 1; + } + } + + execl("/bin/sh", "sh", "-c", argv[6], NULL); fprintf(stderr, "execl %s failed: %s\n", - argv[4], strerror(errno)); + argv[6], strerror(errno)); return 1; } @@ -217,7 +238,7 @@ downcall: } snprintf(procname, sizeof(procname), - "/proc/fs/lustre/mdt/%s/rmtacl_info", argv[1]); + "/proc/fs/lustre/mdt/%s/rmtacl_info", argv[3]); fd = open(procname, O_WRONLY); if (fd < 0) { fprintf(stderr, "open %s failed: %s\n", -- 1.8.3.1