--- zzzz-none-000/linux-2.6.19.2/net/ipv4/udp.c 2007-01-10 19:10:37.000000000 +0000 +++ davinci-8020-5505/linux-2.6.19.2/net/ipv4/udp.c 2007-01-19 15:11:30.000000000 +0000 @@ -101,6 +101,7 @@ #include #include #include +#include #include #include #include @@ -109,6 +110,12 @@ #include #include +extern int gr_search_udp_recvmsg(const struct sock *sk, + const struct sk_buff *skb); +extern int gr_search_udp_sendmsg(const struct sock *sk, + const struct sockaddr_in *addr); + + /* * Snmp MIB for the UDP layer */ @@ -291,8 +298,8 @@ return result; } -static __inline__ struct sock *udp_v4_lookup(__be32 saddr, __be16 sport, - __be32 daddr, __be16 dport, int dif) +struct sock *udp_v4_lookup(__be32 saddr, __be16 sport, + __be32 daddr, __be16 dport, int dif) { struct sock *sk; @@ -567,9 +574,16 @@ dport = usin->sin_port; if (dport == 0) return -EINVAL; + + if (!gr_search_udp_sendmsg(sk, usin)) + return -EPERM; } else { if (sk->sk_state != TCP_ESTABLISHED) return -EDESTADDRREQ; + + if (!gr_search_udp_sendmsg(sk, NULL)) + return -EPERM; + daddr = inet->daddr; dport = inet->dport; /* Open fast path for connected socket. @@ -836,6 +850,11 @@ if (!skb) goto out; + if (!gr_search_udp_recvmsg(sk, skb)) { + err = -EPERM; + goto out_free; + } + copied = skb->len - sizeof(struct udphdr); if (copied > len) { copied = len; @@ -931,32 +950,23 @@ return 1; #else struct udp_sock *up = udp_sk(sk); - struct udphdr *uh; + struct udphdr *uh = skb->h.uh; struct iphdr *iph; int iphlen, len; - __u8 *udpdata; - __be32 *udpdata32; + __u8 *udpdata = (__u8 *)uh + sizeof(struct udphdr); + __be32 *udpdata32 = (__be32 *)udpdata; __u16 encap_type = up->encap_type; /* if we're overly short, let UDP handle it */ - len = skb->len - sizeof(struct udphdr); - if (len <= 0) + if (udpdata > skb->tail) return 1; /* if this is not encapsulated socket, then just return now */ if (!encap_type) return 1; - /* If this is a paged skb, make sure we pull up - * whatever data we need to look at. */ - if (!pskb_may_pull(skb, sizeof(struct udphdr) + min(len, 8))) - return 1; - - /* Now we can get the pointers */ - uh = skb->h.uh; - udpdata = (__u8 *)uh + sizeof(struct udphdr); - udpdata32 = (__be32 *)udpdata; + len = skb->tail - udpdata; switch (encap_type) { default: