add linux-2.6-523-raw-sockets.patch
S.Çağlar Onur [Thu, 29 Apr 2010 17:55:56 +0000 (17:55 +0000)]
kernel.spec
linux-2.6-523-raw-sockets.patch [new file with mode: 0644]

index 028efda..6864f9d 100644 (file)
@@ -1854,6 +1854,10 @@ Patch88888: patch-2.6.32-19.el6-vs2.3.0.36.29.4.diff
 Patch90250: linux-2.6-250-ipsets.patch
 Patch90510: linux-2.6-510-ipod.patch
 Patch90521: linux-2.6-521-packet-tagging.patch
+#
+#Patch90522: linux-2.6-522-iptables-connection-tagging.patch
+#
+Patch90523: linux-2.6-523-raw-sockets.patch
 
 # empty final patch file to facilitate testing of kernel patches
 Patch99999: linux-kernel-test.patch
@@ -3475,6 +3479,10 @@ ApplyPatch patch-2.6.32-19.el6-vs2.3.0.36.29.4.diff
 ApplyPatch linux-2.6-250-ipsets.patch
 ApplyPatch linux-2.6-510-ipod.patch
 ApplyPatch linux-2.6-521-packet-tagging.patch
+#
+#ApplyPatch linux-2.6-522-iptables-connection-tagging.patch
+#
+ApplyPatch linux-2.6-523-raw-sockets.patch
 
 ApplyOptionalPatch linux-kernel-test.patch
 
