From ef5cb9738b488140eb6c3f32fffab08f39a4905e Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Tue, 18 Apr 2006 13:24:14 -0700 Subject: [TCP]: Fix truesize underflow There is a problem with the TSO packet trimming code. The cause of this lies in the tcp_fragment() function. When we allocate a fragment for a completely non-linear packet the truesize is calculated for a payload length of zero. This means that truesize could in fact be less than the real payload length. When that happens the TSO packet trimming can cause truesize to become negative. This in turn can cause sk_forward_alloc to be -n * PAGE_SIZE which would trigger the warning. I've copied the code DaveM used in tso_fragment which should work here. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- net/ipv4/tcp_output.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'net') diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index b871db6adc55..44df1db726a3 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -551,7 +551,9 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len, unsigned int mss buff = sk_stream_alloc_skb(sk, nsize, GFP_ATOMIC); if (buff == NULL) return -ENOMEM; /* We'll just try again later. */ - sk_charge_skb(sk, buff); + + buff->truesize = skb->len - len; + skb->truesize -= buff->truesize; /* Correct the sequence numbers. */ TCP_SKB_CB(buff)->seq = TCP_SKB_CB(skb)->seq + len; -- cgit v1.2.2 From ec6700958a776a83681ecb11239c0525730c42ba Mon Sep 17 00:00:00 2001 From: YOSHIFUJI Hideaki Date: Tue, 18 Apr 2006 14:46:26 -0700 Subject: [IPV6]: Ensure to have hop-by-hop options in our header of &sk_buff. Signed-off-by: YOSHIFUJI Hideaki Signed-off-by: David S. Miller --- net/ipv6/exthdrs.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'net') diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c index 2a1e7e45b890..d88cab7b973f 100644 --- a/net/ipv6/exthdrs.c +++ b/net/ipv6/exthdrs.c @@ -489,6 +489,18 @@ int ipv6_parse_hopopts(struct sk_buff *skb, int nhoff) { struct inet6_skb_parm *opt = IP6CB(skb); + /* + * skb->nh.raw is equal to skb->data, and + * skb->h.raw - skb->nh.raw is always equal to + * sizeof(struct ipv6hdr) by definition of + * hop-by-hop options. + */ + if (!pskb_may_pull(skb, sizeof(struct ipv6hdr) + 8) || + !pskb_may_pull(skb, sizeof(struct ipv6hdr) + ((skb->h.raw[1] + 1) << 3))) { + kfree_skb(skb); + return -1; + } + opt->hop = sizeof(struct ipv6hdr); if (ip6_parse_tlv(tlvprochopopt_lst, skb)) { skb->h.raw += (skb->h.raw[1]+1)<<3; -- cgit v1.2.2 From e3cae904d7df4f86ea1d13d459e667d389cc35e3 Mon Sep 17 00:00:00 2001 From: YOSHIFUJI Hideaki Date: Tue, 18 Apr 2006 14:46:52 -0700 Subject: [IPV6] XFRM: Don't use old copy of pointer after pskb_may_pull(). Signed-off-by: YOSHIFUJI Hideaki Signed-off-by: David S. Miller --- net/ipv6/xfrm6_policy.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'net') diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index 91cce8b2d7a5..588922bd9264 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c @@ -193,7 +193,7 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl) { u16 offset = sizeof(struct ipv6hdr); struct ipv6hdr *hdr = skb->nh.ipv6h; - struct ipv6_opt_hdr *exthdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset); + struct ipv6_opt_hdr *exthdr; u8 nexthdr = skb->nh.ipv6h->nexthdr; memset(fl, 0, sizeof(struct flowi)); @@ -201,6 +201,8 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl) ipv6_addr_copy(&fl->fl6_src, &hdr->saddr); while (pskb_may_pull(skb, skb->nh.raw + offset + 1 - skb->data)) { + exthdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset); + switch (nexthdr) { case NEXTHDR_ROUTING: case NEXTHDR_HOP: -- cgit v1.2.2 From e5d25a90886d62d88fdd7cd5c3375f4fe436be64 Mon Sep 17 00:00:00 2001 From: YOSHIFUJI Hideaki Date: Tue, 18 Apr 2006 14:47:44 -0700 Subject: [IPV6] XFRM: Fix decoding session with preceding extension header(s). We did not correctly decode session with preceding extension header(s). This was because we had already pulled preceding headers, skb->nh.raw + 40 + 1 - skb->data was minus, and pskb_may_pull() failed. We now have IP6CB(skb)->nhoff and skb->h.raw, and we can start parsing / decoding upper layer protocol from current position. Tracked down by Noriaki TAKAMIYA and tested by Kazunori Miyazawa . Signed-off-by: YOSHIFUJI Hideaki Signed-off-by: David S. Miller --- net/ipv6/xfrm6_policy.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'net') diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index 588922bd9264..88c840f1beb6 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c @@ -191,10 +191,10 @@ error: static inline void _decode_session6(struct sk_buff *skb, struct flowi *fl) { - u16 offset = sizeof(struct ipv6hdr); + u16 offset = skb->h.raw - skb->nh.raw; struct ipv6hdr *hdr = skb->nh.ipv6h; struct ipv6_opt_hdr *exthdr; - u8 nexthdr = skb->nh.ipv6h->nexthdr; + u8 nexthdr = skb->nh.raw[IP6CB(skb)->nhoff]; memset(fl, 0, sizeof(struct flowi)); ipv6_addr_copy(&fl->fl6_dst, &hdr->daddr); -- cgit v1.2.2 From b809739a1b455396c21de13bcbf6669faf82f747 Mon Sep 17 00:00:00 2001 From: YOSHIFUJI Hideaki Date: Tue, 18 Apr 2006 14:48:45 -0700 Subject: [IPV6]: Clean up hop-by-hop options handler. - Removed unused argument (nhoff) for ipv6_parse_hopopts(). - Make ipv6_parse_hopopts() to align with other extension header handlers. - Removed pointless assignment (hdr), which is not used afterwards. Signed-off-by: YOSHIFUJI Hideaki Signed-off-by: David S. Miller --- net/ipv6/exthdrs.c | 4 ++-- net/ipv6/ip6_input.c | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) (limited to 'net') diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c index d88cab7b973f..a18d4256372c 100644 --- a/net/ipv6/exthdrs.c +++ b/net/ipv6/exthdrs.c @@ -485,7 +485,7 @@ static struct tlvtype_proc tlvprochopopt_lst[] = { { -1, } }; -int ipv6_parse_hopopts(struct sk_buff *skb, int nhoff) +int ipv6_parse_hopopts(struct sk_buff *skb) { struct inet6_skb_parm *opt = IP6CB(skb); @@ -505,7 +505,7 @@ int ipv6_parse_hopopts(struct sk_buff *skb, int nhoff) if (ip6_parse_tlv(tlvprochopopt_lst, skb)) { skb->h.raw += (skb->h.raw[1]+1)<<3; opt->nhoff = sizeof(struct ipv6hdr); - return sizeof(struct ipv6hdr); + return 1; } return -1; } diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c index 29f73592e68e..aceee252503d 100644 --- a/net/ipv6/ip6_input.c +++ b/net/ipv6/ip6_input.c @@ -114,11 +114,10 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt } if (hdr->nexthdr == NEXTHDR_HOP) { - if (ipv6_parse_hopopts(skb, IP6CB(skb)->nhoff) < 0) { + if (ipv6_parse_hopopts(skb) < 0) { IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); return 0; } - hdr = skb->nh.ipv6h; } return NF_HOOK(PF_INET6,NF_IP6_PRE_ROUTING, skb, dev, NULL, ip6_rcv_finish); -- cgit v1.2.2 From 40daafc80b0f6a950c9252f9f1a242ab5cb6a648 Mon Sep 17 00:00:00 2001 From: Dmitry Mishin Date: Tue, 18 Apr 2006 14:50:10 -0700 Subject: unaligned access in sk_run_filter() This patch fixes unaligned access warnings noticed on IA64 in sk_run_filter(). 'ptr' can be unaligned. Signed-off-By: Dmitry Mishin Signed-off-By: Kirill Korotaev Signed-off-by: David S. Miller --- net/core/filter.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'net') diff --git a/net/core/filter.c b/net/core/filter.c index 93fbd01d2259..5b4486a60cf6 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -34,6 +34,7 @@ #include #include #include +#include #include /* No hurry in this branch */ @@ -177,7 +178,7 @@ unsigned int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int load_w: ptr = load_pointer(skb, k, 4, &tmp); if (ptr != NULL) { - A = ntohl(*(u32 *)ptr); + A = ntohl(get_unaligned((u32 *)ptr)); continue; } break; @@ -186,7 +187,7 @@ load_w: load_h: ptr = load_pointer(skb, k, 2, &tmp); if (ptr != NULL) { - A = ntohs(*(u16 *)ptr); + A = ntohs(get_unaligned((u16 *)ptr)); continue; } break; -- cgit v1.2.2 From 63903ca6af3d9424a0c2b176f927fa7e7ab2ae8e Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Tue, 18 Apr 2006 14:51:44 -0700 Subject: [NET]: Remove redundant NULL checks before [kv]free Redundant NULL check before kfree removal from net/ Signed-off-by: Jesper Juhl Acked-by: James Morris Signed-off-by: David S. Miller --- net/ipv4/ipcomp.c | 7 ++----- net/tipc/name_distr.c | 3 +-- 2 files changed, 3 insertions(+), 7 deletions(-) (limited to 'net') diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c index 04a429465665..cd810f41af1a 100644 --- a/net/ipv4/ipcomp.c +++ b/net/ipv4/ipcomp.c @@ -290,11 +290,8 @@ static void ipcomp_free_scratches(void) if (!scratches) return; - for_each_possible_cpu(i) { - void *scratch = *per_cpu_ptr(scratches, i); - if (scratch) - vfree(scratch); - } + for_each_possible_cpu(i) + vfree(*per_cpu_ptr(scratches, i)); free_percpu(scratches); } diff --git a/net/tipc/name_distr.c b/net/tipc/name_distr.c index 953307a9df1d..a3bbc891f959 100644 --- a/net/tipc/name_distr.c +++ b/net/tipc/name_distr.c @@ -229,8 +229,7 @@ static void node_is_down(struct publication *publ) publ->node, publ->ref, publ->key); assert(p == publ); write_unlock_bh(&tipc_nametbl_lock); - if (publ) - kfree(publ); + kfree(publ); } /** -- cgit v1.2.2 From d4a30e7e66c004da26dfe5229af7c10fe9853a7a Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Tue, 18 Apr 2006 13:14:02 -0400 Subject: RPCSEC_GSS: fix leak in krb5 code caused by superfluous kmalloc I was sloppy when generating a previous patch; I modified the callers of krb5_make_checksum() to allocate memory for the buffer where the result is returned, then forgot to modify krb5_make_checksum to stop allocating that memory itself. The result is a per-packet memory leak. This fixes the problem by removing the now-superfluous kmalloc(). Signed-off-by: J. Bruce Fields Signed-off-by: Trond Myklebust --- net/sunrpc/auth_gss/gss_krb5_crypto.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'net') diff --git a/net/sunrpc/auth_gss/gss_krb5_crypto.c b/net/sunrpc/auth_gss/gss_krb5_crypto.c index 97c981fa6b8e..76b969e6904f 100644 --- a/net/sunrpc/auth_gss/gss_krb5_crypto.c +++ b/net/sunrpc/auth_gss/gss_krb5_crypto.c @@ -212,7 +212,6 @@ make_checksum(s32 cksumtype, char *header, int hdrlen, struct xdr_buf *body, char *cksumname; struct crypto_tfm *tfm = NULL; /* XXX add to ctx? */ struct scatterlist sg[1]; - u32 code = GSS_S_FAILURE; switch (cksumtype) { case CKSUMTYPE_RSA_MD5: @@ -221,13 +220,11 @@ make_checksum(s32 cksumtype, char *header, int hdrlen, struct xdr_buf *body, default: dprintk("RPC: krb5_make_checksum:" " unsupported checksum %d", cksumtype); - goto out; + return GSS_S_FAILURE; } if (!(tfm = crypto_alloc_tfm(cksumname, CRYPTO_TFM_REQ_MAY_SLEEP))) - goto out; + return GSS_S_FAILURE; cksum->len = crypto_tfm_alg_digestsize(tfm); - if ((cksum->data = kmalloc(cksum->len, GFP_KERNEL)) == NULL) - goto out; crypto_digest_init(tfm); sg_set_buf(sg, header, hdrlen); @@ -235,10 +232,8 @@ make_checksum(s32 cksumtype, char *header, int hdrlen, struct xdr_buf *body, process_xdr_buf(body, body_offset, body->len - body_offset, checksummer, tfm); crypto_digest_final(tfm, cksum->data); - code = 0; -out: crypto_free_tfm(tfm); - return code; + return 0; } EXPORT_SYMBOL(make_checksum); -- cgit v1.2.2 From ec535ce154f2eaad3d97f2f20a76a6d8bdac33e5 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Tue, 18 Apr 2006 13:21:50 -0400 Subject: NFS: make 2 functions static Signed-off-by: Adrian Bunk Cc: Trond Myklebust Signed-off-by: Andrew Morton Signed-off-by: Trond Myklebust --- net/sunrpc/stats.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'net') diff --git a/net/sunrpc/stats.c b/net/sunrpc/stats.c index dea529666d69..15c2db26767b 100644 --- a/net/sunrpc/stats.c +++ b/net/sunrpc/stats.c @@ -176,7 +176,8 @@ void rpc_count_iostats(struct rpc_task *task) op_metrics->om_execute += execute; } -void _print_name(struct seq_file *seq, unsigned int op, struct rpc_procinfo *procs) +static void _print_name(struct seq_file *seq, unsigned int op, + struct rpc_procinfo *procs) { if (procs[op].p_name) seq_printf(seq, "\t%12s: ", procs[op].p_name); -- cgit v1.2.2 From a5f9145bc9c340bda743ad51e09bdea60fa3ddfa Mon Sep 17 00:00:00 2001 From: Eric Sesterhenn Date: Wed, 19 Apr 2006 13:06:49 -0400 Subject: SUNRPC: Dead code in net/sunrpc/auth_gss/auth_gss.c Hi, the coverity checker spotted that cred is always NULL when we jump to out_err ( there is just one case, when we fail to allocate the memory for cred ) This is Coverity ID #79 Signed-off-by: Eric Sesterhenn Signed-off-by: Trond Myklebust --- net/sunrpc/auth_gss/auth_gss.c | 1 - 1 file changed, 1 deletion(-) (limited to 'net') diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index 900ef31f5a0e..519ebc17c028 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c @@ -794,7 +794,6 @@ gss_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags) out_err: dprintk("RPC: gss_create_cred failed with error %d\n", err); - if (cred) gss_destroy_cred(&cred->gc_base); return ERR_PTR(err); } -- cgit v1.2.2