From f06807d409c82dd85c208c79c8072402e77f9bac Mon Sep 17 00:00:00 2001 From: Sebastien Buisson Date: Fri, 4 Feb 2022 15:53:35 +0100 Subject: [PATCH] LU-15508 gss: protect from arbitrary write to init channel 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 Change-Id: Iadde630012e4ded83f9609fbb3e10b2e092deb57 Reviewed-on: https://review.whamcloud.com/46461 Tested-by: jenkins Tested-by: Maloo Reviewed-by: James Simmons Reviewed-by: Jeremy Filizetti Reviewed-by: Oleg Drokin --- lustre/ptlrpc/gss/gss_svc_upcall.c | 111 ++++++++++++++++++++----------------- 1 file changed, 59 insertions(+), 52 deletions(-) diff --git a/lustre/ptlrpc/gss/gss_svc_upcall.c b/lustre/ptlrpc/gss/gss_svc_upcall.c index f5b41a8..653c495 100644 --- a/lustre/ptlrpc/gss/gss_svc_upcall.c +++ b/lustre/ptlrpc/gss/gss_svc_upcall.c @@ -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) { -- 1.8.3.1