X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=net%2Fipv4%2Fnetfilter%2Fnf_nat_snmp_basic.c;h=7750c97fde7bb6bdc6ae05061b2528d3d3e31310;hb=311670f3ea90115f2f1840e3e9770ed71e06e6c3;hp=07f2a49926d4ae1c5ffe6227e0058ff3b19dff05;hpb=e79ec50b9587c175f65f98550d66ad5b96c05dd9;p=linux-2.6-omap-h63xx.git diff --git a/net/ipv4/netfilter/nf_nat_snmp_basic.c b/net/ipv4/netfilter/nf_nat_snmp_basic.c index 07f2a49926d..8303e4b406c 100644 --- a/net/ipv4/netfilter/nf_nat_snmp_basic.c +++ b/net/ipv4/netfilter/nf_nat_snmp_basic.c @@ -50,6 +50,7 @@ #include #include +#include #include #include @@ -219,7 +220,7 @@ static unsigned char asn1_length_decode(struct asn1_ctx *ctx, if (ch < 0x80) *len = ch; else { - cnt = (unsigned char) (ch & 0x7F); + cnt = ch & 0x7F; *len = 0; while (cnt > 0) { @@ -231,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; } @@ -249,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 @@ -260,7 +270,7 @@ static unsigned char asn1_eoc_decode(struct asn1_ctx *ctx, unsigned char *eoc) { unsigned char ch; - if (eoc == 0) { + if (eoc == NULL) { if (!asn1_octet_decode(ctx, &ch)) return 0; @@ -429,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()) @@ -617,8 +632,7 @@ struct snmp_cnv int syntax; }; -static struct snmp_cnv snmp_conv [] = -{ +static const struct snmp_cnv snmp_conv[] = { {ASN1_UNI, ASN1_NUL, SNMP_NULL}, {ASN1_UNI, ASN1_INT, SNMP_INTEGER}, {ASN1_UNI, ASN1_OTS, SNMP_OCTETSTR}, @@ -643,7 +657,7 @@ static unsigned char snmp_tag_cls2syntax(unsigned int tag, unsigned int cls, unsigned short *syntax) { - struct snmp_cnv *cnv; + const struct snmp_cnv *cnv; cnv = snmp_conv; @@ -728,6 +742,7 @@ static unsigned char snmp_object_decode(struct asn1_ctx *ctx, *obj = kmalloc(sizeof(struct snmp_object) + len, GFP_ATOMIC); if (*obj == NULL) { + kfree(p); kfree(id); if (net_ratelimit()) printk("OOM in bsalg (%d)\n", __LINE__); @@ -903,7 +918,7 @@ static inline void mangle_address(unsigned char *begin, u_int32_t old; if (debug) - memcpy(&old, (unsigned char *)addr, sizeof(old)); + memcpy(&old, addr, sizeof(old)); *addr = map->to; @@ -998,7 +1013,7 @@ err_id_free: * *****************************************************************************/ -static void hex_dump(unsigned char *buf, size_t len) +static void hex_dump(const unsigned char *buf, size_t len) { size_t i; @@ -1079,7 +1094,7 @@ static int snmp_parse_mangle(unsigned char *msg, if (cls != ASN1_CTX || con != ASN1_CON) return 0; if (debug > 1) { - unsigned char *pdus[] = { + static const unsigned char *const pdus[] = { [SNMP_PDU_GET] = "get", [SNMP_PDU_NEXT] = "get-next", [SNMP_PDU_RESPONSE] = "response", @@ -1231,8 +1246,8 @@ static int help(struct sk_buff *skb, unsigned int protoff, { int dir = CTINFO2DIR(ctinfo); unsigned int ret; - struct iphdr *iph = ip_hdr(skb); - struct udphdr *udph = (struct udphdr *)((u_int32_t *)iph + iph->ihl); + const struct iphdr *iph = ip_hdr(skb); + const struct udphdr *udph = (struct udphdr *)((__be32 *)iph + iph->ihl); /* SNMP replies and originating SNMP traps get mangled */ if (udph->source == htons(SNMP_PORT) && dir != IP_CT_DIR_REPLY) @@ -1267,11 +1282,15 @@ static int help(struct sk_buff *skb, unsigned int protoff, return ret; } +static const struct nf_conntrack_expect_policy snmp_exp_policy = { + .max_expected = 0, + .timeout = 180, +}; + static struct nf_conntrack_helper snmp_helper __read_mostly = { - .max_expected = 0, - .timeout = 180, .me = THIS_MODULE, .help = help, + .expect_policy = &snmp_exp_policy, .name = "snmp", .tuple.src.l3num = AF_INET, .tuple.src.u.udp.port = __constant_htons(SNMP_PORT), @@ -1279,10 +1298,9 @@ static struct nf_conntrack_helper snmp_helper __read_mostly = { }; static struct nf_conntrack_helper snmp_trap_helper __read_mostly = { - .max_expected = 0, - .timeout = 180, .me = THIS_MODULE, .help = help, + .expect_policy = &snmp_exp_policy, .name = "snmp_trap", .tuple.src.l3num = AF_INET, .tuple.src.u.udp.port = __constant_htons(SNMP_TRAP_PORT),