Whamcloud - gitweb
LU-15508 gss: protect from arbitrary write to init channel 61/46461/2
authorSebastien Buisson <sbuisson@ddn.com>
Fri, 4 Feb 2022 14:53:35 +0000 (15:53 +0100)
committerOleg Drokin <green@whamcloud.com>
Sat, 11 Jun 2022 05:34:29 +0000 (05:34 +0000)
In case some arbitrary data was written to the gss init channel,
directly return -EINVAL. This protects against unsolicited
authentication requests, and avoids having a dandling entry
in the auth init cache.

Signed-off-by: Sebastien Buisson <sbuisson@ddn.com>
Change-Id: Iadde630012e4ded83f9609fbb3e10b2e092deb57
Reviewed-on: https://review.whamcloud.com/46461
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: James Simmons <jsimmons@infradead.org>
Reviewed-by: Jeremy Filizetti <jeremy.filizetti@gmail.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/ptlrpc/gss/gss_svc_upcall.c

index f5b41a8..653c495 100644 (file)
@@ -303,47 +303,54 @@ static struct cache_head *rsi_alloc(void)
 
 static int rsi_parse(struct cache_detail *cd, char *mesg, int mlen)
 {
-        char           *buf = mesg;
-        int             len;
-        struct rsi      rsii, *rsip = NULL;
+       char *buf = mesg;
+       int len;
+       struct rsi rsii, *rsip = NULL;
        time64_t expiry;
-        int             status = -EINVAL;
-        ENTRY;
-
+       int status = -EINVAL;
+       ENTRY;
 
-        memset(&rsii, 0, sizeof(rsii));
+       memset(&rsii, 0, sizeof(rsii));
 
-        /* handle */
-        len = qword_get(&mesg, buf, mlen);
-        if (len < 0)
-                goto out;
-        if (rawobj_alloc(&rsii.in_handle, buf, len)) {
-                status = -ENOMEM;
-                goto out;
-        }
+       /* handle */
+       len = qword_get(&mesg, buf, mlen);
+       if (len < 0)
+               goto out;
+       if (rawobj_alloc(&rsii.in_handle, buf, len)) {
+               status = -ENOMEM;
+               goto out;
+       }
 
-        /* token */
-        len = qword_get(&mesg, buf, mlen);
-        if (len < 0)
-                goto out;
-        if (rawobj_alloc(&rsii.in_token, buf, len)) {
-                status = -ENOMEM;
-                goto out;
-        }
+       /* token */
+       len = qword_get(&mesg, buf, mlen);
+       if (len < 0)
+               goto out;
+       if (rawobj_alloc(&rsii.in_token, buf, len)) {
+               status = -ENOMEM;
+               goto out;
+       }
 
-        rsip = rsi_lookup(&rsii);
-        if (!rsip)
+       rsip = rsi_lookup(&rsii);
+       if (!rsip)
+               goto out;
+       if (!test_bit(CACHE_PENDING, &rsip->h.flags)) {
+               /* If this is not a pending request, it probably means
+                * someone wrote arbitrary data to the init channel.
+                * Directly return -EINVAL in this case.
+                */
+               status = -EINVAL;
                 goto out;
+       }
 
-        rsii.h.flags = 0;
-        /* expiry */
-        expiry = get_expiry(&mesg);
-        if (expiry == 0)
-                goto out;
+       rsii.h.flags = 0;
+       /* expiry */
+       expiry = get_expiry(&mesg);
+       if (expiry == 0)
+               goto out;
 
-        len = qword_get(&mesg, buf, mlen);
-        if (len <= 0)
-                goto out;
+       len = qword_get(&mesg, buf, mlen);
+       if (len <= 0)
+               goto out;
 
        /* major */
        status = kstrtoint(buf, 10, &rsii.major_status);
@@ -361,27 +368,27 @@ static int rsi_parse(struct cache_detail *cd, char *mesg, int mlen)
        if (status)
                goto out;
 
-        /* out_handle */
-        len = qword_get(&mesg, buf, mlen);
-        if (len < 0)
-                goto out;
-        if (rawobj_alloc(&rsii.out_handle, buf, len)) {
-                status = -ENOMEM;
-                goto out;
-        }
+       /* out_handle */
+       len = qword_get(&mesg, buf, mlen);
+       if (len < 0)
+               goto out;
+       if (rawobj_alloc(&rsii.out_handle, buf, len)) {
+               status = -ENOMEM;
+               goto out;
+       }
 
-        /* out_token */
-        len = qword_get(&mesg, buf, mlen);
-        if (len < 0)
-                goto out;
-        if (rawobj_alloc(&rsii.out_token, buf, len)) {
-                status = -ENOMEM;
-                goto out;
-        }
+       /* out_token */
+       len = qword_get(&mesg, buf, mlen);
+       if (len < 0)
+               goto out;
+       if (rawobj_alloc(&rsii.out_token, buf, len)) {
+               status = -ENOMEM;
+               goto out;
+       }
 
-        rsii.h.expiry_time = expiry;
-        rsip = rsi_update(&rsii, rsip);
-        status = 0;
+       rsii.h.expiry_time = expiry;
+       rsip = rsi_update(&rsii, rsip);
+       status = 0;
 out:
        rsi_free(&rsii);
        if (rsip) {