From: Shaun Tancheff Date: Fri, 3 Jan 2020 20:10:58 +0000 (-0500) Subject: LU-12634 gss: uid_keyring and session_keyring moved X-Git-Tag: 2.13.52~40 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=97301a491d46cf2cf829185b52b8690287ab7ed6 LU-12634 gss: uid_keyring and session_keyring moved Linux 5.3 removed uid_keyring and session_keyring from user_struct Prefer the lookup_user_key() API when it is available (~5.0) Prefer get_request_key_auth() when it is available (~5.0) kernel-commit: 0f44e4d976f96c6439da0d6717238efa4b91196e kernel-commit: 822ad64d7e46a8e2c8b8a796738d7b657cbb146d Remove LC_HAVE_CRED_TGCRED which is no longer used. Test-Parameters: envdefinitions=SHARED_KEY=true,SANITY_SEC_EXCEPT=30b testlist=sanity,recovery-small,sanity-sec Cray-bug-id: LUS-7689 Signed-off-by: Shaun Tancheff Change-Id: I6d551cd8a9e317b717a43cba9be57f184a281c0a Reviewed-on: https://review.whamcloud.com/35743 Reviewed-by: Sebastien Buisson Reviewed-by: Petros Koutoupis Reviewed-by: James Simmons Tested-by: jenkins Tested-by: Maloo Reviewed-by: Oleg Drokin --- diff --git a/libcfs/autoconf/lustre-libcfs.m4 b/libcfs/autoconf/lustre-libcfs.m4 index 09ea8f6..0c384d41 100644 --- a/libcfs/autoconf/lustre-libcfs.m4 +++ b/libcfs/autoconf/lustre-libcfs.m4 @@ -1052,6 +1052,58 @@ EXTRA_KCFLAGS="$tmp_flags" ]) # LIBCFS_HAVE_IOV_ITER_TYPE # +# LIBCFS_GET_REQUEST_KEY_AUTH +# +# kernel 5.0 commit 822ad64d7e46a8e2c8b8a796738d7b657cbb146d +# keys: Fix dependency loop between construction record and auth key +# +# Added and get_request_key_auth() +# which was propagated to stable +# +AC_DEFUN([LIBCFS_GET_REQUEST_KEY_AUTH], [ +tmp_flags="$EXTRA_KCFLAGS" +EXTRA_KCFLAGS="-Werror" +LB_CHECK_COMPILE([if get_request_key_auth() is available], +get_request_key_auth_exported, [ + #include + #include + #include +],[ + struct key *ring; + const struct key *key = NULL; + struct request_key_auth *rka = get_request_key_auth(key); + + ring = key_get(rka->dest_keyring); +],[ + AC_DEFINE(HAVE_GET_REQUEST_KEY_AUTH, 1, + [get_request_key_auth() is available]) +]) +EXTRA_KCFLAGS="$tmp_flags" +]) # LIBCFS_GET_REQUEST_KEY_AUTH + +# +# LIBCFS_LOOKUP_USER_KEY +# +# kernel 5.3 commit 3cf5d076fb4d48979f382bc9452765bf8b79e740 +# signal: Remove task parameter from force_sig +# +AC_DEFUN([LIBCFS_LOOKUP_USER_KEY], [ +tmp_flags="$EXTRA_KCFLAGS" +EXTRA_KCFLAGS="-Werror" +LB_CHECK_COMPILE([if lookup_user_key() is available], +lookup_user_key_exported, [ + #include + #include +],[ + lookup_user_key(KEY_SPEC_USER_KEYRING, 0, 0); +],[ + AC_DEFINE(HAVE_LOOKUP_USER_KEY, 1, + [lookup_user_key() is available]) +]) +EXTRA_KCFLAGS="$tmp_flags" +]) # LIBCFS_LOOKUP_USER_KEY + +# # LIBCFS_FORCE_SIG_WITH_TASK # # kernel 5.3 commit 3cf5d076fb4d48979f382bc9452765bf8b79e740 @@ -1185,7 +1237,9 @@ LIBCFS_CLEAR_AND_WAKE_UP_BIT LIBCFS_HAVE_IOV_ITER_TYPE # 5.0 LIBCFS_MM_TOTALRAM_PAGES_FUNC +LIBCFS_GET_REQUEST_KEY_AUTH # 5.3 +LIBCFS_LOOKUP_USER_KEY LIBCFS_FORCE_SIG_WITH_TASK LIBCFS_CACHE_DETAIL_WRITERS ]) # LIBCFS_PROG_LINUX diff --git a/lustre/autoconf/lustre-core.m4 b/lustre/autoconf/lustre-core.m4 index 73bac48..c6b5821 100644 --- a/lustre/autoconf/lustre-core.m4 +++ b/lustre/autoconf/lustre-core.m4 @@ -232,23 +232,6 @@ AS_IF([test "x$enable_gss_keyring" != xno], [ ]) # LC_CONFIG_GSS_KEYRING # -# LC_HAVE_CRED_TGCRED -# -# rhel7 struct cred has no member tgcred -# -AC_DEFUN([LC_HAVE_CRED_TGCRED], [ -LB_CHECK_COMPILE([if 'struct cred' has member 'tgcred'], -cred_tgcred, [ - #include -],[ - ((struct cred *)0)->tgcred = NULL; -],[ - AC_DEFINE(HAVE_CRED_TGCRED, 1, - [struct cred has member tgcred]) -]) -]) # LC_HAVE_CRED_TGCRED - -# # LC_KEY_TYPE_INSTANTIATE_2ARGS # # rhel7 key_type->instantiate takes 2 args (struct key, struct key_preparsed_payload) @@ -293,7 +276,6 @@ AC_MSG_RESULT([$enable_gss]) AS_IF([test "x$enable_gss" != xno], [ LC_CONFIG_GSS_KEYRING - LC_HAVE_CRED_TGCRED LC_KEY_TYPE_INSTANTIATE_2ARGS sunrpc_required=$enable_gss LC_CONFIG_SUNRPC diff --git a/lustre/ptlrpc/gss/gss_keyring.c b/lustre/ptlrpc/gss/gss_keyring.c index cd9dc89..204cf7c 100644 --- a/lustre/ptlrpc/gss/gss_keyring.c +++ b/lustre/ptlrpc/gss/gss_keyring.c @@ -60,6 +60,10 @@ #include "gss_internal.h" #include "gss_api.h" +#ifdef HAVE_GET_REQUEST_KEY_AUTH +#include +#endif + static struct ptlrpc_sec_policy gss_policy_keyring; static struct ptlrpc_ctx_ops gss_keyring_ctxops; static struct key_type gss_key_type; @@ -82,45 +86,6 @@ static int sec_install_rctx_kr(struct ptlrpc_sec *sec, * internal helpers * ****************************************/ -#define DUMP_PROCESS_KEYRINGS(tsk) \ -{ \ - CWARN("DUMP PK: %s[%u,%u/%u](<-%s[%u,%u/%u]): " \ - "a %d, t %d, p %d, s %d, u %d, us %d, df %d\n", \ - tsk->comm, tsk->pid, tsk->uid, tsk->fsuid, \ - tsk->parent->comm, tsk->parent->pid, \ - tsk->parent->uid, tsk->parent->fsuid, \ - tsk->request_key_auth ? \ - tsk->request_key_auth->serial : 0, \ - key_cred(tsk)->thread_keyring ? \ - key_cred(tsk)->thread_keyring->serial : 0, \ - key_tgcred(tsk)->process_keyring ? \ - key_tgcred(tsk)->process_keyring->serial : 0, \ - key_tgcred(tsk)->session_keyring ? \ - key_tgcred(tsk)->session_keyring->serial : 0, \ - key_cred(tsk)->user->uid_keyring ? \ - key_cred(tsk)->user->uid_keyring->serial : 0, \ - key_cred(tsk)->user->session_keyring ? \ - key_cred(tsk)->user->session_keyring->serial : 0, \ - key_cred(tsk)->jit_keyring \ - ); \ -} - -#define DUMP_KEY(key) \ -{ \ - CWARN("DUMP KEY: %p(%d) ref %d u%u/g%u desc %s\n", \ - key, key->serial, ll_read_key_usage(key), \ - key->uid, key->gid, \ - key->description ? key->description : "n/a" \ - ); \ -} - -#define key_cred(tsk) ((tsk)->cred) -#ifdef HAVE_CRED_TGCRED -#define key_tgcred(tsk) ((tsk)->cred->tgcred) -#else -#define key_tgcred(tsk) key_cred(tsk) -#endif - static inline void keyring_upcall_lock(struct gss_sec_keyring *gsec_kr) { #ifdef HAVE_KEYRING_UPCALL_SERIALIZED @@ -651,41 +616,103 @@ static inline int user_is_root(struct ptlrpc_sec *sec, struct vfs_cred *vcred) } /* + * kernel 5.3: commit 0f44e4d976f96c6439da0d6717238efa4b91196e + * keys: Move the user and user-session keyrings to the user_namespace + * + * When lookup_user_key is available use the kernel API rather than directly + * accessing the uid_keyring and session_keyring via the current process + * credentials. + */ +#ifdef HAVE_LOOKUP_USER_KEY + +/* from Linux security/keys/internal.h: */ +#ifndef KEY_LOOKUP_FOR_UNLINK +#define KEY_LOOKUP_FOR_UNLINK 0x04 +#endif + +static struct key *_user_key(key_serial_t id) +{ + key_ref_t ref; + + might_sleep(); + ref = lookup_user_key(id, KEY_LOOKUP_FOR_UNLINK, 0); + if (IS_ERR(ref)) + return NULL; + return key_ref_to_ptr(ref); +} + +static inline struct key *get_user_session_keyring(const struct cred *cred) +{ + return _user_key(KEY_SPEC_USER_SESSION_KEYRING); +} + +static inline struct key *get_user_keyring(const struct cred *cred) +{ + return _user_key(KEY_SPEC_USER_KEYRING); +} +#else +static inline struct key *get_user_session_keyring(const struct cred *cred) +{ + return key_get(cred->user->session_keyring); +} + +static inline struct key *get_user_keyring(const struct cred *cred) +{ + return key_get(cred->user->uid_keyring); +} +#endif + +/* * unlink request key from it's ring, which is linked during request_key(). * sadly, we have to 'guess' which keyring it's linked to. * - * FIXME this code is fragile, depend on how request_key_link() is implemented. + * FIXME this code is fragile, it depends on how request_key() is implemented. */ static void request_key_unlink(struct key *key) { - struct task_struct *tsk = current; - struct key *ring; + const struct cred *cred = current_cred(); + struct key *ring = NULL; - switch (key_cred(tsk)->jit_keyring) { + switch (cred->jit_keyring) { case KEY_REQKEY_DEFL_DEFAULT: + case KEY_REQKEY_DEFL_REQUESTOR_KEYRING: +#ifdef HAVE_GET_REQUEST_KEY_AUTH + if (cred->request_key_auth) { + struct request_key_auth *rka; + struct key *authkey = cred->request_key_auth; + + down_read(&authkey->sem); + rka = get_request_key_auth(authkey); + if (!test_bit(KEY_FLAG_REVOKED, &authkey->flags)) + ring = key_get(rka->dest_keyring); + up_read(&authkey->sem); + if (ring) + break; + } +#endif + /* fall through */ case KEY_REQKEY_DEFL_THREAD_KEYRING: - ring = key_get(key_cred(tsk)->thread_keyring); + ring = key_get(cred->thread_keyring); if (ring) break; /* fallthrough */ case KEY_REQKEY_DEFL_PROCESS_KEYRING: - ring = key_get(key_tgcred(tsk)->process_keyring); + ring = key_get(cred->process_keyring); if (ring) break; /* fallthrough */ case KEY_REQKEY_DEFL_SESSION_KEYRING: rcu_read_lock(); - ring = key_get(rcu_dereference(key_tgcred(tsk) - ->session_keyring)); + ring = key_get(rcu_dereference(cred->session_keyring)); rcu_read_unlock(); if (ring) break; /* fallthrough */ case KEY_REQKEY_DEFL_USER_SESSION_KEYRING: - ring = key_get(key_cred(tsk)->user->session_keyring); + ring = get_user_session_keyring(cred); break; case KEY_REQKEY_DEFL_USER_KEYRING: - ring = key_get(key_cred(tsk)->user->uid_keyring); + ring = get_user_keyring(cred); break; case KEY_REQKEY_DEFL_GROUP_KEYRING: default: @@ -1310,15 +1337,15 @@ int gss_kt_instantiate(struct key *key, const void *data, size_t datalen) * the session keyring is created upon upcall, and don't change all * the way until upcall finished, so rcu lock is not needed here. */ - LASSERT(key_tgcred(current)->session_keyring); + LASSERT(current_cred()->session_keyring); lockdep_off(); - rc = key_link(key_tgcred(current)->session_keyring, key); + rc = key_link(current_cred()->session_keyring, key); lockdep_on(); if (unlikely(rc)) { CERROR("failed to link key %08x to keyring %08x: %d\n", key->serial, - key_tgcred(current)->session_keyring->serial, rc); + current_cred()->session_keyring->serial, rc); RETURN(rc); }