Whamcloud - gitweb
LU-18145 gss: fix key unlink for regular user 53/56053/6
authorSebastien Buisson <sbuisson@ddn.com>
Wed, 14 Aug 2024 16:08:17 +0000 (18:08 +0200)
committerOleg Drokin <green@whamcloud.com>
Fri, 23 Aug 2024 22:09:19 +0000 (22:09 +0000)
In case a key is unlinked for a regular user, it can be necessary to
switch credentials to find a valid keyring for that user, which
implies changing the user namespace as well. This needs a reference
drop on the original namespace, as a ref was taken by prepare_creds(),
and also to take a reference on the newly set namespace, as a ref will
be dropped when put_cred() is finally called.

Because of the user switch, calling get_user_keyring() also adds one
more ref on the user keyring, for kernel implementation based on user
keyring pinned from the user_struct struct. This extra ref needs to be
dropped, but just for this specific case.

Test-Parameters: trivial
Test-Parameters: testgroup=review-dne-selinux-ssk-part-1
Test-Parameters: testgroup=review-dne-selinux-ssk-part-2
Test-Parameters: kerberos=true testlist=sanity-krb5
Fixes: bc740feeaa ("LU-17714 gss: support revoked session keyring")
Signed-off-by: Sebastien Buisson <sbuisson@ddn.com>
Change-Id: I4d8fb354394a9f97dedf8aca84e4e3381a98fc60
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/56053
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
Reviewed-by: Bruno Faccini <bfaccini@nvidia.com>
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
lustre/ptlrpc/gss/gss_keyring.c

index c34db45..0b705ea 100644 (file)
@@ -759,9 +759,7 @@ static int construct_get_dest_keyring(struct key **_dest_keyring)
                        break;
                fallthrough;
        case KEY_REQKEY_DEFL_SESSION_KEYRING:
-               rcu_read_lock();
-               dest_keyring = key_get(rcu_dereference(cred->session_keyring));
-               rcu_read_unlock();
+               dest_keyring = get_session_keyring(cred);
                if (dest_keyring) {
                        if (!test_bit(KEY_FLAG_REVOKED, &dest_keyring->flags))
                                break;
@@ -808,7 +806,10 @@ static void request_key_unlink(struct key *key, bool fullsearch)
 
                new_cred->uid = key->uid;
                new_cred->user->uid = key->uid;
-               new_cred->user_ns = &init_user_ns;
+               if (new_cred->user_ns != &init_user_ns) {
+                       put_user_ns(new_cred->user_ns);
+                       new_cred->user_ns = get_user_ns(&init_user_ns);
+               }
 #ifdef HAVE_USER_UID_KEYRING
                root_uid_keyring = current_cred()->user->uid_keyring;
                new_cred->user->uid_keyring = NULL;
@@ -851,7 +852,8 @@ search:
                 * for kernel implementation based on user keyring pinned from
                 * the user_struct struct.
                 */
-               key_put(ring);
+               if (key_uid && !fullsearch)
+                       key_put(ring);
                if (root_uid_keyring)
                        current_cred()->user->uid_keyring = root_uid_keyring;
 #endif