Whamcloud - gitweb
LU-17000 gss: Fix Out-of-bounds access under svcgssd_proc.c 20/52920/9
authorArshad Hussain <arshad.hussain@aeoncomputing.com>
Wed, 1 Nov 2023 06:50:53 +0000 (12:20 +0530)
committerOleg Drokin <green@whamcloud.com>
Wed, 13 Dec 2023 12:21:41 +0000 (12:21 +0000)
Problem reported by coverity was passing 32bit type and
then dereferencing to larger 64bit under function
handle_channel_request(). This patch address this issue.

Since this is an uapi and to catch corner cases like
kernel modules being updated separately from user tools
RSI_DOWNCALL_MAGIC is also changed from 0x6d6dd62a to
0x6d6dd63a.

This patch also changes 32bit member (sid_hash) of
'struct rsi_downcall_data' to 64bit. Which also requires
changing of wiretest.c and wirecheck.c

CoverityID: 404758 ("Out-of-bounds access")
Fixes: 8d828762d1 ("LU-17015 gss: support large kerberos token for rpc sec init")
Test-Parameters: kerberos=true testlist=sanity-krb5
Signed-off-by: Arshad Hussain <arshad.hussain@aeoncomputing.com>
Change-Id: I8041cd4063f1b1cefdebf5681df426be61820f99
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/52920
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Sebastien Buisson <sbuisson@ddn.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/include/uapi/linux/lustre/lgss.h
lustre/ptlrpc/wiretest.c
lustre/utils/gss/svcgssd_proc.c
lustre/utils/wirecheck.c
lustre/utils/wiretest.c

index 154d678..d353fba 100644 (file)
@@ -72,18 +72,27 @@ struct lgssd_ioctl_param {
 };
 
 #define GSS_SOCKET_PATH        "/tmp/svcgssd.socket"
-#define RSI_DOWNCALL_MAGIC     0x6d6dd62a
+/*
+ * Old RSI_DOWNCALL_MAGIC was:
+ * #define RSI_DOWNCALL_MAGIC  0x6d6dd62a
+ *
+ * This is an uapi and to catch cases like kernel modules
+ * being updated separately from user tools new
+ * RSI_DOWNCALL_MAGIC(0x6d6dd63a) was introduced
+ */
+#define RSI_DOWNCALL_MAGIC     0x6d6dd63a
 #define RSI_DOWNCALL_PATH      "sptlrpc/gss/rsi_info"
 #define RSI_CACHE_NAME         "rsicache"
 
 struct rsi_downcall_data {
        __u32     sid_magic;
        __u32     sid_err;
-       __u32     sid_hash;
+       __u32     sid_unused;
        __u32     sid_maj_stat;
        __u32     sid_min_stat;
        __u32     sid_len;
        __s64     sid_offset;
+       __u64     sid_hash;
        /* sid_val contains in_handle, in_token,
         * out_handle, out_token
         */
index 8549a3b..ca536d3 100644 (file)
@@ -4392,7 +4392,7 @@ void lustre_assert_wire_constants(void)
 #endif /* HAVE_SERVER_SUPPORT */
 
        /* Checks for struct rsi_downcall_data */
-       LASSERTF((int)sizeof(struct rsi_downcall_data) == 32, "found %lld\n",
+       LASSERTF((int)sizeof(struct rsi_downcall_data) == 40, "found %lld\n",
                 (long long)(int)sizeof(struct rsi_downcall_data));
        LASSERTF((int)offsetof(struct rsi_downcall_data, sid_magic) == 0, "found %lld\n",
                 (long long)(int)offsetof(struct rsi_downcall_data, sid_magic));
@@ -4402,10 +4402,10 @@ void lustre_assert_wire_constants(void)
                 (long long)(int)offsetof(struct rsi_downcall_data, sid_err));
        LASSERTF((int)sizeof(((struct rsi_downcall_data *)0)->sid_err) == 4, "found %lld\n",
                 (long long)(int)sizeof(((struct rsi_downcall_data *)0)->sid_err));
-       LASSERTF((int)offsetof(struct rsi_downcall_data, sid_hash) == 8, "found %lld\n",
-                (long long)(int)offsetof(struct rsi_downcall_data, sid_hash));
-       LASSERTF((int)sizeof(((struct rsi_downcall_data *)0)->sid_hash) == 4, "found %lld\n",
-                (long long)(int)sizeof(((struct rsi_downcall_data *)0)->sid_hash));
+       LASSERTF((int)offsetof(struct rsi_downcall_data, sid_unused) == 8, "found %lld\n",
+                (long long)(int)offsetof(struct rsi_downcall_data, sid_unused));
+       LASSERTF((int)sizeof(((struct rsi_downcall_data *)0)->sid_unused) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct rsi_downcall_data *)0)->sid_unused));
        LASSERTF((int)offsetof(struct rsi_downcall_data, sid_maj_stat) == 12, "found %lld\n",
                 (long long)(int)offsetof(struct rsi_downcall_data, sid_maj_stat));
        LASSERTF((int)sizeof(((struct rsi_downcall_data *)0)->sid_maj_stat) == 4, "found %lld\n",
@@ -4422,7 +4422,11 @@ void lustre_assert_wire_constants(void)
                 (long long)(int)offsetof(struct rsi_downcall_data, sid_offset));
        LASSERTF((int)sizeof(((struct rsi_downcall_data *)0)->sid_offset) == 8, "found %lld\n",
                 (long long)(int)sizeof(((struct rsi_downcall_data *)0)->sid_offset));
