Skip to content

Commit 16451ae

Browse files
committed
pppd: Be careful not to access beyond end of EAP packets
In the EAP code there are a few places where we could read beyond the end of the received data in a malformed packet received from the peer. Because the received packet is in the statically-allocated inpacket_buf, and because EAP packets can only have a limited number of fields of limited size, these accesses would be within the bounds of inpacket_buf, not to unallocated data. Furthermore the data read were not disclosed to the peer and didn't affect the operation of pppd beyond being printed in log messages. Hence the security impact of these accesses is low, and in fact they don't appear to create any actual vulnerability. Nevertheless it is better to be careful, so this adds extra checks to make sure we never read beyond the end of the received data. Thanks to Kazuma Matsumoto, a security researcher at GMO Cybersecurity by IERAE, Inc., for finding this. Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
1 parent f5a6fb9 commit 16451ae

File tree

1 file changed

+36
-19
lines changed

1 file changed

+36
-19
lines changed

pppd/eap.c

Lines changed: 36 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1954,14 +1954,14 @@ eap_request(eap_state *esp, u_char *inp, int id, int len)
19541954
/* No session key just yet */
19551955
esp->es_client.ea_skey = NULL;
19561956
if (tc == NULL) {
1957-
GETCHAR(vallen, inp);
1958-
len--;
1959-
if (vallen >= len) {
1957+
if (len < 1 || len < inp[0] + 1) {
19601958
error("EAP: badly-formed SRP Challenge"
19611959
" (name)");
19621960
/* Ignore badly-formed messages */
19631961
return;
19641962
}
1963+
GETCHAR(vallen, inp);
1964+
len--;
19651965
BCOPY(inp, rhostname, vallen);
19661966
rhostname[vallen] = '\0';
19671967
INCPTR(vallen, inp);
@@ -1982,27 +1982,27 @@ eap_request(eap_state *esp, u_char *inp, int id, int len)
19821982
esp->es_client.ea_peer = strdup(rhostname);
19831983
esp->es_client.ea_peerlen = strlen(rhostname);
19841984

1985-
GETCHAR(vallen, inp);
1986-
len--;
1987-
if (vallen >= len) {
1985+
if (len < 1 || len < inp[0] + 1) {
19881986
error("EAP: badly-formed SRP Challenge"
19891987
" (s)");
19901988
/* Ignore badly-formed messages */
19911989
return;
19921990
}
1991+
GETCHAR(vallen, inp);
1992+
len--;
19931993
sval.data = inp;
19941994
sval.len = vallen;
19951995
INCPTR(vallen, inp);
19961996
len -= vallen;
19971997

1998-
GETCHAR(vallen, inp);
1999-
len--;
2000-
if (vallen > len) {
1998+
if (len < 1 || len < inp[0] + 1) {
20011999
error("EAP: badly-formed SRP Challenge"
20022000
" (g)");
20032001
/* Ignore badly-formed messages */
20042002
return;
20052003
}
2004+
GETCHAR(vallen, inp);
2005+
len--;
20062006
/* If no generator present, then use value 2 */
20072007
if (vallen == 0) {
20082008
gval.data = (u_char *)"\002";
@@ -2196,11 +2196,16 @@ eap_request(eap_state *esp, u_char *inp, int id, int len)
21962196
u_char *challenge = inp;
21972197

21982198
unsigned char vsize;
2199+
2200+
if (len < 1 + MS_CHAP2_PEER_CHAL_LEN) {
2201+
error("EAP: received invalid MSCHAPv2 packet, invalid length: %d", len);
2202+
return;
2203+
}
21992204
GETCHAR(vsize, inp);
22002205
len -= 1;
22012206

22022207
/* Validate the VALUE field */
2203-
if (vsize != MS_CHAP2_PEER_CHAL_LEN || len < MS_CHAP2_PEER_CHAL_LEN) {
2208+
if (vsize != MS_CHAP2_PEER_CHAL_LEN) {
22042209
error("EAP: received invalid MSCHAPv2 packet, invalid value-length: %d", vsize);
22052210
return;
22062211
}
@@ -2622,17 +2627,17 @@ eap_response(eap_state *esp, u_char *inp, int id, int len)
26222627
eap_figure_next_state(esp, 1);
26232628
break;
26242629
}
2625-
/* skip MS ID + len */
2626-
INCPTR(3, inp);
2627-
GETCHAR(vallen, inp);
2628-
len -= 4;
26292630

2630-
if (vallen != MS_CHAP2_RESPONSE_LEN || vallen > len) {
2631-
error("EAP: Invalid MSCHAPv2-Response "
2632-
"length %d", vallen);
2631+
/* skip MS ID + len */
2632+
if (len < 4 + MS_CHAP2_RESPONSE_LEN || inp[3] != MS_CHAP2_RESPONSE_LEN) {
2633+
error("EAP: Invalid/short MSCHAPv2-Response, "
2634+
"length %d", len);
26332635
eap_figure_next_state(esp, 1);
26342636
break;
26352637
}
2638+
INCPTR(3, inp);
2639+
GETCHAR(vallen, inp);
2640+
len -= 4;
26362641

26372642
/* Not so likely to happen. */
26382643
if (len - vallen >= sizeof (rhostname)) {
@@ -3010,14 +3015,16 @@ eap_printpkt(u_char *inp, int inlen,
30103015
GETCHAR(code, inp);
30113016
GETCHAR(id, inp);
30123017
GETSHORT(len, inp);
3013-
if (len < EAP_HEADERLEN || len > inlen)
3014-
return (0);
30153018

30163019
if (code >= 1 && code <= sizeof(eap_codenames) / sizeof(char *))
30173020
printer(arg, " %s", eap_codenames[code-1]);
30183021
else
30193022
printer(arg, " code=0x%x", code);
30203023
printer(arg, " id=0x%x", id);
3024+
if (len < EAP_HEADERLEN || len > inlen) {
3025+
printer(arg, " <bad length=%d>", len);
3026+
return (0);
3027+
}
30213028
len -= EAP_HEADERLEN;
30223029
switch (code) {
30233030
case EAP_REQUEST:
@@ -3075,6 +3082,8 @@ eap_printpkt(u_char *inp, int inlen,
30753082
len--;
30763083
switch (opcode) {
30773084
case CHAP_CHALLENGE:
3085+
if (len < 4)
3086+
goto truncated;
30783087
INCPTR(3, inp);
30793088
len -= 3;
30803089
GETCHAR(vallen, inp);
@@ -3100,20 +3109,26 @@ eap_printpkt(u_char *inp, int inlen,
31003109
}
31013110
break;
31023111
case CHAP_SUCCESS:
3112+
if (len < 3)
3113+
goto truncated;
31033114
INCPTR(3, inp);
31043115
len -= 3;
31053116
printer(arg, " Success <Message ");
31063117
print_string((char *)inp, len, printer, arg);
31073118
printer(arg, ">");
31083119
break;
31093120
case CHAP_FAILURE:
3121+
if (len < 3)
3122+
goto truncated;
31103123
INCPTR(3, inp);
31113124
len -= 3;
31123125
printer(arg, " Failure <Message ");
31133126
print_string((char *)inp, len, printer, arg);
31143127
printer(arg, ">");
31153128
break;
31163129
default:
3130+
if (len < 3)
3131+
goto truncated;
31173132
INCPTR(3, inp);
31183133
len -= 3;
31193134
printer(arg, " opcode=0x%x <%.*B>", opcode, len, inp);
@@ -3317,6 +3332,8 @@ eap_printpkt(u_char *inp, int inlen,
33173332
len--;
33183333
switch (opcode) {
33193334
case CHAP_RESPONSE:
3335+
if (len < 4)
3336+
goto truncated;
33203337
INCPTR(3, inp);
33213338
len -= 3;
33223339
GETCHAR(vallen, inp);

0 commit comments

Comments
 (0)