* [PATCH] cifs.upcall: resolve scraped ccache name explicitly
@ 2026-09-17 0:37 Paulo Alcantara
2026-09-17 7:06 ` Shyam Prasad N
2026-09-17 16:22 ` Paulo Alcantara
0 siblings, 2 replies; 3+ messages in thread
From: Paulo Alcantara @ 2026-09-17 0:37 UTC (permalink / raw)
To: Pavel Shilovsky
Cc: Alexander Bokovoy, Shyam Prasad N, Bharath SM, David Howells,
linux-cifs
get_existing_cc() selected the credentials cache scraped from the
initiating process' environment by exporting it via setenv($KRB5CCNAME)
and then calling krb5_cc_default().
MIT krb5 reads $KRB5CCNAME through secure_getenv(), which returns NULL
whenever the process runs with AT_SECURE set. The request-key upcall
that spawns cifs.upcall triggers an SELinux domain transition, so on
systems with SELinux enforcing cifs.upcall runs with AT_SECURE=1. The
setenv() is therefore silently ignored and krb5 falls back to the
profile default_ccache_name (KCM: on many distros). As a result, a
valid TGT living in a FILE credential cache is never found, and the
mount fails with:
cifs.upcall: main: valid TGT is not present in credential cache
cifs.upcall: Unable to obtain service ticket
while the same TGT in a KCM cache (selected via the profile default,
not the environment) works fine.
Resolve the scraped name directly with krb5_cc_resolve(), which takes
the ccache name as an argument and does not consult secure_getenv(),
so the FILE ccache is honored regardless of AT_SECURE. Fall back to
krb5_cc_default() only when nothing was scraped.
Reported-by: Alexander Bokovoy <ab@samba.org>
Fixes: ed97e4ecab4e ("cifs.upcall: allow scraping of KRB5CCNAME out of initiating task's /proc/<pid>/environ file")
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Cc: Shyam Prasad N <sprasad@microsoft.com>
Cc: Bharath SM <bharathsm@microsoft.com>
Cc: David Howells <dhowells@redhat.com>
Cc: linux-cifs@vger.kernel.org
---
cifs.upcall.c | 32 ++++++++++++++++++++++++--------
1 file changed, 24 insertions(+), 8 deletions(-)
diff --git a/cifs.upcall.c b/cifs.upcall.c
index 76e88b79a760..8fdf1af710ef 100644
--- a/cifs.upcall.c
+++ b/cifs.upcall.c
@@ -534,15 +534,31 @@ get_existing_cc(const char *env_cachename)
krb5_ccache cc;
char *cachename;
+ /*
+ * If we scraped a cache name out of the initiating process'
+ * environment, resolve it explicitly instead of exporting it via
+ * $KRB5CCNAME and relying on krb5_cc_default(). MIT krb5 reads
+ * $KRB5CCNAME through secure_getenv(), which returns NULL whenever the
+ * process runs with AT_SECURE set (e.g. an SELinux domain transition on
+ * the request-key upcall). In that case the setenv() is silently
+ * ignored and krb5 falls back to the profile default_ccache_name (KCM:
+ * on many distros), so a TGT living in a FILE ccache is never found.
+ * krb5_cc_resolve() takes the name directly and is not affected.
+ */
if (env_cachename) {
- if (setenv(ENV_NAME, env_cachename, 1))
- syslog(LOG_DEBUG, "%s: failed to setenv %d\n", __func__, errno);
- }
-
- ret = krb5_cc_default(context, &cc);
- if (ret) {
- syslog(LOG_DEBUG, "%s: krb5_cc_default returned %d", __func__, ret);
- return NULL;
+ ret = krb5_cc_resolve(context, env_cachename, &cc);
+ if (ret) {
+ syslog(LOG_DEBUG, "%s: krb5_cc_resolve(%s) failed: %d\n",
+ __func__, env_cachename, ret);
+ return NULL;
+ }
+ } else {
+ ret = krb5_cc_default(context, &cc);
+ if (ret) {
+ syslog(LOG_DEBUG, "%s: krb5_cc_default returned %d",
+ __func__, ret);
+ return NULL;
+ }
}
ret = krb5_cc_get_full_name(context, cc, &cachename);
--
2.55.0
^ permalink raw reply related [flat|nested] 3+ messages in thread* Re: [PATCH] cifs.upcall: resolve scraped ccache name explicitly
2026-09-17 0:37 [PATCH] cifs.upcall: resolve scraped ccache name explicitly Paulo Alcantara
@ 2026-09-17 7:06 ` Shyam Prasad N
2026-09-17 16:22 ` Paulo Alcantara
1 sibling, 0 replies; 3+ messages in thread
From: Shyam Prasad N @ 2026-09-17 7:06 UTC (permalink / raw)
To: Paulo Alcantara
Cc: Pavel Shilovsky, Alexander Bokovoy, Shyam Prasad N, Bharath SM,
David Howells, linux-cifs
On Thu, Sep 17, 2026 at 6:27 AM Paulo Alcantara <pc@manguebit.org> wrote:
>
> get_existing_cc() selected the credentials cache scraped from the
> initiating process' environment by exporting it via setenv($KRB5CCNAME)
> and then calling krb5_cc_default().
>
> MIT krb5 reads $KRB5CCNAME through secure_getenv(), which returns NULL
> whenever the process runs with AT_SECURE set. The request-key upcall
> that spawns cifs.upcall triggers an SELinux domain transition, so on
> systems with SELinux enforcing cifs.upcall runs with AT_SECURE=1. The
> setenv() is therefore silently ignored and krb5 falls back to the
> profile default_ccache_name (KCM: on many distros). As a result, a
> valid TGT living in a FILE credential cache is never found, and the
> mount fails with:
>
> cifs.upcall: main: valid TGT is not present in credential cache
> cifs.upcall: Unable to obtain service ticket
>
> while the same TGT in a KCM cache (selected via the profile default,
> not the environment) works fine.
>
> Resolve the scraped name directly with krb5_cc_resolve(), which takes
> the ccache name as an argument and does not consult secure_getenv(),
> so the FILE ccache is honored regardless of AT_SECURE. Fall back to
> krb5_cc_default() only when nothing was scraped.
>
> Reported-by: Alexander Bokovoy <ab@samba.org>
> Fixes: ed97e4ecab4e ("cifs.upcall: allow scraping of KRB5CCNAME out of initiating task's /proc/<pid>/environ file")
> Signed-off-by: Paulo Alcantara <pc@manguebit.org>
> Cc: Shyam Prasad N <sprasad@microsoft.com>
> Cc: Bharath SM <bharathsm@microsoft.com>
> Cc: David Howells <dhowells@redhat.com>
> Cc: linux-cifs@vger.kernel.org
> ---
> cifs.upcall.c | 32 ++++++++++++++++++++++++--------
> 1 file changed, 24 insertions(+), 8 deletions(-)
>
> diff --git a/cifs.upcall.c b/cifs.upcall.c
> index 76e88b79a760..8fdf1af710ef 100644
> --- a/cifs.upcall.c
> +++ b/cifs.upcall.c
> @@ -534,15 +534,31 @@ get_existing_cc(const char *env_cachename)
> krb5_ccache cc;
> char *cachename;
>
> + /*
> + * If we scraped a cache name out of the initiating process'
> + * environment, resolve it explicitly instead of exporting it via
> + * $KRB5CCNAME and relying on krb5_cc_default(). MIT krb5 reads
> + * $KRB5CCNAME through secure_getenv(), which returns NULL whenever the
> + * process runs with AT_SECURE set (e.g. an SELinux domain transition on
> + * the request-key upcall). In that case the setenv() is silently
> + * ignored and krb5 falls back to the profile default_ccache_name (KCM:
> + * on many distros), so a TGT living in a FILE ccache is never found.
> + * krb5_cc_resolve() takes the name directly and is not affected.
> + */
> if (env_cachename) {
> - if (setenv(ENV_NAME, env_cachename, 1))
> - syslog(LOG_DEBUG, "%s: failed to setenv %d\n", __func__, errno);
> - }
> -
> - ret = krb5_cc_default(context, &cc);
> - if (ret) {
> - syslog(LOG_DEBUG, "%s: krb5_cc_default returned %d", __func__, ret);
> - return NULL;
> + ret = krb5_cc_resolve(context, env_cachename, &cc);
> + if (ret) {
> + syslog(LOG_DEBUG, "%s: krb5_cc_resolve(%s) failed: %d\n",
> + __func__, env_cachename, ret);
> + return NULL;
> + }
> + } else {
> + ret = krb5_cc_default(context, &cc);
> + if (ret) {
> + syslog(LOG_DEBUG, "%s: krb5_cc_default returned %d",
> + __func__, ret);
> + return NULL;
> + }
> }
>
> ret = krb5_cc_get_full_name(context, cc, &cachename);
> --
> 2.55.0
>
>
Seems like a reasonable fix. Pending testing, you can add my Acked-by.
--
Regards,
Shyam
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: [PATCH] cifs.upcall: resolve scraped ccache name explicitly
2026-09-17 0:37 [PATCH] cifs.upcall: resolve scraped ccache name explicitly Paulo Alcantara
2026-09-17 7:06 ` Shyam Prasad N
@ 2026-09-17 16:22 ` Paulo Alcantara
1 sibling, 0 replies; 3+ messages in thread
From: Paulo Alcantara @ 2026-09-17 16:22 UTC (permalink / raw)
To: Pavel Shilovsky
Cc: Alexander Bokovoy, Shyam Prasad N, Bharath SM, David Howells,
linux-cifs
Paulo Alcantara <pc@manguebit.org> writes:
> get_existing_cc() selected the credentials cache scraped from the
> initiating process' environment by exporting it via setenv($KRB5CCNAME)
> and then calling krb5_cc_default().
>
> MIT krb5 reads $KRB5CCNAME through secure_getenv(), which returns NULL
> whenever the process runs with AT_SECURE set. The request-key upcall
> that spawns cifs.upcall triggers an SELinux domain transition, so on
> systems with SELinux enforcing cifs.upcall runs with AT_SECURE=1. The
> setenv() is therefore silently ignored and krb5 falls back to the
> profile default_ccache_name (KCM: on many distros). As a result, a
> valid TGT living in a FILE credential cache is never found, and the
> mount fails with:
>
> cifs.upcall: main: valid TGT is not present in credential cache
> cifs.upcall: Unable to obtain service ticket
>
> while the same TGT in a KCM cache (selected via the profile default,
> not the environment) works fine.
>
> Resolve the scraped name directly with krb5_cc_resolve(), which takes
> the ccache name as an argument and does not consult secure_getenv(),
> so the FILE ccache is honored regardless of AT_SECURE. Fall back to
> krb5_cc_default() only when nothing was scraped.
> ...
Applied.
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-09-17 16:22 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-17 0:37 [PATCH] cifs.upcall: resolve scraped ccache name explicitly Paulo Alcantara
2026-09-17 7:06 ` Shyam Prasad N
2026-09-17 16:22 ` Paulo Alcantara
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox