From: Greg Kroah-Hartman Date: Tue, 20 May 2025 07:33:35 +0000 (+0200) Subject: 6.12-stable patches X-Git-Tag: v5.15.184~39 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7294cf6ff42482531f62f9b2a74d9c7ee00bbb59;p=thirdparty%2Fkernel%2Fstable-queue.git 6.12-stable patches added patches: cifs-new-mount-option-for-cifs.upcall-namespace-resolution.patch --- diff --git a/queue-6.12/cifs-new-mount-option-for-cifs.upcall-namespace-resolution.patch b/queue-6.12/cifs-new-mount-option-for-cifs.upcall-namespace-resolution.patch new file mode 100644 index 0000000000..d26e654f52 --- /dev/null +++ b/queue-6.12/cifs-new-mount-option-for-cifs.upcall-namespace-resolution.patch @@ -0,0 +1,296 @@ +From db363b0a1d9e6b9dc556296f1b1007aeb496a8cf Mon Sep 17 00:00:00 2001 +From: Ritvik Budhiraja +Date: Mon, 11 Nov 2024 11:43:51 +0000 +Subject: CIFS: New mount option for cifs.upcall namespace resolution + +From: Ritvik Budhiraja + +commit db363b0a1d9e6b9dc556296f1b1007aeb496a8cf upstream. + +In the current implementation, the SMB filesystem on a mount point can +trigger upcalls from the kernel to the userspace to enable certain +functionalities like spnego, dns_resolution, amongst others. These upcalls +usually either happen in the context of the mount or in the context of an +application/user. The upcall handler for cifs, cifs.upcall already has +existing code which switches the namespaces to the caller's namespace +before handling the upcall. This behaviour is expected for scenarios like +multiuser mounts, but might not cover all single user scenario with +services such as Kubernetes, where the mount can happen from different +locations such as on the host, from an app container, or a driver pod +which does the mount on behalf of a different pod. + +This patch introduces a new mount option called upcall_target, to +customise the upcall behaviour. upcall_target can take 'mount' and 'app' +as possible values. This aids use cases like Kubernetes where the mount +happens on behalf of the application in another container altogether. +Having this new mount option allows the mount command to specify where the +upcall should happen: 'mount' for resolving the upcall to the host +namespace, and 'app' for resolving the upcall to the ns of the calling +thread. This will enable both the scenarios where the Kerberos credentials +can be found on the application namespace or the host namespace to which +just the mount operation is "delegated". + +Reviewed-by: Shyam Prasad +Reviewed-by: Bharath S M +Reviewed-by: Ronnie Sahlberg +Signed-off-by: Ritvik Budhiraja +Signed-off-by: Steve French +Cc: Salvatore Bonaccorso +Signed-off-by: Greg Kroah-Hartman +--- + fs/smb/client/cifs_spnego.c | 16 ++++++++++++++++ + fs/smb/client/cifsfs.c | 25 +++++++++++++++++++++++++ + fs/smb/client/cifsglob.h | 7 +++++++ + fs/smb/client/connect.c | 20 ++++++++++++++++++++ + fs/smb/client/fs_context.c | 39 +++++++++++++++++++++++++++++++++++++++ + fs/smb/client/fs_context.h | 10 ++++++++++ + 6 files changed, 117 insertions(+) + +--- a/fs/smb/client/cifs_spnego.c ++++ b/fs/smb/client/cifs_spnego.c +@@ -82,6 +82,9 @@ struct key_type cifs_spnego_key_type = { + /* strlen of ";pid=0x" */ + #define PID_KEY_LEN 7 + ++/* strlen of ";upcall_target=" */ ++#define UPCALL_TARGET_KEY_LEN 15 ++ + /* get a key struct with a SPNEGO security blob, suitable for session setup */ + struct key * + cifs_get_spnego_key(struct cifs_ses *sesInfo, +@@ -108,6 +111,11 @@ cifs_get_spnego_key(struct cifs_ses *ses + if (sesInfo->user_name) + desc_len += USER_KEY_LEN + strlen(sesInfo->user_name); + ++ if (sesInfo->upcall_target == UPTARGET_MOUNT) ++ desc_len += UPCALL_TARGET_KEY_LEN + 5; // strlen("mount") ++ else ++ desc_len += UPCALL_TARGET_KEY_LEN + 3; // strlen("app") ++ + spnego_key = ERR_PTR(-ENOMEM); + description = kzalloc(desc_len, GFP_KERNEL); + if (description == NULL) +@@ -158,6 +166,14 @@ cifs_get_spnego_key(struct cifs_ses *ses + dp = description + strlen(description); + sprintf(dp, ";pid=0x%x", current->pid); + ++ if (sesInfo->upcall_target == UPTARGET_MOUNT) { ++ dp = description + strlen(description); ++ sprintf(dp, ";upcall_target=mount"); ++ } else { ++ dp = description + strlen(description); ++ sprintf(dp, ";upcall_target=app"); ++ } ++ + cifs_dbg(FYI, "key description = %s\n", description); + saved_cred = override_creds(spnego_cred); + spnego_key = request_key(&cifs_spnego_key_type, description, ""); +--- a/fs/smb/client/cifsfs.c ++++ b/fs/smb/client/cifsfs.c +@@ -547,6 +547,30 @@ static int cifs_show_devname(struct seq_ + return 0; + } + ++static void ++cifs_show_upcall_target(struct seq_file *s, struct cifs_sb_info *cifs_sb) ++{ ++ if (cifs_sb->ctx->upcall_target == UPTARGET_UNSPECIFIED) { ++ seq_puts(s, ",upcall_target=app"); ++ return; ++ } ++ ++ seq_puts(s, ",upcall_target="); ++ ++ switch (cifs_sb->ctx->upcall_target) { ++ case UPTARGET_APP: ++ seq_puts(s, "app"); ++ break; ++ case UPTARGET_MOUNT: ++ seq_puts(s, "mount"); ++ break; ++ default: ++ /* shouldn't ever happen */ ++ seq_puts(s, "unknown"); ++ break; ++ } ++} ++ + /* + * cifs_show_options() is for displaying mount options in /proc/mounts. + * Not all settable options are displayed but most of the important +@@ -563,6 +587,7 @@ cifs_show_options(struct seq_file *s, st + seq_show_option(s, "vers", tcon->ses->server->vals->version_string); + cifs_show_security(s, tcon->ses); + cifs_show_cache_flavor(s, cifs_sb); ++ cifs_show_upcall_target(s, cifs_sb); + + if (tcon->no_lease) + seq_puts(s, ",nolease"); +--- a/fs/smb/client/cifsglob.h ++++ b/fs/smb/client/cifsglob.h +@@ -154,6 +154,12 @@ enum securityEnum { + IAKerb, /* Kerberos proxy */ + }; + ++enum upcall_target_enum { ++ UPTARGET_UNSPECIFIED, /* not specified, defaults to app */ ++ UPTARGET_MOUNT, /* upcall to the mount namespace */ ++ UPTARGET_APP, /* upcall to the application namespace which did the mount */ ++}; ++ + enum cifs_reparse_type { + CIFS_REPARSE_TYPE_NFS, + CIFS_REPARSE_TYPE_WSL, +@@ -1085,6 +1091,7 @@ struct cifs_ses { + struct session_key auth_key; + struct ntlmssp_auth *ntlmssp; /* ciphertext, flags, server challenge */ + enum securityEnum sectype; /* what security flavor was specified? */ ++ enum upcall_target_enum upcall_target; /* what upcall target was specified? */ + bool sign; /* is signing required? */ + bool domainAuto:1; + bool expired_pwd; /* track if access denied or expired pwd so can know if need to update */ +--- a/fs/smb/client/connect.c ++++ b/fs/smb/client/connect.c +@@ -2381,6 +2381,26 @@ retry_old_session: + + ses->sectype = ctx->sectype; + ses->sign = ctx->sign; ++ ++ /* ++ *Explicitly marking upcall_target mount option for easier handling ++ * by cifs_spnego.c and eventually cifs.upcall.c ++ */ ++ ++ switch (ctx->upcall_target) { ++ case UPTARGET_UNSPECIFIED: /* default to app */ ++ case UPTARGET_APP: ++ ses->upcall_target = UPTARGET_APP; ++ break; ++ case UPTARGET_MOUNT: ++ ses->upcall_target = UPTARGET_MOUNT; ++ break; ++ default: ++ // should never happen ++ ses->upcall_target = UPTARGET_APP; ++ break; ++ } ++ + ses->local_nls = load_nls(ctx->local_nls->charset); + + /* add server as first channel */ +--- a/fs/smb/client/fs_context.c ++++ b/fs/smb/client/fs_context.c +@@ -67,6 +67,12 @@ static const match_table_t cifs_secflavo + { Opt_sec_err, NULL } + }; + ++static const match_table_t cifs_upcall_target = { ++ { Opt_upcall_target_mount, "mount" }, ++ { Opt_upcall_target_application, "app" }, ++ { Opt_upcall_target_err, NULL } ++}; ++ + const struct fs_parameter_spec smb3_fs_parameters[] = { + /* Mount options that take no arguments */ + fsparam_flag_no("user_xattr", Opt_user_xattr), +@@ -179,6 +185,7 @@ const struct fs_parameter_spec smb3_fs_p + fsparam_string("sec", Opt_sec), + fsparam_string("cache", Opt_cache), + fsparam_string("reparse", Opt_reparse), ++ fsparam_string("upcall_target", Opt_upcalltarget), + + /* Arguments that should be ignored */ + fsparam_flag("guest", Opt_ignore), +@@ -249,6 +256,29 @@ cifs_parse_security_flavors(struct fs_co + return 0; + } + ++static int ++cifs_parse_upcall_target(struct fs_context *fc, char *value, struct smb3_fs_context *ctx) ++{ ++ substring_t args[MAX_OPT_ARGS]; ++ ++ ctx->upcall_target = UPTARGET_UNSPECIFIED; ++ ++ switch (match_token(value, cifs_upcall_target, args)) { ++ case Opt_upcall_target_mount: ++ ctx->upcall_target = UPTARGET_MOUNT; ++ break; ++ case Opt_upcall_target_application: ++ ctx->upcall_target = UPTARGET_APP; ++ break; ++ ++ default: ++ cifs_errorf(fc, "bad upcall target: %s\n", value); ++ return 1; ++ } ++ ++ return 0; ++} ++ + static const match_table_t cifs_cacheflavor_tokens = { + { Opt_cache_loose, "loose" }, + { Opt_cache_strict, "strict" }, +@@ -1526,6 +1556,10 @@ static int smb3_fs_context_parse_param(s + if (cifs_parse_security_flavors(fc, param->string, ctx) != 0) + goto cifs_parse_mount_err; + break; ++ case Opt_upcalltarget: ++ if (cifs_parse_upcall_target(fc, param->string, ctx) != 0) ++ goto cifs_parse_mount_err; ++ break; + case Opt_cache: + if (cifs_parse_cache_flavor(fc, param->string, ctx) != 0) + goto cifs_parse_mount_err; +@@ -1703,6 +1737,11 @@ static int smb3_fs_context_parse_param(s + } + /* case Opt_ignore: - is ignored as expected ... */ + ++ if (ctx->multiuser && ctx->upcall_target == UPTARGET_MOUNT) { ++ cifs_errorf(fc, "multiuser mount option not supported with upcalltarget set as 'mount'\n"); ++ goto cifs_parse_mount_err; ++ } ++ + return 0; + + cifs_parse_mount_err: +--- a/fs/smb/client/fs_context.h ++++ b/fs/smb/client/fs_context.h +@@ -61,6 +61,12 @@ enum cifs_sec_param { + Opt_sec_err + }; + ++enum cifs_upcall_target_param { ++ Opt_upcall_target_mount, ++ Opt_upcall_target_application, ++ Opt_upcall_target_err ++}; ++ + enum cifs_param { + /* Mount options that take no arguments */ + Opt_user_xattr, +@@ -114,6 +120,8 @@ enum cifs_param { + Opt_multichannel, + Opt_compress, + Opt_witness, ++ Opt_is_upcall_target_mount, ++ Opt_is_upcall_target_application, + + /* Mount options which take numeric value */ + Opt_backupuid, +@@ -157,6 +165,7 @@ enum cifs_param { + Opt_sec, + Opt_cache, + Opt_reparse, ++ Opt_upcalltarget, + + /* Mount options to be ignored */ + Opt_ignore, +@@ -198,6 +207,7 @@ struct smb3_fs_context { + umode_t file_mode; + umode_t dir_mode; + enum securityEnum sectype; /* sectype requested via mnt opts */ ++ enum upcall_target_enum upcall_target; /* where to upcall for mount */ + bool sign; /* was signing requested via mnt opts? */ + bool ignore_signature:1; + bool retry:1; diff --git a/queue-6.12/series b/queue-6.12/series index 3428c6af64..962dc1e26f 100644 --- a/queue-6.12/series +++ b/queue-6.12/series @@ -133,3 +133,4 @@ dmaengine-idxd-add-missing-idxd-cleanup-to-fix-memory-leak-in-remove-call.patch dmaengine-idxd-fix-memory-leak-in-error-handling-path-of-idxd_alloc.patch dmaengine-idxd-fix-memory-leak-in-error-handling-path-of-idxd_pci_probe.patch dmaengine-idxd-refactor-remove-call-with-idxd_cleanup-helper.patch +cifs-new-mount-option-for-cifs.upcall-namespace-resolution.patch