Setting tag linux-2.6-32-36
[linux-2.6.git] / linux-2.6-523-raw-sockets.patch
1 From bd4f158ca795506569b503210e667dfd192c011e Mon Sep 17 00:00:00 2001
2 From: S.Çağlar Onur <caglar@cs.princeton.edu>
3 Date: Tue, 7 Dec 2010 11:07:12 -0500
4 Subject: [PATCH] linux-2.6-523-raw-sockets.patch
5
6 ---
7  include/linux/vserver/network.h |    2 ++
8  net/core/sock.c                 |   15 ++++++++++++++-
9  net/ipv4/af_inet.c              |    3 +++
10  net/ipv4/ip_options.c           |    6 +++---
11  net/ipv4/raw.c                  |   13 +++++++------
12  5 files changed, 29 insertions(+), 10 deletions(-)
13
14 diff --git a/include/linux/vserver/network.h b/include/linux/vserver/network.h
15 index 1775630..86715c2 100644
16 --- a/include/linux/vserver/network.h
17 +++ b/include/linux/vserver/network.h
18 @@ -47,6 +47,8 @@ static inline uint64_t __nxf_init_set(void) {
19  #define NXC_TUN_CREATE         0x00000001
20  
21  #define NXC_RAW_ICMP           0x00000100
22 +#define NXC_RAW_SOCKET         0x00000200
23 +#define NXC_RAW_SEND           0x00000400
24  
25  
26  /* address types */
27 diff --git a/net/core/sock.c b/net/core/sock.c
28 index 53cb689..4638715 100644
29 --- a/net/core/sock.c
30 +++ b/net/core/sock.c
31 @@ -401,7 +401,7 @@ static int sock_bindtodevice(struct sock *sk, char __user *optval, int optlen)
32  
33         /* Sorry... */
34         ret = -EPERM;
35 -       if (!capable(CAP_NET_RAW))
36 +       if (!nx_capable(CAP_NET_RAW, NXC_RAW_SOCKET))
37                 goto out;
38  
39         ret = -EINVAL;
40 @@ -537,6 +537,19 @@ set_sndbuf:
41                 }
42                 goto set_sndbuf;
43  
44 +       case SO_SETXID:
45 +               if (current_vx_info()) {
46 +                       ret = -EPERM;
47 +                       break;
48 +               }
49 +               if (val < 0 || val > MAX_S_CONTEXT) {
50 +                       ret = -EINVAL;
51 +                       break;
52 +               }
53 +               sk->sk_xid = val;
54 +               sk->sk_nid = val;
55 +               break;
56 +
57         case SO_RCVBUF:
58                 /* Don't error on this BSD doesn't and if you think
59                    about it this is right. Otherwise apps have to
60 diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
61 index 9e8942b..1c0b4a5 100644
62 --- a/net/ipv4/af_inet.c
63 +++ b/net/ipv4/af_inet.c
64 @@ -332,6 +332,9 @@ lookup_protocol:
65         if ((protocol == IPPROTO_ICMP) &&
66                 nx_capable(CAP_NET_RAW, NXC_RAW_ICMP))
67                 goto override;
68 +       if (sock->type == SOCK_RAW &&
69 +               nx_capable(CAP_NET_RAW, NXC_RAW_SOCKET))
70 +               goto override;
71         if (sock->type == SOCK_RAW && !kern && !capable(CAP_NET_RAW))
72                 goto out_rcu_unlock;
73  
74 diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c
75 index 94bf105..dc81f1c 100644
76 --- a/net/ipv4/ip_options.c
77 +++ b/net/ipv4/ip_options.c
78 @@ -397,7 +397,7 @@ int ip_options_compile(struct net *net,
79                                         optptr[2] += 8;
80                                         break;
81                                       default:
82 -                                       if (!skb && !capable(CAP_NET_RAW)) {
83 +                                       if (!skb && !nx_capable(CAP_NET_RAW, NXC_RAW_SOCKET)) {
84                                                 pp_ptr = optptr + 3;
85                                                 goto error;
86                                         }
87 @@ -433,7 +433,7 @@ int ip_options_compile(struct net *net,
88                                 opt->router_alert = optptr - iph;
89                         break;
90                       case IPOPT_CIPSO:
91 -                       if ((!skb && !capable(CAP_NET_RAW)) || opt->cipso) {
92 +                       if ((!skb && !nx_capable(CAP_NET_RAW, NXC_RAW_SOCKET)) || opt->cipso) {
93                                 pp_ptr = optptr;
94                                 goto error;
95                         }
96 @@ -446,7 +446,7 @@ int ip_options_compile(struct net *net,
97                       case IPOPT_SEC:
98                       case IPOPT_SID:
99                       default:
100 -                       if (!skb && !capable(CAP_NET_RAW)) {
101 +                       if (!skb && !nx_capable(CAP_NET_RAW, NXC_RAW_SOCKET)) {
102                                 pp_ptr = optptr;
103                                 goto error;
104                         }
105 diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
106 index 8913f67..3583cba 100644
107 --- a/net/ipv4/raw.c
108 +++ b/net/ipv4/raw.c
109 @@ -108,7 +108,7 @@ void raw_unhash_sk(struct sock *sk)
110  EXPORT_SYMBOL_GPL(raw_unhash_sk);
111  
112  static struct sock *__raw_v4_lookup(struct net *net, struct sock *sk,
113 -               unsigned short num, __be32 raddr, __be32 laddr, int dif)
114 +               unsigned short num, __be32 raddr, __be32 laddr, int dif, int tag)
115  {
116         struct hlist_node *node;
117  
118 @@ -117,6 +117,7 @@ static struct sock *__raw_v4_lookup(struct net *net, struct sock *sk,
119  
120                 if (net_eq(sock_net(sk), net) && inet->num == num       &&
121                     !(inet->daddr && inet->daddr != raddr)              &&
122 +                   (!sk->sk_nx_info || tag == 1 || sk->sk_nid == tag)  &&
123                     v4_sock_addr_match(sk->sk_nx_info, inet, laddr)     &&
124                     !(sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif))
125                         goto found; /* gotcha */
126 @@ -169,7 +170,7 @@ static int raw_v4_input(struct sk_buff *skb, struct iphdr *iph, int hash)
127         net = dev_net(skb->dev);
128         sk = __raw_v4_lookup(net, __sk_head(head), iph->protocol,
129                              iph->saddr, iph->daddr,
130 -                            skb->dev->ifindex);
131 +                            skb->dev->ifindex, skb->skb_tag);
132  
133         while (sk) {
134                 delivered = 1;
135 @@ -182,7 +183,7 @@ static int raw_v4_input(struct sk_buff *skb, struct iphdr *iph, int hash)
136                 }
137                 sk = __raw_v4_lookup(net, sk_next(sk), iph->protocol,
138                                      iph->saddr, iph->daddr,
139 -                                    skb->dev->ifindex);
140 +                                    skb->dev->ifindex, skb->skb_tag);
141         }
142  out:
143         read_unlock(&raw_v4_hashinfo.lock);
144 @@ -277,8 +278,8 @@ void raw_icmp_error(struct sk_buff *skb, int protocol, u32 info)
145                 net = dev_net(skb->dev);
146  
147                 while ((raw_sk = __raw_v4_lookup(net, raw_sk, protocol,
148 -                                               iph->daddr, iph->saddr,
149 -                                               skb->dev->ifindex)) != NULL) {
150 +                       iph->daddr, iph->saddr, skb->dev->ifindex,
151 +                       skb->skb_tag)) != NULL) {
152                         raw_err(raw_sk, skb, info);
153                         raw_sk = sk_next(raw_sk);
154                         iph = (struct iphdr *)skb->data;
155 @@ -384,7 +385,7 @@ static int raw_send_hdrinc(struct sock *sk, void *from, size_t length,
156                         skb_transport_header(skb))->type);
157  
158         err = -EPERM;
159 -       if (!nx_check(0, VS_ADMIN) && !capable(CAP_NET_RAW) &&
160 +       if (!nx_check(0, VS_ADMIN) && !nx_capable(CAP_NET_RAW, NXC_RAW_SOCKET) &&
161                 sk->sk_nx_info &&
162                 !v4_addr_in_nx_info(sk->sk_nx_info, iph->saddr, NXA_MASK_BIND))
163                 goto error_free;
164 -- 
165 1.5.4.3
166