[PATCH 2/3] cifs.upcall: namespace-aware key authority
Enzo Matsumiya <[email protected]>
| Newsgroups | org.kernel.vger.linux-cifs |
|---|---|
| Message-ID | <[email protected]> |
spnego key is allocated before switching namespaces (i.e. as root/host credentials), but instantiation is done only later. If we have successfully switched user namespaces, key instantiation returns EPERM because credentials have changed. Call keyctl_assume_authority() after switching NS/UID/GID so key is instantiated with correct creds. Signed-off-by: Enzo Matsumiya <[email protected]> --- cifs.upcall.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/cifs.upcall.c b/cifs.upcall.c index 8a207544cf48..3f56c69cae28 100644 --- a/cifs.upcall.c +++ b/cifs.upcall.c @@ -1539,6 +1539,7 @@ int main(const int argc, char *const argv[]) krb5_ccache ccache = NULL; unsigned expire_time = DNS_RESOLVER_DEFAULT_TIMEOUT; const char *key_descr = NULL; + bool same_ns = true; hostbuf[0] = '\0'; @@ -1688,6 +1689,7 @@ int main(const int argc, char *const argv[]) if (arg->upcall_target == UPTARGET_APP || arg->upcall_target == UPTARGET_UNSPECIFIED) { syslog(LOG_INFO, "upcall_target=app, switching namespaces to application thread"); arg->upcall_target = UPTARGET_APP; + same_ns = in_same_user_ns(getpid(), arg->pid); rc = switch_to_process_ns(arg->pid); if (rc == -1) { syslog(LOG_ERR, "unable to switch to process namespace: %s", strerror(errno)); @@ -1756,6 +1758,27 @@ int main(const int argc, char *const argv[]) if (rc) goto out; + /* + * Keyring keys' credentials are per user NS. If we switched user namespaces, we need to + * re-acquire authority (with correct UID/GID) over it so we're able to instantiate it + * later (in setup_key()). + */ + if (!same_ns) { + errno = 0; + rc = keyctl_assume_authority(key); + + /* + * EINPROGRESS and ENOENT are non-fatal in most cases. + * keyctl_instantiate() (in setup_key()) will fail if something was really + * unexpected. + */ + if (rc < 0 && errno != EINPROGRESS && errno != ENOENT) { + syslog(LOG_ERR, "keyctl_assume_authority: %s", strerror(errno)); + rc = 1; + goto out; + } + } + rc = krb5_init_context(&context); if (rc) { syslog(LOG_ERR, "unable to init krb5 context: %ld", rc); -- 2.54.0