• R/O
  • HTTP
  • SSH
  • HTTPS

linux-2.4.36: Commit

2.4.36-stable kernel tree


Commit MetaInfo

Revision53d12affc55d827d895fba7b902fb03ec2098a29 (tree)
Zeit2008-06-06 07:11:50
AutorChris Wright <chrisw@sous...>
CommiterWilly Tarreau

Log Message

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 invalid length could cause overflow when calculating buffer size
for decoding oid.

- An oid length of zero is invalid and allows for an off-by-one error when

decoding oid because the first subid actually encodes first 2 subids.

- 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>

Ändern Zusammenfassung

Diff

--- a/net/ipv4/netfilter/ip_nat_snmp_basic.c
+++ b/net/ipv4/netfilter/ip_nat_snmp_basic.c
@@ -232,6 +232,11 @@ static unsigned char asn1_length_decode(struct asn1_ctx *ctx,
232232 }
233233 }
234234 }
235+
236+ /* don't trust len bigger than ctx buffer */
237+ if (*len > ctx->end - ctx->pointer)
238+ return 0;
239+
235240 return 1;
236241 }
237242
@@ -248,7 +253,11 @@ static unsigned char asn1_header_decode(struct asn1_ctx *ctx,
248253
249254 if (!asn1_length_decode(ctx, &def, &len))
250255 return 0;
251-
256+
257+ /* primitive shall be definite, indefinite shall be constructed */
258+ if (*con == ASN1_PRI && !def)
259+ return 0;
260+
252261 if (def)
253262 *eoc = ctx->pointer + len;
254263 else
@@ -433,6 +442,11 @@ static unsigned char asn1_oid_decode(struct asn1_ctx *ctx,
433442 unsigned long *optr;
434443
435444 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+
436450 *oid = kmalloc(size * sizeof(unsigned long), GFP_ATOMIC);
437451 if (*oid == NULL) {
438452 if (net_ratelimit())
Show on old repository browser