diff --git a/linux-2.6-523-raw-sockets.patch b/linux-2.6-523-raw-sockets.patch
new file mode 100644 (file)
index 0000000..8059e78
--- /dev/null
@@ -0,0 +1,150 @@
+diff --git a/include/linux/vserver/network.h b/include/linux/vserver/network.h
+index 1775630..86715c2 100644
+--- a/include/linux/vserver/network.h
++++ b/include/linux/vserver/network.h
+@@ -47,6 +47,8 @@ static inline uint64_t __nxf_init_set(void) {
+ #define NXC_TUN_CREATE                0x00000001
+ #define NXC_RAW_ICMP          0x00000100
++#define NXC_RAW_SOCKET                0x00000200
++#define NXC_RAW_SEND          0x00000400
+ /* address types */
+diff --git a/net/core/sock.c b/net/core/sock.c
+index d276d4b..ac135b9 100644
+--- a/net/core/sock.c
++++ b/net/core/sock.c
+@@ -395,7 +395,7 @@ static int sock_bindtodevice(struct sock *sk, char __user *optval, int optlen)
+       /* Sorry... */
+       ret = -EPERM;
+-      if (!capable(CAP_NET_RAW))
++      if (!nx_capable(CAP_NET_RAW, NXC_RAW_SOCKET))
+               goto out;
+       ret = -EINVAL;
+@@ -531,6 +531,19 @@ set_sndbuf:
+               }
+               goto set_sndbuf;
++      case SO_SETXID:
++              if (current_vx_info()) {
++                      ret = -EPERM;
++                      break;
++              }
++              if (val < 0 || val > MAX_S_CONTEXT) {
++                      ret = -EINVAL;
++                      break;
++              }
++              sk->sk_xid = val;
++              sk->sk_nid = val;
++              break;
++
+       case SO_RCVBUF:
+               /* Don't error on this BSD doesn't and if you think
+                  about it this is right. Otherwise apps have to
+diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
+index 026c3b1..1e9b53c 100644
+--- a/net/ipv4/af_inet.c
++++ b/net/ipv4/af_inet.c
+@@ -332,6 +332,9 @@ lookup_protocol:
+       if ((protocol == IPPROTO_ICMP) &&
+               nx_capable(CAP_NET_RAW, NXC_RAW_ICMP))
+               goto override;
++      if (sock->type == SOCK_RAW &&
++              nx_capable(CAP_NET_RAW, NXC_RAW_SOCKET))
++              goto override;
+       if (sock->type == SOCK_RAW && !kern && !capable(CAP_NET_RAW))
+               goto out_rcu_unlock;
+ override:
+diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c
+index 94bf105..dc81f1c 100644
+--- a/net/ipv4/ip_options.c
++++ b/net/ipv4/ip_options.c
+@@ -397,7 +397,7 @@ int ip_options_compile(struct net *net,
+                                       optptr[2] += 8;
+                                       break;
+                                     default:
+-                                      if (!skb && !capable(CAP_NET_RAW)) {
++                                      if (!skb && !nx_capable(CAP_NET_RAW, NXC_RAW_SOCKET)) {
+                                               pp_ptr = optptr + 3;
+                                               goto error;
+                                       }
+@@ -433,7 +433,7 @@ int ip_options_compile(struct net *net,
+                               opt->router_alert = optptr - iph;
+                       break;
+                     case IPOPT_CIPSO:
+-                      if ((!skb && !capable(CAP_NET_RAW)) || opt->cipso) {
++                      if ((!skb && !nx_capable(CAP_NET_RAW, NXC_RAW_SOCKET)) || opt->cipso) {
+                               pp_ptr = optptr;
+                               goto error;
+                       }
+@@ -446,7 +446,7 @@ int ip_options_compile(struct net *net,
+                     case IPOPT_SEC:
+                     case IPOPT_SID:
+                     default:
+-                      if (!skb && !capable(CAP_NET_RAW)) {
++                      if (!skb && !nx_capable(CAP_NET_RAW, NXC_RAW_SOCKET)) {
+                               pp_ptr = optptr;
+                               goto error;
+                       }
+diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
+index 8913f67..3583cba 100644
+--- a/net/ipv4/raw.c
++++ b/net/ipv4/raw.c
+@@ -108,7 +108,7 @@ void raw_unhash_sk(struct sock *sk)
+ EXPORT_SYMBOL_GPL(raw_unhash_sk);
+ static struct sock *__raw_v4_lookup(struct net *net, struct sock *sk,
+-              unsigned short num, __be32 raddr, __be32 laddr, int dif)
++              unsigned short num, __be32 raddr, __be32 laddr, int dif, int tag)
+ {
+       struct hlist_node *node;
+@@ -117,6 +117,7 @@ static struct sock *__raw_v4_lookup(struct net *net, struct sock *sk,
+               if (net_eq(sock_net(sk), net) && inet->num == num       &&
+                   !(inet->daddr && inet->daddr != raddr)              &&
++                  (!sk->sk_nx_info || tag == 1 || sk->sk_nid == tag)  &&
+                   v4_sock_addr_match(sk->sk_nx_info, inet, laddr)     &&
+                   !(sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif))
+                       goto found; /* gotcha */
+@@ -169,7 +170,7 @@ static int raw_v4_input(struct sk_buff *skb, struct iphdr *iph, int hash)
+       net = dev_net(skb->dev);
+       sk = __raw_v4_lookup(net, __sk_head(head), iph->protocol,
+                            iph->saddr, iph->daddr,
+-                           skb->dev->ifindex);
++                           skb->dev->ifindex, skb->skb_tag);
+       while (sk) {
+               delivered = 1;
+@@ -182,7 +183,7 @@ static int raw_v4_input(struct sk_buff *skb, struct iphdr *iph, int hash)
+               }
+               sk = __raw_v4_lookup(net, sk_next(sk), iph->protocol,
+                                    iph->saddr, iph->daddr,
+-                                   skb->dev->ifindex);
++                                   skb->dev->ifindex, skb->skb_tag);
+       }
+ out:
+       read_unlock(&raw_v4_hashinfo.lock);
+@@ -277,8 +278,8 @@ void raw_icmp_error(struct sk_buff *skb, int protocol, u32 info)
+               net = dev_net(skb->dev);
+               while ((raw_sk = __raw_v4_lookup(net, raw_sk, protocol,
+-                                              iph->daddr, iph->saddr,
+-                                              skb->dev->ifindex)) != NULL) {
++                      iph->daddr, iph->saddr, skb->dev->ifindex,
++                      skb->skb_tag)) != NULL) {
+                       raw_err(raw_sk, skb, info);
+                       raw_sk = sk_next(raw_sk);
+                       iph = (struct iphdr *)skb->data;
+@@ -384,7 +385,7 @@ static int raw_send_hdrinc(struct sock *sk, void *from, size_t length,
+                       skb_transport_header(skb))->type);
+       err = -EPERM;
+-      if (!nx_check(0, VS_ADMIN) && !capable(CAP_NET_RAW) &&
++      if (!nx_check(0, VS_ADMIN) && !nx_capable(CAP_NET_RAW, NXC_RAW_SOCKET) &&
+               sk->sk_nx_info &&
+               !v4_addr_in_nx_info(sk->sk_nx_info, iph->saddr, NXA_MASK_BIND))
+               goto error_free;