2.4.36-stable kernel tree
Revision | 53d12affc55d827d895fba7b902fb03ec2098a29 (tree) |
---|---|
Zeit | 2008-06-06 07:11:50 |
Autor | Chris Wright <chrisw@sous...> |
Commiter | Willy Tarreau |
asn1: additional sanity checking during BER decoding (CVE-2008-1673)
[backport of 2.6 commit ddb2c43594f22843e9f3153da151deaba1a834c5]
- Don't trust a length which is greater than the working buffer.
- An oid length of zero is invalid and allows for an off-by-one error when
- A primitive encoding may not have an indefinite length.
Thanks to Wei Wang from McAfee for report.
Cc: Steven French <sfrench@us.ibm.com>
Cc: stable@kernel.org
Acked-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Chris Wright <chrisw@sous-sol.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
[w@1wt.eu: backported to 2.4 : no cifs ; snmp in ip_nat_snmp_basic.c]
Signed-off-by: Willy Tarreau <w@1wt.eu>
@@ -232,6 +232,11 @@ static unsigned char asn1_length_decode(struct asn1_ctx *ctx, | ||
232 | 232 | } |
233 | 233 | } |
234 | 234 | } |
235 | + | |
236 | + /* don't trust len bigger than ctx buffer */ | |
237 | + if (*len > ctx->end - ctx->pointer) | |
238 | + return 0; | |
239 | + | |
235 | 240 | return 1; |
236 | 241 | } |
237 | 242 |
@@ -248,7 +253,11 @@ static unsigned char asn1_header_decode(struct asn1_ctx *ctx, | ||
248 | 253 | |
249 | 254 | if (!asn1_length_decode(ctx, &def, &len)) |
250 | 255 | return 0; |
251 | - | |
256 | + | |
257 | + /* primitive shall be definite, indefinite shall be constructed */ | |
258 | + if (*con == ASN1_PRI && !def) | |
259 | + return 0; | |
260 | + | |
252 | 261 | if (def) |
253 | 262 | *eoc = ctx->pointer + len; |
254 | 263 | else |
@@ -433,6 +442,11 @@ static unsigned char asn1_oid_decode(struct asn1_ctx *ctx, | ||
433 | 442 | unsigned long *optr; |
434 | 443 | |
435 | 444 | size = eoc - ctx->pointer + 1; |
445 | + | |
446 | + /* first subid actually encodes first two subids */ | |
447 | + if (size < 2 || size > ULONG_MAX/sizeof(unsigned long)) | |
448 | + return 0; | |
449 | + | |
436 | 450 | *oid = kmalloc(size * sizeof(unsigned long), GFP_ATOMIC); |
437 | 451 | if (*oid == NULL) { |
438 | 452 | if (net_ratelimit()) |