From f6687bafcb296aa7c152774de65bc865c774c464 Mon Sep 17 00:00:00 2001 From: Sebastien Buisson Date: Tue, 5 Dec 2023 14:14:58 +0100 Subject: [PATCH] LU-17317 sec: add srpc_serverctx proc file GSS srpc contexts for client connections can already be dumped via proc file .*.srpc_contexts. This patch adds a new proc file to dump server side GSS srpc contexts, e.g.: mgs.MGS.gss.srpc_serverctx mdt.testfs-MDT0000.gss.srpc_serverctx obdfilter.testfs-OST0000.gss.srpc_serverctx The GSS context information is dumped as YAML, with one line per context, like this: - 0000000013221bdf: { peer_nid: 192.168.56.206@tcp, uid: 0, ctxref: 1, expire: 1707934985, delta: 3401, flags: [uptodate, cached], seq: 0, win: 2048, key: 00000000, keyref: 0, hdl: "0x5ae1a771fd57043:0x65a64972fda4e200", mech: "krb5 (aes256-cts-hmac-sha1-96)" } Because of this new syntax, sanity-sec test_28 needs to be fixed. Test-Parameters: trivial Test-Parameters: kerberos=true testlist=sanity-krb5 Test-Parameters: testgroup=review-dne-selinux-ssk-part-2 Signed-off-by: Sebastien Buisson Change-Id: I37da9ffe6dd5884006b36271185a4d7155ead65b Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/53376 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Aurelien Degremont Reviewed-by: Andreas Dilger Reviewed-by: Oleg Drokin --- lustre/include/lustre_sec.h | 1 + lustre/include/obd.h | 1 + lustre/mdt/mdt_lproc.c | 14 ++++++++++++ lustre/mgs/lproc_mgs.c | 14 ++++++++++++ lustre/obdclass/lprocfs_status.c | 3 +++ lustre/ofd/lproc_ofd.c | 14 ++++++++++++ lustre/ptlrpc/gss/gss_keyring.c | 45 ++++++++++++++++++++++---------------- lustre/ptlrpc/gss/gss_svc_upcall.c | 8 +++---- lustre/ptlrpc/gss/sec_gss.c | 16 +++++++------- lustre/ptlrpc/sec.c | 34 ++++++++++++++++++++++++++++ lustre/ptlrpc/service.c | 2 ++ lustre/tests/sanity-sec.sh | 8 +++---- 12 files changed, 125 insertions(+), 35 deletions(-) diff --git a/lustre/include/lustre_sec.h b/lustre/include/lustre_sec.h index 77f970e..d49c4c3 100644 --- a/lustre/include/lustre_sec.h +++ b/lustre/include/lustre_sec.h @@ -1099,6 +1099,7 @@ int sptlrpc_import_sec_adapt(struct obd_import *imp, struct sptlrpc_flavor *flvr); struct ptlrpc_sec *sptlrpc_import_sec_ref(struct obd_import *imp); void sptlrpc_import_sec_put(struct obd_import *imp); +int lprocfs_srpc_serverctx_seq_show(struct seq_file *m, void *data); int sptlrpc_import_check_ctx(struct obd_import *imp); void sptlrpc_import_flush_root_ctx(struct obd_import *imp); diff --git a/lustre/include/obd.h b/lustre/include/obd.h index 4438d4e..6ed6020 100644 --- a/lustre/include/obd.h +++ b/lustre/include/obd.h @@ -722,6 +722,7 @@ struct obd_device { struct lprocfs_stats *obd_md_stats; struct dentry *obd_debugfs_entry; + struct dentry *obd_debugfs_gss_dir; struct proc_dir_entry *obd_proc_entry; struct proc_dir_entry *obd_proc_exports_entry; struct dentry *obd_svc_debugfs_entry; diff --git a/lustre/mdt/mdt_lproc.c b/lustre/mdt/mdt_lproc.c index 48b6ae8..31d5f47 100644 --- a/lustre/mdt/mdt_lproc.c +++ b/lustre/mdt/mdt_lproc.c @@ -1389,6 +1389,14 @@ static struct ldebugfs_vars ldebugfs_mdt_obd_vars[] = { { NULL } }; +LDEBUGFS_SEQ_FOPS_RO_TYPE(mdt, srpc_serverctx); + +static struct ldebugfs_vars ldebugfs_mdt_gss_vars[] = { + { .name = "srpc_serverctx", + .fops = &mdt_srpc_serverctx_fops }, + { NULL } +}; + static int lprocfs_mdt_print_open_files(struct obd_export *exp, void *v) { @@ -1534,6 +1542,12 @@ int mdt_tunables_init(struct mdt_device *mdt, const char *name) return rc; } + obd->obd_debugfs_gss_dir = debugfs_create_dir("gss", + obd->obd_debugfs_entry); + if (obd->obd_debugfs_gss_dir) + ldebugfs_add_vars(obd->obd_debugfs_gss_dir, + ldebugfs_mdt_gss_vars, obd); + obd->obd_proc_exports_entry = proc_mkdir("exports", obd->obd_proc_entry); if (obd->obd_proc_exports_entry) diff --git a/lustre/mgs/lproc_mgs.c b/lustre/mgs/lproc_mgs.c index 3d58463..082fb03 100644 --- a/lustre/mgs/lproc_mgs.c +++ b/lustre/mgs/lproc_mgs.c @@ -218,6 +218,14 @@ static struct lprocfs_vars lprocfs_mgs_obd_vars[] = { LUSTRE_RO_ATTR(num_exports); LUSTRE_RO_ATTR(eviction_count); +LDEBUGFS_SEQ_FOPS_RO_TYPE(ofd, srpc_serverctx); + +static struct ldebugfs_vars ldebugfs_ofd_gss_vars[] = { + { .name = "srpc_serverctx", + .fops = &ofd_srpc_serverctx_fops }, + { NULL } +}; + static ssize_t fstype_show(struct kobject *kobj, struct attribute *attr, char *buf) { @@ -296,6 +304,12 @@ int lproc_mgs_setup(struct mgs_device *mgs, const char *osd_name) GOTO(out, rc); } + obd->obd_debugfs_gss_dir = debugfs_create_dir("gss", + obd->obd_debugfs_entry); + if (obd->obd_debugfs_gss_dir) + ldebugfs_add_vars(obd->obd_debugfs_gss_dir, + ldebugfs_ofd_gss_vars, obd); + obd->obd_proc_exports_entry = lprocfs_register("exports", obd->obd_proc_entry, NULL, NULL); diff --git a/lustre/obdclass/lprocfs_status.c b/lustre/obdclass/lprocfs_status.c index 7ffbc42..3aa4b9e 100644 --- a/lustre/obdclass/lprocfs_status.c +++ b/lustre/obdclass/lprocfs_status.c @@ -1142,6 +1142,9 @@ int lprocfs_obd_cleanup(struct obd_device *obd) if (!obd) return -EINVAL; + debugfs_remove_recursive(obd->obd_debugfs_gss_dir); + obd->obd_debugfs_gss_dir = NULL; + if (obd->obd_proc_exports_entry) { /* Should be no exports left */ lprocfs_remove(&obd->obd_proc_exports_entry); diff --git a/lustre/ofd/lproc_ofd.c b/lustre/ofd/lproc_ofd.c index f03d8d1..b0c4210 100644 --- a/lustre/ofd/lproc_ofd.c +++ b/lustre/ofd/lproc_ofd.c @@ -949,6 +949,14 @@ struct ldebugfs_vars ldebugfs_ofd_obd_vars[] = { { NULL } }; +LDEBUGFS_SEQ_FOPS_RO_TYPE(ofd, srpc_serverctx); + +static struct ldebugfs_vars ldebugfs_ofd_gss_vars[] = { + { .name = "srpc_serverctx", + .fops = &ofd_srpc_serverctx_fops }, + { NULL } +}; + /** * Initialize OFD statistics counters * @@ -1081,6 +1089,12 @@ int ofd_tunables_init(struct ofd_device *ofd) GOTO(tgt_cleanup, rc); } + obd->obd_debugfs_gss_dir = debugfs_create_dir("gss", + obd->obd_debugfs_entry); + if (obd->obd_debugfs_gss_dir) + ldebugfs_add_vars(obd->obd_debugfs_gss_dir, + ldebugfs_ofd_gss_vars, obd); + entry = lprocfs_register("exports", obd->obd_proc_entry, NULL, NULL); if (IS_ERR(entry)) { rc = PTR_ERR(entry); diff --git a/lustre/ptlrpc/gss/gss_keyring.c b/lustre/ptlrpc/gss/gss_keyring.c index a4b5948..ad099d8 100644 --- a/lustre/ptlrpc/gss/gss_keyring.c +++ b/lustre/ptlrpc/gss/gss_keyring.c @@ -1199,38 +1199,45 @@ int gss_sec_display_kr(struct ptlrpc_sec *sec, struct seq_file *seq) struct hlist_node *next; struct ptlrpc_cli_ctx *ctx; struct gss_cli_ctx *gctx; + struct ptlrpc_connection *conn; time64_t now = ktime_get_real_seconds(); ENTRY; spin_lock(&sec->ps_lock); hlist_for_each_entry_safe(ctx, next, &gsec_kr->gsk_clist, cc_cache) { - struct key *key; - char flags_str[40]; - char mech[40]; + struct key *key; + char flags_str[40]; + char mech[40]; - gctx = ctx2gctx(ctx); - key = ctx2gctx_keyring(ctx)->gck_key; + gctx = ctx2gctx(ctx); + key = ctx2gctx_keyring(ctx)->gck_key; + if (sec_is_reverse(sec) && + ctx->cc_sec && ctx->cc_sec->ps_import && + ctx->cc_sec->ps_import->imp_connection) + conn = ctx->cc_sec->ps_import->imp_connection; + else + conn = NULL; - gss_cli_ctx_flags2str(ctx->cc_flags, - flags_str, sizeof(flags_str)); + gss_cli_ctx_flags2str(ctx->cc_flags, + flags_str, sizeof(flags_str)); - if (gctx->gc_mechctx) - lgss_display(gctx->gc_mechctx, mech, sizeof(mech)); - else - snprintf(mech, sizeof(mech), "N/A"); - mech[sizeof(mech) - 1] = '\0'; + if (gctx->gc_mechctx) + lgss_display(gctx->gc_mechctx, mech, sizeof(mech)); + else + snprintf(mech, sizeof(mech), "N/A"); + mech[sizeof(mech) - 1] = '\0'; seq_printf(seq, - "%p: uid %u, ref %d, expire %lld(%+lld), fl %s, seq %d, win %u, key %08x(ref %d), hdl %#llx:%#llx, mech: %s\n", - ctx, ctx->cc_vcred.vc_uid, - atomic_read(&ctx->cc_refcount), + "- %p: { %s%s%suid: %u, ctxref: %d, expire: %lld, delta: %lld, flags: [%s], seq: %d, win: %u, key: %08x, keyref: %d, hdl: \"%#llx:%#llx\", mech: \"%s\" }\n", + ctx, conn ? "peer_nid: " : "", + conn ? libcfs_nidstr(&conn->c_peer.nid) : "", + conn ? ", " : "", + ctx->cc_vcred.vc_uid, atomic_read(&ctx->cc_refcount), ctx->cc_expire, ctx->cc_expire ? ctx->cc_expire - now : 0, - flags_str, - atomic_read(&gctx->gc_seq), - gctx->gc_win, - key ? key->serial : 0, + flags_str, atomic_read(&gctx->gc_seq), + gctx->gc_win, key ? key->serial : 0, key ? ll_read_key_usage(key) : 0, gss_handle_to_u64(&gctx->gc_handle), gss_handle_to_u64(&gctx->gc_svc_handle), diff --git a/lustre/ptlrpc/gss/gss_svc_upcall.c b/lustre/ptlrpc/gss/gss_svc_upcall.c index 441afa3..d9072e9 100644 --- a/lustre/ptlrpc/gss/gss_svc_upcall.c +++ b/lustre/ptlrpc/gss/gss_svc_upcall.c @@ -142,8 +142,8 @@ static __always_inline __u64 gss_hash_64(__u64 val, unsigned int bits) static inline unsigned long hash_mem_64(char *buf, int length, int bits) { - unsigned long hash = 0; - unsigned long l = 0; + __u64 hash = 0; + __u64 l = 0; int len = 0; unsigned char c; @@ -157,8 +157,8 @@ static inline unsigned long hash_mem_64(char *buf, int length, int bits) l = (l << 8) | c; len++; - if ((len & (BITS_PER_LONG/8-1)) == 0) - hash = gss_hash_64(hash^l, BITS_PER_LONG); + if ((len & (BITS_PER_LONG / 8 - 1)) == 0) + hash = gss_hash_64(hash ^ l, BITS_PER_LONG); } while (len); return hash >> (BITS_PER_LONG - bits); diff --git a/lustre/ptlrpc/gss/sec_gss.c b/lustre/ptlrpc/gss/sec_gss.c index fc2417b..5c88883 100644 --- a/lustre/ptlrpc/gss/sec_gss.c +++ b/lustre/ptlrpc/gss/sec_gss.c @@ -588,19 +588,19 @@ void gss_cli_ctx_flags2str(unsigned long flags, char *buf, int bufsize) buf[0] = '\0'; if (flags & PTLRPC_CTX_NEW) - strlcat(buf, "new,", bufsize); + strlcat(buf, "new, ", bufsize); if (flags & PTLRPC_CTX_UPTODATE) - strlcat(buf, "uptodate,", bufsize); + strlcat(buf, "uptodate, ", bufsize); if (flags & PTLRPC_CTX_DEAD) - strlcat(buf, "dead,", bufsize); + strlcat(buf, "dead, ", bufsize); if (flags & PTLRPC_CTX_ERROR) - strlcat(buf, "error,", bufsize); + strlcat(buf, "error, ", bufsize); if (flags & PTLRPC_CTX_CACHED) - strlcat(buf, "cached,", bufsize); + strlcat(buf, "cached, ", bufsize); if (flags & PTLRPC_CTX_ETERNAL) - strlcat(buf, "eternal,", bufsize); - if (buf[0] == '\0') - strlcat(buf, "-,", bufsize); + strlcat(buf, "eternal, ", bufsize); + if (buf[strlen(buf) - 2] == ',') + buf[strlen(buf) - 2] = '\0'; } int gss_cli_ctx_sign(struct ptlrpc_cli_ctx *ctx, struct ptlrpc_request *req) diff --git a/lustre/ptlrpc/sec.c b/lustre/ptlrpc/sec.c index 725a71f..f3ad28a 100644 --- a/lustre/ptlrpc/sec.c +++ b/lustre/ptlrpc/sec.c @@ -1403,6 +1403,40 @@ struct ptlrpc_sec * sptlrpc_sec_create(struct obd_import *imp, RETURN(sec); } +static int print_srpc_serverctx_seq(struct obd_export *exp, void *cb_data) +{ + struct seq_file *m = cb_data; + struct obd_import *imp = exp->exp_imp_reverse; + struct ptlrpc_sec *sec = NULL; + + if (imp) + sec = sptlrpc_import_sec_ref(imp); + if (sec == NULL) + goto out; + + if (sec->ps_policy->sp_cops->display) + sec->ps_policy->sp_cops->display(sec, m); + + sptlrpc_sec_put(sec); +out: + return 0; +} + +int lprocfs_srpc_serverctx_seq_show(struct seq_file *m, void *data) +{ + struct obd_device *obd = m->private; + struct obd_export *exp, *n; + + spin_lock(&obd->obd_dev_lock); + list_for_each_entry_safe(exp, n, &obd->obd_exports, exp_obd_chain) { + print_srpc_serverctx_seq(exp, m); + } + spin_unlock(&obd->obd_dev_lock); + + return 0; +} +EXPORT_SYMBOL(lprocfs_srpc_serverctx_seq_show); + struct ptlrpc_sec *sptlrpc_import_sec_ref(struct obd_import *imp) { struct ptlrpc_sec *sec; diff --git a/lustre/ptlrpc/service.c b/lustre/ptlrpc/service.c index 9276b8d..c1bdf7b 100644 --- a/lustre/ptlrpc/service.c +++ b/lustre/ptlrpc/service.c @@ -2093,6 +2093,7 @@ static int ptlrpc_server_handle_req_in(struct ptlrpc_service_part *svcpt, spin_unlock(&svcpt->scp_lock); /* go through security check/transform */ + CDEBUG(D_RPCTRACE, "unwrap req x%llu\n", req->rq_xid); rc = sptlrpc_svc_unwrap_request(req); switch (rc) { case SECSVC_OK: @@ -2238,6 +2239,7 @@ static int ptlrpc_server_handle_req_in(struct ptlrpc_service_part *svcpt, RETURN(1); err_req: + CDEBUG(D_RPCTRACE, "finish req x%llu\n", req->rq_xid); ptlrpc_server_finish_request(svcpt, req); RETURN(1); diff --git a/lustre/tests/sanity-sec.sh b/lustre/tests/sanity-sec.sh index f8d1a1f..0b7fc17 100755 --- a/lustre/tests/sanity-sec.sh +++ b/lustre/tests/sanity-sec.sh @@ -2222,16 +2222,16 @@ test_28() { error "read before rotation failed" fi # store top key identity to ensure rotation has occurred - SK_IDENTITY_OLD=$(lctl get_param *.*.*srpc* 2>/dev/null | grep "expire"| - head -1 | awk '{print $15}' | cut -c1-8) + SK_IDENTITY_OLD=$($LCTL get_param -n *.*.*srpc_contexts 2>/dev/null | + head -n 1 | awk 'BEGIN{RS=", "} $1=="expire:"{print $2}') do_facet $SINGLEMDS lfs flushctx || error "could not run flushctx on $SINGLEMDS" sleep 5 lfs flushctx || error "could not run flushctx on client" sleep 5 # verify new key is in place - SK_IDENTITY_NEW=$(lctl get_param *.*.*srpc* 2>/dev/null | grep "expire"| - head -1 | awk '{print $15}' | cut -c1-8) + SK_IDENTITY_NEW=$($LCTL get_param -n *.*.*srpc_contexts 2>/dev/null | + head -n 1 | awk 'BEGIN{RS=", "} $1=="expire:"{print $2}') if [ $SK_IDENTITY_OLD == $SK_IDENTITY_NEW ]; then error "key did not rotate correctly" fi -- 1.8.3.1