-       LASSERTF((int)offsetof(struct rsi_downcall_data, sid_val) == 32, "found %lld\n",
+       LASSERTF((int)offsetof(struct rsi_downcall_data, sid_hash) == 32, "found %lld\n",
+                (long long)(int)offsetof(struct rsi_downcall_data, sid_hash));
+       LASSERTF((int)sizeof(((struct rsi_downcall_data *)0)->sid_hash) == 8, "found %lld\n",
+                (long long)(int)sizeof(((struct rsi_downcall_data *)0)->sid_hash));
+       LASSERTF((int)offsetof(struct rsi_downcall_data, sid_val) == 40, "found %lld\n",
                 (long long)(int)offsetof(struct rsi_downcall_data, sid_val));
        LASSERTF((int)sizeof(((struct rsi_downcall_data *)0)->sid_val) == 0, "found %lld\n",
                 (long long)(int)sizeof(((struct rsi_downcall_data *)0)->sid_val));
index fa61a74..456e19d 100644 (file)
@@ -177,7 +177,7 @@ out:
 
 #define RPCSEC_GSS_SEQ_WIN     5
 
-static int send_response(int auth_res, uint64_t hash,
+static int send_response(int auth_res, __u64 hash,
                        gss_buffer_desc *in_handle, gss_buffer_desc *in_token,
                        u_int32_t maj_stat, u_int32_t min_stat,
                        gss_buffer_desc *out_handle, gss_buffer_desc *out_token)
@@ -912,7 +912,8 @@ int handle_channel_request(int fd)
                .maj_stat               = GSS_S_FAILURE,
                .ctx                    = GSS_C_NO_CONTEXT,
        };
-       uint64_t hash = 0;
+       __u64 hash = 0;
+       __u64 tmp_lustre_svc = 0;
 
        printerr(LL_INFO, "handling request\n");
        if (readline(fd, &lbuf, &lbuflen) != 1) {
@@ -923,16 +924,17 @@ int handle_channel_request(int fd)
        cp = lbuf;
 
        /* see rsi_do_upcall() for the format of data being input here */
-       rc = gss_u64_read_string(&cp, (__u64 *)&hash);
+       rc = gss_u64_read_string(&cp, &hash);
        if (rc < 0) {
                printerr(LL_ERR, "ERROR: failed parsing request: hash\n");
                goto out_err;
        }
-       rc = gss_u64_read_string(&cp, (__u64 *)&snd.lustre_svc);
+       rc = gss_u64_read_string(&cp, &tmp_lustre_svc);
        if (rc < 0) {
                printerr(LL_ERR, "ERROR: failed parsing request: lustre svc\n");
                goto out_err;
        }
+       snd.lustre_svc = tmp_lustre_svc;
        /* lustre_svc is the svc and gss subflavor */
        lustre_mech = (snd.lustre_svc & LUSTRE_GSS_MECH_MASK) >>
                LUSTRE_GSS_MECH_SHIFT;
index 4668a0d..22cb0c2 100644 (file)
@@ -2052,11 +2052,12 @@ check_rsi_downcall_data(void)
        CHECK_STRUCT(rsi_downcall_data);
        CHECK_MEMBER(rsi_downcall_data, sid_magic);
        CHECK_MEMBER(rsi_downcall_data, sid_err);
-       CHECK_MEMBER(rsi_downcall_data, sid_hash);
+       CHECK_MEMBER(rsi_downcall_data, sid_unused);
        CHECK_MEMBER(rsi_downcall_data, sid_maj_stat);
        CHECK_MEMBER(rsi_downcall_data, sid_min_stat);
        CHECK_MEMBER(rsi_downcall_data, sid_len);
        CHECK_MEMBER(rsi_downcall_data, sid_offset);
+       CHECK_MEMBER(rsi_downcall_data, sid_hash);
        CHECK_MEMBER(rsi_downcall_data, sid_val);
 }
 
index fa20d85..5c85588 100644 (file)
@@ -4453,7 +4453,7 @@ void lustre_assert_wire_constants(void)
 #endif /* HAVE_SERVER_SUPPORT */
 
        /* Checks for struct rsi_downcall_data */
-       LASSERTF((int)sizeof(struct rsi_downcall_data) == 32, "found %lld\n",
+       LASSERTF((int)sizeof(struct rsi_downcall_data) == 40, "found %lld\n",
                 (long long)(int)sizeof(struct rsi_downcall_data));
        LASSERTF((int)offsetof(struct rsi_downcall_data, sid_magic) == 0, "found %lld\n",
                 (long long)(int)offsetof(struct rsi_downcall_data, sid_magic));
@@ -4463,10 +4463,10 @@ void lustre_assert_wire_constants(void)
                 (long long)(int)offsetof(struct rsi_downcall_data, sid_err));
        LASSERTF((int)sizeof(((struct rsi_downcall_data *)0)->sid_err) == 4, "found %lld\n",
                 (long long)(int)sizeof(((struct rsi_downcall_data *)0)->sid_err));
-       LASSERTF((int)offsetof(struct rsi_downcall_data, sid_hash) == 8, "found %lld\n",
-                (long long)(int)offsetof(struct rsi_downcall_data, sid_hash));
-       LASSERTF((int)sizeof(((struct rsi_downcall_data *)0)->sid_hash) == 4, "found %lld\n",
-                (long long)(int)sizeof(((struct rsi_downcall_data *)0)->sid_hash));
+       LASSERTF((int)offsetof(struct rsi_downcall_data, sid_unused) == 8, "found %lld\n",
+                (long long)(int)offsetof(struct rsi_downcall_data, sid_unused));
+       LASSERTF((int)sizeof(((struct rsi_downcall_data *)0)->sid_unused) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct rsi_downcall_data *)0)->sid_unused));
        LASSERTF((int)offsetof(struct rsi_downcall_data, sid_maj_stat) == 12, "found %lld\n",
                 (long long)(int)offsetof(struct rsi_downcall_data, sid_maj_stat));
        LASSERTF((int)sizeof(((struct rsi_downcall_data *)0)->sid_maj_stat) == 4, "found %lld\n",
@@ -4483,7 +4483,11 @@ void lustre_assert_wire_constants(void)
                 (long long)(int)offsetof(struct rsi_downcall_data, sid_offset));
        LASSERTF((int)sizeof(((struct rsi_downcall_data *)0)->sid_offset) == 8, "found %lld\n",
                 (long long)(int)sizeof(((struct rsi_downcall_data *)0)->sid_offset));
-       LASSERTF((int)offsetof(struct rsi_downcall_data, sid_val) == 32, "found %lld\n",
+       LASSERTF((int)offsetof(struct rsi_downcall_data, sid_hash) == 32, "found %lld\n",
+                (long long)(int)offsetof(struct rsi_downcall_data, sid_hash));
+       LASSERTF((int)sizeof(((struct rsi_downcall_data *)0)->sid_hash) == 8, "found %lld\n",
+                (long long)(int)sizeof(((struct rsi_downcall_data *)0)->sid_hash));
+       LASSERTF((int)offsetof(struct rsi_downcall_data, sid_val) == 40, "found %lld\n",
                 (long long)(int)offsetof(struct rsi_downcall_data, sid_val));
        LASSERTF((int)sizeof(((struct rsi_downcall_data *)0)->sid_val) == 0, "found %lld\n",
                 (long long)(int)sizeof(((struct rsi_downcall_data *)0)->sid_val));