Re: [PATCH] CIFS.upcall to accomodate new namespace mount opt

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Attaching the previously sent patch which introduces the upcall target mount
opt for the kernel. The current patch is dependent on the attached patch below.


On Mon, 18 Nov 2024 at 22:08, <budhirajaritviksmb@xxxxxxxxx> wrote:
From: Ritvik Budhiraja <rbudhiraja@xxxxxxxxxxxxx>

NOTE: This patch is dependent on one of the previously sent patches:
[PATCH] CIFS: New mount option for cifs.upcall namespace resolution
which introduces a new mount option called upcall_target, to
customise the upcall behaviour.

Building upon the above patch, the following patch adds functionality
to handle upcall_target as a mount option in cifs.upcall. It can have 2 values -
mount, app.
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".
This aids use cases like Kubernetes where the mount
happens on behalf of the application in another container altogether.

Signed-off-by: Ritvik Budhiraja <rbudhiraja@xxxxxxxxxxxxx>
---
 cifs.upcall.c | 55 +++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 47 insertions(+), 8 deletions(-)

diff --git a/cifs.upcall.c b/cifs.upcall.c
index ff6f2bd..a790aca 100644
--- a/cifs.upcall.c
+++ b/cifs.upcall.c
@@ -954,6 +954,13 @@ struct decoded_args {
 #define MAX_USERNAME_SIZE 256
        char username[MAX_USERNAME_SIZE + 1];

+#define MAX_UPCALL_STRING_LEN 6 /* "mount\0" */
+       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 */
+       } upcall_target;
+
        uid_t uid;
        uid_t creduid;
        pid_t pid;
@@ -970,6 +977,7 @@ struct decoded_args {
 #define DKD_HAVE_PID           0x20
 #define DKD_HAVE_CREDUID       0x40
 #define DKD_HAVE_USERNAME      0x80
+#define DKD_HAVE_UPCALL_TARGET 0x100
 #define DKD_MUSTHAVE_SET (DKD_HAVE_HOSTNAME|DKD_HAVE_VERSION|DKD_HAVE_SEC)
        int have;
 };
@@ -980,6 +988,7 @@ __decode_key_description(const char *desc, struct decoded_args *arg)
        size_t len;
        char *pos;
        const char *tkn = desc;
+       arg->upcall_target = UPTARGET_UNSPECIFIED;

        do {
                pos = index(tkn, ';');
@@ -1078,6 +1087,31 @@ __decode_key_description(const char *desc, struct decoded_args *arg)
                        }
                        arg->have |= DKD_HAVE_VERSION;
                        syslog(LOG_DEBUG, "ver=%d", arg->ver);
+               } else if (strncmp(tkn, "upcall_target=", 14) == 0) {
+                       if (pos == NULL)
+                               len = strlen(tkn);
+                       else
+                               len = pos - tkn;
+
+                       len -= 14;
+                       if (len > MAX_UPCALL_STRING_LEN) {
+                               syslog(LOG_ERR, "upcall_target= value too long for buffer");
+                               return 1;
+                       }
+                       if (strncmp(tkn + 14, "mount", 5) == 0) {
+                               arg->upcall_target = UPTARGET_MOUNT;
+                               syslog(LOG_DEBUG, "upcall_target=mount");
+                       } else if (strncmp(tkn + 14, "app", 3) == 0) {
+                               arg->upcall_target = UPTARGET_APP;
+                               syslog(LOG_DEBUG, "upcall_target=app");
+                       } else {
+                               // Should never happen
+                               syslog(LOG_ERR, "Invalid upcall_target value: %s, defaulting to app",
+                                      tkn + 14);
+                               arg->upcall_target = UPTARGET_APP;
+                               syslog(LOG_DEBUG, "upcall_target=app");
+                       }
+                       arg->have |= DKD_HAVE_UPCALL_TARGET;
                }
                if (pos == NULL)
                        break;
@@ -1441,15 +1475,20 @@ int main(const int argc, char *const argv[])
         * acceptably in containers, because we'll be looking at the correct
         * filesystem and have the correct network configuration.
         */
-       rc = switch_to_process_ns(arg->pid);
-       if (rc == -1) {
-               syslog(LOG_ERR, "unable to switch to process namespace: %s", strerror(errno));
-               rc = 1;
-               goto out;
+       if (arg->upcall_target == UPTARGET_APP || arg->upcall_target == UPTARGET_UNSPECIFIED) {
+               syslog(LOG_INFO, "upcall_target=app, switching namespaces to application thread");
+               rc = switch_to_process_ns(arg->pid);
+               if (rc == -1) {
+                       syslog(LOG_ERR, "unable to switch to process namespace: %s", strerror(errno));
+                       rc = 1;
+                       goto out;
+               }
+               if (trim_capabilities(env_probe))
+                       goto out;
+       } else {
+               syslog(LOG_INFO, "upcall_target=mount, not switching namespaces to application thread");
        }

-       if (trim_capabilities(env_probe))
-               goto out;

        /*
         * The kernel doesn't pass down the gid, so we resort here to scraping
@@ -1496,7 +1535,7 @@ int main(const int argc, char *const argv[])
         * look at the environ file.
         */
        env_cachename =
-               get_cachename_from_process_env(env_probe ? arg->pid : 0);
+               get_cachename_from_process_env((env_probe && (arg->upcall_target == UPTARGET_APP)) ? arg->pid : 0);

        rc = setuid(uid);
        if (rc == -1) {
--
2.43.0

Attachment: upcall_target_patch.patch
Description: Binary data


[Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux