Skip to content

Commit aa1e52c

Browse files
scottmayhewgregkh
authored andcommitted
sunrpc: fix 4 more call sites that were using stack memory with a scatterlist
commit e7afe6c upstream. While trying to reproduce a reported kernel panic on arm64, I discovered that AUTH_GSS basically doesn't work at all with older enctypes on arm64 systems with CONFIG_VMAP_STACK enabled. It turns out there still a few places using stack memory with scatterlists, causing krb5_encrypt() and krb5_decrypt() to produce incorrect results (or a BUG if CONFIG_DEBUG_SG is enabled). Tested with cthon on v4.0/v4.1/v4.2 with krb5/krb5i/krb5p using des3-cbc-sha1 and arcfour-hmac-md5. Signed-off-by: Scott Mayhew <[email protected]> Cc: [email protected] Signed-off-by: J. Bruce Fields <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 3a493b7 commit aa1e52c

File tree

1 file changed

+38
-11
lines changed

1 file changed

+38
-11
lines changed

net/sunrpc/auth_gss/gss_krb5_seqnum.c

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ krb5_make_rc4_seq_num(struct krb5_ctx *kctx, int direction, s32 seqnum,
4444
unsigned char *cksum, unsigned char *buf)
4545
{
4646
struct crypto_skcipher *cipher;
47-
unsigned char plain[8];
47+
unsigned char *plain;
4848
s32 code;
4949

5050
dprintk("RPC: %s:\n", __func__);
@@ -53,6 +53,10 @@ krb5_make_rc4_seq_num(struct krb5_ctx *kctx, int direction, s32 seqnum,
5353
if (IS_ERR(cipher))
5454
return PTR_ERR(cipher);
5555

56+
plain = kmalloc(8, GFP_NOFS);
57+
if (!plain)
58+
return -ENOMEM;
59+
5660
plain[0] = (unsigned char) ((seqnum >> 24) & 0xff);
5761
plain[1] = (unsigned char) ((seqnum >> 16) & 0xff);
5862
plain[2] = (unsigned char) ((seqnum >> 8) & 0xff);
@@ -69,6 +73,7 @@ krb5_make_rc4_seq_num(struct krb5_ctx *kctx, int direction, s32 seqnum,
6973
code = krb5_encrypt(cipher, cksum, plain, buf, 8);
7074
out:
7175
crypto_free_skcipher(cipher);
76+
kfree(plain);
7277
return code;
7378
}
7479
s32
@@ -78,12 +83,17 @@ krb5_make_seq_num(struct krb5_ctx *kctx,
7883
u32 seqnum,
7984
unsigned char *cksum, unsigned char *buf)
8085
{
81-
unsigned char plain[8];
86+
unsigned char *plain;
87+
s32 code;
8288

8389
if (kctx->enctype == ENCTYPE_ARCFOUR_HMAC)
8490
return krb5_make_rc4_seq_num(kctx, direction, seqnum,
8591
cksum, buf);
8692

93+
plain = kmalloc(8, GFP_NOFS);
94+
if (!plain)
95+
return -ENOMEM;
96+
8797
plain[0] = (unsigned char) (seqnum & 0xff);
8898
plain[1] = (unsigned char) ((seqnum >> 8) & 0xff);
8999
plain[2] = (unsigned char) ((seqnum >> 16) & 0xff);
@@ -94,15 +104,17 @@ krb5_make_seq_num(struct krb5_ctx *kctx,
94104
plain[6] = direction;
95105
plain[7] = direction;
96106

97-
return krb5_encrypt(key, cksum, plain, buf, 8);
107+
code = krb5_encrypt(key, cksum, plain, buf, 8);
108+
kfree(plain);
109+
return code;
98110
}
99111

100112
static s32
101113
krb5_get_rc4_seq_num(struct krb5_ctx *kctx, unsigned char *cksum,
102114
unsigned char *buf, int *direction, s32 *seqnum)
103115
{
104116
struct crypto_skcipher *cipher;
105-
unsigned char plain[8];
117+
unsigned char *plain;
106118
s32 code;
107119

108120
dprintk("RPC: %s:\n", __func__);
@@ -115,20 +127,28 @@ krb5_get_rc4_seq_num(struct krb5_ctx *kctx, unsigned char *cksum,
115127
if (code)
116128
goto out;
117129

130+
plain = kmalloc(8, GFP_NOFS);
131+
if (!plain) {
132+
code = -ENOMEM;
133+
goto out;
134+
}
135+
118136
code = krb5_decrypt(cipher, cksum, buf, plain, 8);
119137
if (code)
120-
goto out;
138+
goto out_plain;
121139

122140
if ((plain[4] != plain[5]) || (plain[4] != plain[6])
123141
|| (plain[4] != plain[7])) {
124142
code = (s32)KG_BAD_SEQ;
125-
goto out;
143+
goto out_plain;
126144
}
127145

128146
*direction = plain[4];
129147

130148
*seqnum = ((plain[0] << 24) | (plain[1] << 16) |
131149
(plain[2] << 8) | (plain[3]));
150+
out_plain:
151+
kfree(plain);
132152
out:
133153
crypto_free_skcipher(cipher);
134154
return code;
@@ -141,26 +161,33 @@ krb5_get_seq_num(struct krb5_ctx *kctx,
141161
int *direction, u32 *seqnum)
142162
{
143163
s32 code;
144-
unsigned char plain[8];
145164
struct crypto_skcipher *key = kctx->seq;
165+
unsigned char *plain;
146166

147167
dprintk("RPC: krb5_get_seq_num:\n");
148168

149169
if (kctx->enctype == ENCTYPE_ARCFOUR_HMAC)
150170
return krb5_get_rc4_seq_num(kctx, cksum, buf,
151171
direction, seqnum);
172+
plain = kmalloc(8, GFP_NOFS);
173+
if (!plain)
174+
return -ENOMEM;
152175

153176
if ((code = krb5_decrypt(key, cksum, buf, plain, 8)))
154-
return code;
177+
goto out;
155178

156179
if ((plain[4] != plain[5]) || (plain[4] != plain[6]) ||
157-
(plain[4] != plain[7]))
158-
return (s32)KG_BAD_SEQ;
180+
(plain[4] != plain[7])) {
181+
code = (s32)KG_BAD_SEQ;
182+
goto out;
183+
}
159184

160185
*direction = plain[4];
161186

162187
*seqnum = ((plain[0]) |
163188
(plain[1] << 8) | (plain[2] << 16) | (plain[3] << 24));
164189

165-
return 0;
190+
out:
191+
kfree(plain);
192+
return code;
166193
}

0 commit comments

Comments
 (0)