]> err.no Git - linux-2.6/blobdiff - net/ipv4/netfilter/nf_nat_snmp_basic.c
netfilter: nf_nat_snmp_basic: fix a range check in NAT for SNMP
[linux-2.6] / net / ipv4 / netfilter / nf_nat_snmp_basic.c
index 5daefad3d1936393139baf80d48cff263c5262cd..ffeaffc3fffe6c31c78e858b9a1fa61fe71ba03e 100644 (file)
@@ -232,6 +232,11 @@ static unsigned char asn1_length_decode(struct asn1_ctx *ctx,
                        }
                }
        }
+
+       /* don't trust len bigger than ctx buffer */
+       if (*len > ctx->end - ctx->pointer)
+               return 0;
+
        return 1;
 }
 
@@ -250,6 +255,10 @@ static unsigned char asn1_header_decode(struct asn1_ctx *ctx,
        if (!asn1_length_decode(ctx, &def, &len))
                return 0;
 
+       /* primitive shall be definite, indefinite shall be constructed */
+       if (*con == ASN1_PRI && !def)
+               return 0;
+
        if (def)
                *eoc = ctx->pointer + len;
        else
@@ -430,10 +439,15 @@ static unsigned char asn1_oid_decode(struct asn1_ctx *ctx,
                                     unsigned int *len)
 {
        unsigned long subid;
-       unsigned int  size;
        unsigned long *optr;
+       size_t size;
 
        size = eoc - ctx->pointer + 1;
+
+       /* first subid actually encodes first two subids */
+       if (size < 2 || size > ULONG_MAX/sizeof(unsigned long))
+               return 0;
+
        *oid = kmalloc(size * sizeof(unsigned long), GFP_ATOMIC);
        if (*oid == NULL) {
                if (net_ratelimit())