From: Arshad Hussain Date: Wed, 1 Nov 2023 06:50:53 +0000 (+0530) Subject: LU-17000 gss: Fix Out-of-bounds access under svcgssd_proc.c X-Git-Tag: 2.15.60~55 X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=7d764f1f11be144ad26e33aa8cecedc5bb708793;p=fs%2Flustre-release.git LU-17000 gss: Fix Out-of-bounds access under svcgssd_proc.c 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 Change-Id: I8041cd4063f1b1cefdebf5681df426be61820f99 Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/52920 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Andreas Dilger Reviewed-by: Sebastien Buisson Reviewed-by: Oleg Drokin --- diff --git a/lustre/include/uapi/linux/lustre/lgss.h b/lustre/include/uapi/linux/lustre/lgss.h index 154d678..d353fba 100644 --- a/lustre/include/uapi/linux/lustre/lgss.h +++ b/lustre/include/uapi/linux/lustre/lgss.h @@ -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 */ diff --git a/lustre/ptlrpc/wiretest.c b/lustre/ptlrpc/wiretest.c index 8549a3b..ca536d3 100644 --- a/lustre/ptlrpc/wiretest.c +++ b/lustre/ptlrpc/wiretest.c @@ -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)); diff --git a/lustre/utils/gss/svcgssd_proc.c b/lustre/utils/gss/svcgssd_proc.c index fa61a74..456e19d 100644 --- a/lustre/utils/gss/svcgssd_proc.c +++ b/lustre/utils/gss/svcgssd_proc.c @@ -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; diff --git a/lustre/utils/wirecheck.c b/lustre/utils/wirecheck.c index 4668a0d..22cb0c2 100644 --- a/lustre/utils/wirecheck.c +++ b/lustre/utils/wirecheck.c @@ -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); } diff --git a/lustre/utils/wiretest.c b/lustre/utils/wiretest.c index fa20d85..5c85588 100644 --- a/lustre/utils/wiretest.c +++ b/lustre/utils/wiretest.c @@ -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));