X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fptlrpc%2Fsec_lproc.c;h=8531103291f74eb2cc3b41c26f351d41cae10048;hb=add70ce9cdc3e2d6148dafeef587d12d0277744c;hp=c6c0242df973c6ac85f93d976730ad9e7b385b24;hpb=50f28f81b5aa8f8ad1c8585bd7e262910f936e50;p=fs%2Flustre-release.git diff --git a/lustre/ptlrpc/sec_lproc.c b/lustre/ptlrpc/sec_lproc.c index c6c0242..8531103 100644 --- a/lustre/ptlrpc/sec_lproc.c +++ b/lustre/ptlrpc/sec_lproc.c @@ -79,12 +79,12 @@ static int sptlrpc_info_lprocfs_seq_show(struct seq_file *seq, void *v) strcmp(obd->obd_type->typ_name, LUSTRE_LWP_NAME) == 0 || strcmp(obd->obd_type->typ_name, LUSTRE_OSP_NAME) == 0); - if (cli->cl_import) - sec = sptlrpc_import_sec_ref(cli->cl_import); - if (sec == NULL) - goto out; + if (cli->cl_import) + sec = sptlrpc_import_sec_ref(cli->cl_import); + if (sec == NULL) + goto out; - sec_flags2str(sec->ps_flvr.sf_flags, str, sizeof(str)); + sec_flags2str(sec->ps_flvr.sf_flags, str, sizeof(str)); seq_printf(seq, "rpc flavor: %s\n", sptlrpc_flavor2name_base(sec->ps_flvr.sf_rpc)); @@ -96,14 +96,14 @@ static int sptlrpc_info_lprocfs_seq_show(struct seq_file *seq, void *v) seq_printf(seq, "refcount: %d\n", atomic_read(&sec->ps_refcount)); seq_printf(seq, "nctx: %d\n", atomic_read(&sec->ps_nctx)); - seq_printf(seq, "gc internal %lld\n", sec->ps_gc_interval); + seq_printf(seq, "gc interval %lld\n", sec->ps_gc_interval); seq_printf(seq, "gc next %lld\n", sec->ps_gc_interval ? (s64)(sec->ps_gc_next - ktime_get_real_seconds()) : 0ll); sptlrpc_sec_put(sec); out: - return 0; + return 0; } LDEBUGFS_SEQ_FOPS_RO(sptlrpc_info_lprocfs); @@ -120,45 +120,102 @@ static int sptlrpc_ctxs_lprocfs_seq_show(struct seq_file *seq, void *v) strcmp(obd->obd_type->typ_name, LUSTRE_LWP_NAME) == 0 || strcmp(obd->obd_type->typ_name, LUSTRE_OSP_NAME) == 0); - if (cli->cl_import) - sec = sptlrpc_import_sec_ref(cli->cl_import); - if (sec == NULL) - goto out; + if (cli->cl_import) + sec = sptlrpc_import_sec_ref(cli->cl_import); + if (sec == NULL) + goto out; - if (sec->ps_policy->sp_cops->display) - sec->ps_policy->sp_cops->display(sec, seq); + if (sec->ps_policy->sp_cops->display) + sec->ps_policy->sp_cops->display(sec, seq); - sptlrpc_sec_put(sec); + sptlrpc_sec_put(sec); out: - return 0; + return 0; } LDEBUGFS_SEQ_FOPS_RO(sptlrpc_ctxs_lprocfs); +static inline +bool sptlrpc_sepol_update_needed(struct ptlrpc_sec *imp_sec, + ktime_t mtime, char *pol, size_t pol_len) +{ + struct sptlrpc_sepol *old; + bool rc; + + rcu_read_lock(); + old = rcu_dereference(imp_sec->ps_sepol); + if (!old) + rc = true; + else if (!kref_read(&old->ssp_ref)) + rc = false; + else if (ktime_compare(old->ssp_mtime, mtime) != 0) + rc = true; + else + rc = false; + rcu_read_unlock(); + + return rc; +} +static int sptlrpc_sepol_update(struct obd_import *imp, + ktime_t mtime, char *pol, size_t pol_len) +{ + struct sptlrpc_sepol *old; + struct sptlrpc_sepol *new; + struct ptlrpc_sec *imp_sec; + int rc = 0; + + imp_sec = sptlrpc_import_sec_ref(imp); + if (!imp_sec) + RETURN(-ENODEV); + + if (!sptlrpc_sepol_update_needed(imp_sec, mtime, pol, pol_len)) + GOTO(out, rc); + + new = kmalloc(sizeof(typeof(*new)) + pol_len + 1, GFP_KERNEL); + if (!new) + GOTO(out, rc = -ENOMEM); + + kref_init(&new->ssp_ref); + new->ssp_sepol_size = pol_len + 1; + new->ssp_mtime = mtime; + strscpy(new->ssp_sepol, pol, new->ssp_sepol_size); + + spin_lock(&imp_sec->ps_lock); + old = rcu_dereference_protected(imp_sec->ps_sepol, 1); + rcu_assign_pointer(imp_sec->ps_sepol, new); + spin_unlock(&imp_sec->ps_lock); + sptlrpc_sepol_put(old); +out: + sptlrpc_sec_put(imp_sec); + + return rc; +} + #if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 16, 53, 0) static ssize_t sepol_seq_write_old(struct obd_device *obd, - const char __user *buffer, - size_t count) + const char __user *buffer, size_t count) { struct client_obd *cli = &obd->u.cli; struct obd_import *imp = cli->cl_import; struct sepol_downcall_data_old *param; - int size = sizeof(*param); - __u16 len; + size_t maxlen = LUSTRE_NODEMAP_SEPOL_LENGTH + 1; + size_t size = sizeof(*param); + size_t maxparam = sizeof(*param) + maxlen; + int len; int rc = 0; - if (count < size) { + if (count <= size) { rc = -EINVAL; - CERROR("%s: invalid data count = %lu, size = %d: rc = %d\n", - obd->obd_name, (unsigned long) count, size, rc); + CERROR("%s: invalid data count %zu <= size %zu: rc = %d\n", + obd->obd_name, count, size, rc); return rc; } - OBD_ALLOC(param, size); - if (param == NULL) + OBD_ALLOC(param, maxparam); + if (!param) return -ENOMEM; - if (copy_from_user(param, buffer, size)) { + if (copy_from_user(param, buffer, min(count, maxparam))) { rc = -EFAULT; CERROR("%s: bad sepol data: rc = %d\n", obd->obd_name, rc); GOTO(out, rc); @@ -166,53 +223,34 @@ static ssize_t sepol_seq_write_old(struct obd_device *obd, if (param->sdd_magic != SEPOL_DOWNCALL_MAGIC_OLD) { rc = -EINVAL; - CERROR("%s: sepol downcall bad params: rc = %d\n", - obd->obd_name, rc); + CERROR("%s: sepol downcall bad magic %#08x != %#08x: rc = %d\n", + obd->obd_name, param->sdd_magic, + SEPOL_DOWNCALL_MAGIC_OLD, rc); GOTO(out, rc); } - if (param->sdd_sepol_len == 0 || - param->sdd_sepol_len >= sizeof(imp->imp_sec->ps_sepol)) { + len = param->sdd_sepol_len; + if (len == 0 || len >= maxlen) { rc = -EINVAL; - CERROR("%s: invalid sepol data returned: rc = %d\n", - obd->obd_name, rc); + CERROR("%s: bad sepol len %u >= maxlen %zu: rc = %d\n", + obd->obd_name, len, maxlen, rc); GOTO(out, rc); } - len = param->sdd_sepol_len; /* save sdd_sepol_len */ - OBD_FREE(param, size); - size = offsetof(struct sepol_downcall_data_old, - sdd_sepol[len]); + size = offsetof(typeof(*param), sdd_sepol[len]); if (count < size) { rc = -EINVAL; - CERROR("%s: invalid sepol count = %lu, size = %d: rc = %d\n", - obd->obd_name, (unsigned long) count, size, rc); - return rc; - } - - /* alloc again with real size */ - OBD_ALLOC(param, size); - if (param == NULL) - return -ENOMEM; - - if (copy_from_user(param, buffer, size)) { - rc = -EFAULT; - CERROR("%s: cannot copy sepol data: rc = %d\n", - obd->obd_name, rc); + CERROR("%s: bad sepol count %zu < total size %zu: rc = %d\n", + obd->obd_name, count, size, rc); GOTO(out, rc); } - spin_lock(&imp->imp_sec->ps_lock); - snprintf(imp->imp_sec->ps_sepol, param->sdd_sepol_len + 1, "%s", - param->sdd_sepol); - imp->imp_sec->ps_sepol_mtime = ktime_set(param->sdd_sepol_mtime, 0); - spin_unlock(&imp->imp_sec->ps_lock); - + rc = sptlrpc_sepol_update(imp, ktime_set(param->sdd_sepol_mtime, 0), + param->sdd_sepol, len); out: - if (param != NULL) - OBD_FREE(param, size); + OBD_FREE(param, maxparam); - return rc ? rc : count; + return rc ?: count; } #endif @@ -225,91 +263,107 @@ ldebugfs_sptlrpc_sepol_seq_write(struct file *file, const char __user *buffer, struct client_obd *cli = &obd->u.cli; struct obd_import *imp = cli->cl_import; struct sepol_downcall_data *param; - __u32 magic; - int size = sizeof(magic); - __u16 len; + size_t maxlen = LUSTRE_NODEMAP_SEPOL_LENGTH + 1; + size_t size = sizeof(*param); + size_t maxparam = size + maxlen; + int len; int rc = 0; - if (count < size) { + if (count <= size) { rc = -EINVAL; - CERROR("%s: invalid buffer count = %lu, size = %d: rc = %d\n", - obd->obd_name, (unsigned long) count, size, rc); - return rc; - } - - if (copy_from_user(&magic, buffer, size)) { - rc = -EFAULT; - CERROR("%s: bad sepol magic: rc = %d\n", obd->obd_name, rc); + CERROR("%s: invalid data count %zu <= size %zu: rc = %d\n", + obd->obd_name, count, size, rc); return rc; } - if (magic != SEPOL_DOWNCALL_MAGIC) { #if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 16, 53, 0) - if (magic == SEPOL_DOWNCALL_MAGIC_OLD) { - return sepol_seq_write_old(obd, buffer, count); + { + __u32 magic; + + if (copy_from_user(&magic, buffer, sizeof(magic))) { + rc = -EFAULT; + CERROR("%s: bad sepol magic data: rc = %d\n", + obd->obd_name, rc); + return rc; } -#endif - rc = -EINVAL; - CERROR("%s: sepol downcall bad magic '%#08x': rc = %d\n", - obd->obd_name, magic, rc); - return rc; - } - size = sizeof(*param); - if (count < size) { - rc = -EINVAL; - CERROR("%s: invalid data count = %lu, size = %d: rc = %d\n", - obd->obd_name, (unsigned long) count, size, rc); - return rc; + if (unlikely(magic == SEPOL_DOWNCALL_MAGIC_OLD)) + return sepol_seq_write_old(obd, buffer, count); } +#endif - OBD_ALLOC(param, size); - if (param == NULL) + OBD_ALLOC(param, maxparam); + if (!param) return -ENOMEM; - if (copy_from_user(param, buffer, size)) { + if (copy_from_user(param, buffer, min(count, maxparam))) { rc = -EFAULT; CERROR("%s: bad sepol data: rc = %d\n", obd->obd_name, rc); GOTO(out, rc); } - if (param->sdd_sepol_len == 0 || - param->sdd_sepol_len >= sizeof(imp->imp_sec->ps_sepol)) { + if (param->sdd_magic != SEPOL_DOWNCALL_MAGIC) { rc = -EINVAL; - CERROR("%s: invalid sepol data returned: rc = %d\n", - obd->obd_name, rc); + CERROR("%s: sepol downcall bad magic %#08x != %#08x: rc = %d\n", + obd->obd_name, param->sdd_magic, + SEPOL_DOWNCALL_MAGIC, rc); GOTO(out, rc); } - len = param->sdd_sepol_len; /* save sdd_sepol_len */ - OBD_FREE(param, size); - size = offsetof(struct sepol_downcall_data, - sdd_sepol[len]); - - /* alloc again with real size */ - OBD_ALLOC(param, size); - if (param == NULL) - return -ENOMEM; - if (copy_from_user(param, buffer, size)) { - rc = -EFAULT; - CERROR("%s: cannot copy sepol data: rc = %d\n", - obd->obd_name, rc); + len = param->sdd_sepol_len; + if (len == 0 || len >= maxlen) { + rc = -EINVAL; + CERROR("%s: bad sepol len %u >= maxlen %zu: rc = %d\n", + obd->obd_name, len, maxlen, rc); GOTO(out, rc); } + size = offsetof(typeof(*param), sdd_sepol[len]); - spin_lock(&imp->imp_sec->ps_lock); - snprintf(imp->imp_sec->ps_sepol, param->sdd_sepol_len + 1, "%s", - param->sdd_sepol); - imp->imp_sec->ps_sepol_mtime = ktime_set(param->sdd_sepol_mtime, 0); - spin_unlock(&imp->imp_sec->ps_lock); + if (count < size) { + rc = -EINVAL; + CERROR("%s: bad sepol count %zu < total size %zu: rc = %d\n", + obd->obd_name, count, size, rc); + GOTO(out, rc); + } + rc = sptlrpc_sepol_update(imp, ktime_set(param->sdd_sepol_mtime, 0), + param->sdd_sepol, len); out: - if (param != NULL) - OBD_FREE(param, size); + OBD_FREE(param, maxparam); - return rc ? rc : count; + return rc ?: count; } -LDEBUGFS_FOPS_WR_ONLY(srpc, sptlrpc_sepol); + +static int lprocfs_sptlrpc_sepol_seq_show(struct seq_file *seq, void *v) +{ + struct obd_device *obd = seq->private; + struct client_obd *cli = &obd->u.cli; + struct obd_import *imp = cli->cl_import; + struct ptlrpc_sec *imp_sec; + struct sptlrpc_sepol *sepol; + struct timespec64 ts; + int rc = 0; + + imp_sec = sptlrpc_import_sec_ref(imp); + if (!imp_sec) + RETURN(-ENODEV); + + rcu_read_lock(); + sepol = rcu_dereference(imp->imp_sec->ps_sepol); + if (sepol) { + ts = ktime_to_timespec64(sepol->ssp_mtime); + seq_printf(seq, "mtime: %lld\n", (long long int) ts.tv_sec); + seq_printf(seq, "sepol: %.*s\n", + sepol->ssp_sepol_size, sepol->ssp_sepol); + } else { + seq_puts(seq, "uninitialized\n"); + } + rcu_read_unlock(); + sptlrpc_sec_put(imp_sec); + + return rc; +} +LDEBUGFS_SEQ_FOPS_RW_TYPE(srpc, sptlrpc_sepol); int sptlrpc_lprocfs_cliobd_attach(struct obd_device *obd) { @@ -336,11 +390,15 @@ int sptlrpc_lprocfs_cliobd_attach(struct obd_device *obd) } EXPORT_SYMBOL(sptlrpc_lprocfs_cliobd_attach); -LDEBUGFS_SEQ_FOPS_RO(sptlrpc_proc_enc_pool); +LDEBUGFS_SEQ_FOPS_RO(encrypt_page_pools); +LDEBUGFS_SEQ_FOPS_RO(page_pools); static struct ldebugfs_vars sptlrpc_lprocfs_vars[] = { { .name = "encrypt_page_pools", - .fops = &sptlrpc_proc_enc_pool_fops }, + .fops = &encrypt_page_pools_fops }, + { .name = "page_pools", + .fops = &page_pools_fops }, + { NULL } };