diff options
Diffstat (limited to 'net')
52 files changed, 432 insertions, 221 deletions
diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c index 0eb96f7e44be..2dcff0be8acb 100644 --- a/net/8021q/vlan_core.c +++ b/net/8021q/vlan_core.c | |||
@@ -43,6 +43,9 @@ int vlan_hwaccel_do_receive(struct sk_buff *skb) | |||
43 | struct net_device *dev = skb->dev; | 43 | struct net_device *dev = skb->dev; |
44 | struct vlan_rx_stats *rx_stats; | 44 | struct vlan_rx_stats *rx_stats; |
45 | 45 | ||
46 | if (unlikely(!is_vlan_dev(dev))) | ||
47 | return 0; | ||
48 | |||
46 | skb->dev = vlan_dev_info(dev)->real_dev; | 49 | skb->dev = vlan_dev_info(dev)->real_dev; |
47 | netif_nit_deliver(skb); | 50 | netif_nit_deliver(skb); |
48 | 51 | ||
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c index cfdfd7e2a172..6e2371a493b7 100644 --- a/net/ax25/af_ax25.c +++ b/net/ax25/af_ax25.c | |||
@@ -1392,6 +1392,7 @@ static int ax25_getname(struct socket *sock, struct sockaddr *uaddr, | |||
1392 | ax25_cb *ax25; | 1392 | ax25_cb *ax25; |
1393 | int err = 0; | 1393 | int err = 0; |
1394 | 1394 | ||
1395 | memset(fsa, 0, sizeof(fsa)); | ||
1395 | lock_sock(sk); | 1396 | lock_sock(sk); |
1396 | ax25 = ax25_sk(sk); | 1397 | ax25 = ax25_sk(sk); |
1397 | 1398 | ||
@@ -1403,7 +1404,6 @@ static int ax25_getname(struct socket *sock, struct sockaddr *uaddr, | |||
1403 | 1404 | ||
1404 | fsa->fsa_ax25.sax25_family = AF_AX25; | 1405 | fsa->fsa_ax25.sax25_family = AF_AX25; |
1405 | fsa->fsa_ax25.sax25_call = ax25->dest_addr; | 1406 | fsa->fsa_ax25.sax25_call = ax25->dest_addr; |
1406 | fsa->fsa_ax25.sax25_ndigis = 0; | ||
1407 | 1407 | ||
1408 | if (ax25->digipeat != NULL) { | 1408 | if (ax25->digipeat != NULL) { |
1409 | ndigi = ax25->digipeat->ndigi; | 1409 | ndigi = ax25->digipeat->ndigi; |
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index 0b54b7dd8401..dc6020570a32 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c | |||
@@ -2891,7 +2891,7 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd | |||
2891 | struct l2cap_chan_list *list = &conn->chan_list; | 2891 | struct l2cap_chan_list *list = &conn->chan_list; |
2892 | struct l2cap_conn_req *req = (struct l2cap_conn_req *) data; | 2892 | struct l2cap_conn_req *req = (struct l2cap_conn_req *) data; |
2893 | struct l2cap_conn_rsp rsp; | 2893 | struct l2cap_conn_rsp rsp; |
2894 | struct sock *parent, *uninitialized_var(sk); | 2894 | struct sock *parent, *sk = NULL; |
2895 | int result, status = L2CAP_CS_NO_INFO; | 2895 | int result, status = L2CAP_CS_NO_INFO; |
2896 | 2896 | ||
2897 | u16 dcid = 0, scid = __le16_to_cpu(req->scid); | 2897 | u16 dcid = 0, scid = __le16_to_cpu(req->scid); |
@@ -3000,7 +3000,7 @@ sendresp: | |||
3000 | L2CAP_INFO_REQ, sizeof(info), &info); | 3000 | L2CAP_INFO_REQ, sizeof(info), &info); |
3001 | } | 3001 | } |
3002 | 3002 | ||
3003 | if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT) && | 3003 | if (sk && !(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT) && |
3004 | result == L2CAP_CR_SUCCESS) { | 3004 | result == L2CAP_CR_SUCCESS) { |
3005 | u8 buf[128]; | 3005 | u8 buf[128]; |
3006 | l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT; | 3006 | l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT; |
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index eb5b256ffc88..f19e347f56f6 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c | |||
@@ -437,7 +437,7 @@ static struct sk_buff *br_ip6_multicast_alloc_query(struct net_bridge *br, | |||
437 | ip6h = ipv6_hdr(skb); | 437 | ip6h = ipv6_hdr(skb); |
438 | 438 | ||
439 | *(__force __be32 *)ip6h = htonl(0x60000000); | 439 | *(__force __be32 *)ip6h = htonl(0x60000000); |
440 | ip6h->payload_len = 8 + sizeof(*mldq); | 440 | ip6h->payload_len = htons(8 + sizeof(*mldq)); |
441 | ip6h->nexthdr = IPPROTO_HOPOPTS; | 441 | ip6h->nexthdr = IPPROTO_HOPOPTS; |
442 | ip6h->hop_limit = 1; | 442 | ip6h->hop_limit = 1; |
443 | ipv6_addr_set(&ip6h->saddr, 0, 0, 0, 0); | 443 | ipv6_addr_set(&ip6h->saddr, 0, 0, 0, 0); |
diff --git a/net/can/bcm.c b/net/can/bcm.c index 08ffe9e4be20..6faa8256e10c 100644 --- a/net/can/bcm.c +++ b/net/can/bcm.c | |||
@@ -125,7 +125,7 @@ struct bcm_sock { | |||
125 | struct list_head tx_ops; | 125 | struct list_head tx_ops; |
126 | unsigned long dropped_usr_msgs; | 126 | unsigned long dropped_usr_msgs; |
127 | struct proc_dir_entry *bcm_proc_read; | 127 | struct proc_dir_entry *bcm_proc_read; |
128 | char procname [9]; /* pointer printed in ASCII with \0 */ | 128 | char procname [20]; /* pointer printed in ASCII with \0 */ |
129 | }; | 129 | }; |
130 | 130 | ||
131 | static inline struct bcm_sock *bcm_sk(const struct sock *sk) | 131 | static inline struct bcm_sock *bcm_sk(const struct sock *sk) |
diff --git a/net/compat.c b/net/compat.c index 63d260e81472..3649d5895361 100644 --- a/net/compat.c +++ b/net/compat.c | |||
@@ -41,10 +41,12 @@ static inline int iov_from_user_compat_to_kern(struct iovec *kiov, | |||
41 | compat_size_t len; | 41 | compat_size_t len; |
42 | 42 | ||
43 | if (get_user(len, &uiov32->iov_len) || | 43 | if (get_user(len, &uiov32->iov_len) || |
44 | get_user(buf, &uiov32->iov_base)) { | 44 | get_user(buf, &uiov32->iov_base)) |
45 | tot_len = -EFAULT; | 45 | return -EFAULT; |
46 | break; | 46 | |
47 | } | 47 | if (len > INT_MAX - tot_len) |
48 | len = INT_MAX - tot_len; | ||
49 | |||
48 | tot_len += len; | 50 | tot_len += len; |
49 | kiov->iov_base = compat_ptr(buf); | 51 | kiov->iov_base = compat_ptr(buf); |
50 | kiov->iov_len = (__kernel_size_t) len; | 52 | kiov->iov_len = (__kernel_size_t) len; |
diff --git a/net/core/dev.c b/net/core/dev.c index 660dd41aaaa6..1dad6c0926f2 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -1648,10 +1648,10 @@ EXPORT_SYMBOL(netif_device_attach); | |||
1648 | 1648 | ||
1649 | static bool can_checksum_protocol(unsigned long features, __be16 protocol) | 1649 | static bool can_checksum_protocol(unsigned long features, __be16 protocol) |
1650 | { | 1650 | { |
1651 | return ((features & NETIF_F_GEN_CSUM) || | 1651 | return ((features & NETIF_F_NO_CSUM) || |
1652 | ((features & NETIF_F_IP_CSUM) && | 1652 | ((features & NETIF_F_V4_CSUM) && |
1653 | protocol == htons(ETH_P_IP)) || | 1653 | protocol == htons(ETH_P_IP)) || |
1654 | ((features & NETIF_F_IPV6_CSUM) && | 1654 | ((features & NETIF_F_V6_CSUM) && |
1655 | protocol == htons(ETH_P_IPV6)) || | 1655 | protocol == htons(ETH_P_IPV6)) || |
1656 | ((features & NETIF_F_FCOE_CRC) && | 1656 | ((features & NETIF_F_FCOE_CRC) && |
1657 | protocol == htons(ETH_P_FCOE))); | 1657 | protocol == htons(ETH_P_FCOE))); |
@@ -2891,6 +2891,15 @@ static int __netif_receive_skb(struct sk_buff *skb) | |||
2891 | ncls: | 2891 | ncls: |
2892 | #endif | 2892 | #endif |
2893 | 2893 | ||
2894 | /* If we got this far with a hardware accelerated VLAN tag, it means | ||
2895 | * that we were put in promiscuous mode but nobody is interested in | ||
2896 | * this vid. Drop the packet now to prevent it from getting propagated | ||
2897 | * to other parts of the stack that won't know how to deal with packets | ||
2898 | * tagged in this manner. | ||
2899 | */ | ||
2900 | if (unlikely(vlan_tx_tag_present(skb))) | ||
2901 | goto bypass; | ||
2902 | |||
2894 | /* Handle special case of bridge or macvlan */ | 2903 | /* Handle special case of bridge or macvlan */ |
2895 | rx_handler = rcu_dereference(skb->dev->rx_handler); | 2904 | rx_handler = rcu_dereference(skb->dev->rx_handler); |
2896 | if (rx_handler) { | 2905 | if (rx_handler) { |
@@ -2927,6 +2936,7 @@ ncls: | |||
2927 | } | 2936 | } |
2928 | } | 2937 | } |
2929 | 2938 | ||
2939 | bypass: | ||
2930 | if (pt_prev) { | 2940 | if (pt_prev) { |
2931 | ret = pt_prev->func(skb, skb->dev, pt_prev, orig_dev); | 2941 | ret = pt_prev->func(skb, skb->dev, pt_prev, orig_dev); |
2932 | } else { | 2942 | } else { |
diff --git a/net/core/dst.c b/net/core/dst.c index 6c41b1fac3db..2844639dfb79 100644 --- a/net/core/dst.c +++ b/net/core/dst.c | |||
@@ -343,6 +343,7 @@ static int dst_dev_event(struct notifier_block *this, unsigned long event, | |||
343 | 343 | ||
344 | static struct notifier_block dst_dev_notifier = { | 344 | static struct notifier_block dst_dev_notifier = { |
345 | .notifier_call = dst_dev_event, | 345 | .notifier_call = dst_dev_event, |
346 | .priority = -10, /* must be called after other network notifiers */ | ||
346 | }; | 347 | }; |
347 | 348 | ||
348 | void __init dst_init(void) | 349 | void __init dst_init(void) |
diff --git a/net/core/filter.c b/net/core/filter.c index 52b051f82a01..71a433cdf7d3 100644 --- a/net/core/filter.c +++ b/net/core/filter.c | |||
@@ -112,39 +112,41 @@ EXPORT_SYMBOL(sk_filter); | |||
112 | */ | 112 | */ |
113 | unsigned int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen) | 113 | unsigned int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen) |
114 | { | 114 | { |
115 | struct sock_filter *fentry; /* We walk down these */ | ||
116 | void *ptr; | 115 | void *ptr; |
117 | u32 A = 0; /* Accumulator */ | 116 | u32 A = 0; /* Accumulator */ |
118 | u32 X = 0; /* Index Register */ | 117 | u32 X = 0; /* Index Register */ |
119 | u32 mem[BPF_MEMWORDS]; /* Scratch Memory Store */ | 118 | u32 mem[BPF_MEMWORDS]; /* Scratch Memory Store */ |
119 | unsigned long memvalid = 0; | ||
120 | u32 tmp; | 120 | u32 tmp; |
121 | int k; | 121 | int k; |
122 | int pc; | 122 | int pc; |
123 | 123 | ||
124 | BUILD_BUG_ON(BPF_MEMWORDS > BITS_PER_LONG); | ||
124 | /* | 125 | /* |
125 | * Process array of filter instructions. | 126 | * Process array of filter instructions. |
126 | */ | 127 | */ |
127 | for (pc = 0; pc < flen; pc++) { | 128 | for (pc = 0; pc < flen; pc++) { |
128 | fentry = &filter[pc]; | 129 | const struct sock_filter *fentry = &filter[pc]; |
130 | u32 f_k = fentry->k; | ||
129 | 131 | ||
130 | switch (fentry->code) { | 132 | switch (fentry->code) { |
131 | case BPF_S_ALU_ADD_X: | 133 | case BPF_S_ALU_ADD_X: |
132 | A += X; | 134 | A += X; |
133 | continue; | 135 | continue; |
134 | case BPF_S_ALU_ADD_K: | 136 | case BPF_S_ALU_ADD_K: |
135 | A += fentry->k; | 137 | A += f_k; |
136 | continue; | 138 | continue; |
137 | case BPF_S_ALU_SUB_X: | 139 | case BPF_S_ALU_SUB_X: |
138 | A -= X; | 140 | A -= X; |
139 | continue; | 141 | continue; |
140 | case BPF_S_ALU_SUB_K: | 142 | case BPF_S_ALU_SUB_K: |
141 | A -= fentry->k; | 143 | A -= f_k; |
142 | continue; | 144 | continue; |
143 | case BPF_S_ALU_MUL_X: | 145 | case BPF_S_ALU_MUL_X: |
144 | A *= X; | 146 | A *= X; |
145 | continue; | 147 | continue; |
146 | case BPF_S_ALU_MUL_K: | 148 | case BPF_S_ALU_MUL_K: |
147 | A *= fentry->k; | 149 | A *= f_k; |
148 | continue; | 150 | continue; |
149 | case BPF_S_ALU_DIV_X: | 151 | case BPF_S_ALU_DIV_X: |
150 | if (X == 0) | 152 | if (X == 0) |
@@ -152,49 +154,49 @@ unsigned int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int | |||
152 | A /= X; | 154 | A /= X; |
153 | continue; | 155 | continue; |
154 | case BPF_S_ALU_DIV_K: | 156 | case BPF_S_ALU_DIV_K: |
155 | A /= fentry->k; | 157 | A /= f_k; |
156 | continue; | 158 | continue; |
157 | case BPF_S_ALU_AND_X: | 159 | case BPF_S_ALU_AND_X: |
158 | A &= X; | 160 | A &= X; |
159 | continue; | 161 | continue; |
160 | case BPF_S_ALU_AND_K: | 162 | case BPF_S_ALU_AND_K: |
161 | A &= fentry->k; | 163 | A &= f_k; |
162 | continue; | 164 | continue; |
163 | case BPF_S_ALU_OR_X: | 165 | case BPF_S_ALU_OR_X: |
164 | A |= X; | 166 | A |= X; |
165 | continue; | 167 | continue; |
166 | case BPF_S_ALU_OR_K: | 168 | case BPF_S_ALU_OR_K: |
167 | A |= fentry->k; | 169 | A |= f_k; |
168 | continue; | 170 | continue; |
169 | case BPF_S_ALU_LSH_X: | 171 | case BPF_S_ALU_LSH_X: |
170 | A <<= X; | 172 | A <<= X; |
171 | continue; | 173 | continue; |
172 | case BPF_S_ALU_LSH_K: | 174 | case BPF_S_ALU_LSH_K: |
173 | A <<= fentry->k; | 175 | A <<= f_k; |
174 | continue; | 176 | continue; |
175 | case BPF_S_ALU_RSH_X: | 177 | case BPF_S_ALU_RSH_X: |
176 | A >>= X; | 178 | A >>= X; |
177 | continue; | 179 | continue; |
178 | case BPF_S_ALU_RSH_K: | 180 | case BPF_S_ALU_RSH_K: |
179 | A >>= fentry->k; | 181 | A >>= f_k; |
180 | continue; | 182 | continue; |
181 | case BPF_S_ALU_NEG: | 183 | case BPF_S_ALU_NEG: |
182 | A = -A; | 184 | A = -A; |
183 | continue; | 185 | continue; |
184 | case BPF_S_JMP_JA: | 186 | case BPF_S_JMP_JA: |
185 | pc += fentry->k; | 187 | pc += f_k; |
186 | continue; | 188 | continue; |
187 | case BPF_S_JMP_JGT_K: | 189 | case BPF_S_JMP_JGT_K: |
188 | pc += (A > fentry->k) ? fentry->jt : fentry->jf; | 190 | pc += (A > f_k) ? fentry->jt : fentry->jf; |
189 | continue; | 191 | continue; |
190 | case BPF_S_JMP_JGE_K: | 192 | case BPF_S_JMP_JGE_K: |
191 | pc += (A >= fentry->k) ? fentry->jt : fentry->jf; | 193 | pc += (A >= f_k) ? fentry->jt : fentry->jf; |
192 | continue; | 194 | continue; |
193 | case BPF_S_JMP_JEQ_K: | 195 | case BPF_S_JMP_JEQ_K: |
194 | pc += (A == fentry->k) ? fentry->jt : fentry->jf; | 196 | pc += (A == f_k) ? fentry->jt : fentry->jf; |
195 | continue; | 197 | continue; |
196 | case BPF_S_JMP_JSET_K: | 198 | case BPF_S_JMP_JSET_K: |
197 | pc += (A & fentry->k) ? fentry->jt : fentry->jf; | 199 | pc += (A & f_k) ? fentry->jt : fentry->jf; |
198 | continue; | 200 | continue; |
199 | case BPF_S_JMP_JGT_X: | 201 | case BPF_S_JMP_JGT_X: |
200 | pc += (A > X) ? fentry->jt : fentry->jf; | 202 | pc += (A > X) ? fentry->jt : fentry->jf; |
@@ -209,7 +211,7 @@ unsigned int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int | |||
209 | pc += (A & X) ? fentry->jt : fentry->jf; | 211 | pc += (A & X) ? fentry->jt : fentry->jf; |
210 | continue; | 212 | continue; |
211 | case BPF_S_LD_W_ABS: | 213 | case BPF_S_LD_W_ABS: |
212 | k = fentry->k; | 214 | k = f_k; |
213 | load_w: | 215 | load_w: |
214 | ptr = load_pointer(skb, k, 4, &tmp); | 216 | ptr = load_pointer(skb, k, 4, &tmp); |
215 | if (ptr != NULL) { | 217 | if (ptr != NULL) { |
@@ -218,7 +220,7 @@ load_w: | |||
218 | } | 220 | } |
219 | break; | 221 | break; |
220 | case BPF_S_LD_H_ABS: | 222 | case BPF_S_LD_H_ABS: |
221 | k = fentry->k; | 223 | k = f_k; |
222 | load_h: | 224 | load_h: |
223 | ptr = load_pointer(skb, k, 2, &tmp); | 225 | ptr = load_pointer(skb, k, 2, &tmp); |
224 | if (ptr != NULL) { | 226 | if (ptr != NULL) { |
@@ -227,7 +229,7 @@ load_h: | |||
227 | } | 229 | } |
228 | break; | 230 | break; |
229 | case BPF_S_LD_B_ABS: | 231 | case BPF_S_LD_B_ABS: |
230 | k = fentry->k; | 232 | k = f_k; |
231 | load_b: | 233 | load_b: |
232 | ptr = load_pointer(skb, k, 1, &tmp); | 234 | ptr = load_pointer(skb, k, 1, &tmp); |
233 | if (ptr != NULL) { | 235 | if (ptr != NULL) { |
@@ -242,32 +244,34 @@ load_b: | |||
242 | X = skb->len; | 244 | X = skb->len; |
243 | continue; | 245 | continue; |
244 | case BPF_S_LD_W_IND: | 246 | case BPF_S_LD_W_IND: |
245 | k = X + fentry->k; | 247 | k = X + f_k; |
246 | goto load_w; | 248 | goto load_w; |
247 | case BPF_S_LD_H_IND: | 249 | case BPF_S_LD_H_IND: |
248 | k = X + fentry->k; | 250 | k = X + f_k; |
249 | goto load_h; | 251 | goto load_h; |
250 | case BPF_S_LD_B_IND: | 252 | case BPF_S_LD_B_IND: |
251 | k = X + fentry->k; | 253 | k = X + f_k; |
252 | goto load_b; | 254 | goto load_b; |
253 | case BPF_S_LDX_B_MSH: | 255 | case BPF_S_LDX_B_MSH: |
254 | ptr = load_pointer(skb, fentry->k, 1, &tmp); | 256 | ptr = load_pointer(skb, f_k, 1, &tmp); |
255 | if (ptr != NULL) { | 257 | if (ptr != NULL) { |
256 | X = (*(u8 *)ptr & 0xf) << 2; | 258 | X = (*(u8 *)ptr & 0xf) << 2; |
257 | continue; | 259 | continue; |
258 | } | 260 | } |
259 | return 0; | 261 | return 0; |
260 | case BPF_S_LD_IMM: | 262 | case BPF_S_LD_IMM: |
261 | A = fentry->k; | 263 | A = f_k; |
262 | continue; | 264 | continue; |
263 | case BPF_S_LDX_IMM: | 265 | case BPF_S_LDX_IMM: |
264 | X = fentry->k; | 266 | X = f_k; |
265 | continue; | 267 | continue; |
266 | case BPF_S_LD_MEM: | 268 | case BPF_S_LD_MEM: |
267 | A = mem[fentry->k]; | 269 | A = (memvalid & (1UL << f_k)) ? |
270 | mem[f_k] : 0; | ||
268 | continue; | 271 | continue; |
269 | case BPF_S_LDX_MEM: | 272 | case BPF_S_LDX_MEM: |
270 | X = mem[fentry->k]; | 273 | X = (memvalid & (1UL << f_k)) ? |
274 | mem[f_k] : 0; | ||
271 | continue; | 275 | continue; |
272 | case BPF_S_MISC_TAX: | 276 | case BPF_S_MISC_TAX: |
273 | X = A; | 277 | X = A; |
@@ -276,14 +280,16 @@ load_b: | |||
276 | A = X; | 280 | A = X; |
277 | continue; | 281 | continue; |
278 | case BPF_S_RET_K: | 282 | case BPF_S_RET_K: |
279 | return fentry->k; | 283 | return f_k; |
280 | case BPF_S_RET_A: | 284 | case BPF_S_RET_A: |
281 | return A; | 285 | return A; |
282 | case BPF_S_ST: | 286 | case BPF_S_ST: |
283 | mem[fentry->k] = A; | 287 | memvalid |= 1UL << f_k; |
288 | mem[f_k] = A; | ||
284 | continue; | 289 | continue; |
285 | case BPF_S_STX: | 290 | case BPF_S_STX: |
286 | mem[fentry->k] = X; | 291 | memvalid |= 1UL << f_k; |
292 | mem[f_k] = X; | ||
287 | continue; | 293 | continue; |
288 | default: | 294 | default: |
289 | WARN_ON(1); | 295 | WARN_ON(1); |
@@ -583,23 +589,16 @@ int sk_chk_filter(struct sock_filter *filter, int flen) | |||
583 | EXPORT_SYMBOL(sk_chk_filter); | 589 | EXPORT_SYMBOL(sk_chk_filter); |
584 | 590 | ||
585 | /** | 591 | /** |
586 | * sk_filter_rcu_release: Release a socket filter by rcu_head | 592 | * sk_filter_release_rcu - Release a socket filter by rcu_head |
587 | * @rcu: rcu_head that contains the sk_filter to free | 593 | * @rcu: rcu_head that contains the sk_filter to free |
588 | */ | 594 | */ |
589 | static void sk_filter_rcu_release(struct rcu_head *rcu) | 595 | void sk_filter_release_rcu(struct rcu_head *rcu) |
590 | { | 596 | { |
591 | struct sk_filter *fp = container_of(rcu, struct sk_filter, rcu); | 597 | struct sk_filter *fp = container_of(rcu, struct sk_filter, rcu); |
592 | 598 | ||
593 | sk_filter_release(fp); | 599 | kfree(fp); |
594 | } | ||
595 | |||
596 | static void sk_filter_delayed_uncharge(struct sock *sk, struct sk_filter *fp) | ||
597 | { | ||
598 | unsigned int size = sk_filter_len(fp); | ||
599 | |||
600 | atomic_sub(size, &sk->sk_omem_alloc); | ||
601 | call_rcu_bh(&fp->rcu, sk_filter_rcu_release); | ||
602 | } | 600 | } |
601 | EXPORT_SYMBOL(sk_filter_release_rcu); | ||
603 | 602 | ||
604 | /** | 603 | /** |
605 | * sk_attach_filter - attach a socket filter | 604 | * sk_attach_filter - attach a socket filter |
@@ -644,7 +643,7 @@ int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk) | |||
644 | rcu_read_unlock_bh(); | 643 | rcu_read_unlock_bh(); |
645 | 644 | ||
646 | if (old_fp) | 645 | if (old_fp) |
647 | sk_filter_delayed_uncharge(sk, old_fp); | 646 | sk_filter_uncharge(sk, old_fp); |
648 | return 0; | 647 | return 0; |
649 | } | 648 | } |
650 | EXPORT_SYMBOL_GPL(sk_attach_filter); | 649 | EXPORT_SYMBOL_GPL(sk_attach_filter); |
@@ -658,7 +657,7 @@ int sk_detach_filter(struct sock *sk) | |||
658 | filter = rcu_dereference_bh(sk->sk_filter); | 657 | filter = rcu_dereference_bh(sk->sk_filter); |
659 | if (filter) { | 658 | if (filter) { |
660 | rcu_assign_pointer(sk->sk_filter, NULL); | 659 | rcu_assign_pointer(sk->sk_filter, NULL); |
661 | sk_filter_delayed_uncharge(sk, filter); | 660 | sk_filter_uncharge(sk, filter); |
662 | ret = 0; | 661 | ret = 0; |
663 | } | 662 | } |
664 | rcu_read_unlock_bh(); | 663 | rcu_read_unlock_bh(); |
diff --git a/net/core/iovec.c b/net/core/iovec.c index e6b133b77ccb..58eb9999f89d 100644 --- a/net/core/iovec.c +++ b/net/core/iovec.c | |||
@@ -35,10 +35,9 @@ | |||
35 | * in any case. | 35 | * in any case. |
36 | */ | 36 | */ |
37 | 37 | ||
38 | long verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *address, int mode) | 38 | int verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *address, int mode) |
39 | { | 39 | { |
40 | int size, ct; | 40 | int size, ct, err; |
41 | long err; | ||
42 | 41 | ||
43 | if (m->msg_namelen) { | 42 | if (m->msg_namelen) { |
44 | if (mode == VERIFY_READ) { | 43 | if (mode == VERIFY_READ) { |
@@ -60,14 +59,13 @@ long verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *address, | |||
60 | err = 0; | 59 | err = 0; |
61 | 60 | ||
62 | for (ct = 0; ct < m->msg_iovlen; ct++) { | 61 | for (ct = 0; ct < m->msg_iovlen; ct++) { |
63 | err += iov[ct].iov_len; | 62 | size_t len = iov[ct].iov_len; |
64 | /* | 63 | |
65 | * Goal is not to verify user data, but to prevent returning | 64 | if (len > INT_MAX - err) { |
66 | * negative value, which is interpreted as errno. | 65 | len = INT_MAX - err; |
67 | * Overflow is still possible, but it is harmless. | 66 | iov[ct].iov_len = len; |
68 | */ | 67 | } |
69 | if (err < 0) | 68 | err += len; |
70 | return -EMSGSIZE; | ||
71 | } | 69 | } |
72 | 70 | ||
73 | return err; | 71 | return err; |
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index f78d821bd935..29d7bce933f2 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
@@ -1546,6 +1546,9 @@ replay: | |||
1546 | snprintf(ifname, IFNAMSIZ, "%s%%d", ops->kind); | 1546 | snprintf(ifname, IFNAMSIZ, "%s%%d", ops->kind); |
1547 | 1547 | ||
1548 | dest_net = rtnl_link_get_net(net, tb); | 1548 | dest_net = rtnl_link_get_net(net, tb); |
1549 | if (IS_ERR(dest_net)) | ||
1550 | return PTR_ERR(dest_net); | ||
1551 | |||
1549 | dev = rtnl_create_link(net, dest_net, ifname, ops, tb); | 1552 | dev = rtnl_create_link(net, dest_net, ifname, ops, tb); |
1550 | 1553 | ||
1551 | if (IS_ERR(dev)) | 1554 | if (IS_ERR(dev)) |
diff --git a/net/core/timestamping.c b/net/core/timestamping.c index 0ae6c22da85b..c19bb4ee405e 100644 --- a/net/core/timestamping.c +++ b/net/core/timestamping.c | |||
@@ -96,11 +96,13 @@ bool skb_defer_rx_timestamp(struct sk_buff *skb) | |||
96 | struct phy_device *phydev; | 96 | struct phy_device *phydev; |
97 | unsigned int type; | 97 | unsigned int type; |
98 | 98 | ||
99 | skb_push(skb, ETH_HLEN); | 99 | if (skb_headroom(skb) < ETH_HLEN) |
100 | return false; | ||
101 | __skb_push(skb, ETH_HLEN); | ||
100 | 102 | ||
101 | type = classify(skb); | 103 | type = classify(skb); |
102 | 104 | ||
103 | skb_pull(skb, ETH_HLEN); | 105 | __skb_pull(skb, ETH_HLEN); |
104 | 106 | ||
105 | switch (type) { | 107 | switch (type) { |
106 | case PTP_CLASS_V1_IPV4: | 108 | case PTP_CLASS_V1_IPV4: |
diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c index d6b93d19790f..cf38f52be4f7 100644 --- a/net/decnet/af_decnet.c +++ b/net/decnet/af_decnet.c | |||
@@ -1556,6 +1556,8 @@ static int __dn_getsockopt(struct socket *sock, int level,int optname, char __us | |||
1556 | if (r_len > sizeof(struct linkinfo_dn)) | 1556 | if (r_len > sizeof(struct linkinfo_dn)) |
1557 | r_len = sizeof(struct linkinfo_dn); | 1557 | r_len = sizeof(struct linkinfo_dn); |
1558 | 1558 | ||
1559 | memset(&link, 0, sizeof(link)); | ||
1560 | |||
1559 | switch(sock->state) { | 1561 | switch(sock->state) { |
1560 | case SS_CONNECTING: | 1562 | case SS_CONNECTING: |
1561 | link.idn_linkstate = LL_CONNECTING; | 1563 | link.idn_linkstate = LL_CONNECTING; |
diff --git a/net/econet/af_econet.c b/net/econet/af_econet.c index dc54bd0d083b..172a6a91a214 100644 --- a/net/econet/af_econet.c +++ b/net/econet/af_econet.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/skbuff.h> | 31 | #include <linux/skbuff.h> |
32 | #include <linux/udp.h> | 32 | #include <linux/udp.h> |
33 | #include <linux/slab.h> | 33 | #include <linux/slab.h> |
34 | #include <linux/vmalloc.h> | ||
34 | #include <net/sock.h> | 35 | #include <net/sock.h> |
35 | #include <net/inet_common.h> | 36 | #include <net/inet_common.h> |
36 | #include <linux/stat.h> | 37 | #include <linux/stat.h> |
@@ -276,12 +277,12 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
276 | #endif | 277 | #endif |
277 | #ifdef CONFIG_ECONET_AUNUDP | 278 | #ifdef CONFIG_ECONET_AUNUDP |
278 | struct msghdr udpmsg; | 279 | struct msghdr udpmsg; |
279 | struct iovec iov[msg->msg_iovlen+1]; | 280 | struct iovec iov[2]; |
280 | struct aunhdr ah; | 281 | struct aunhdr ah; |
281 | struct sockaddr_in udpdest; | 282 | struct sockaddr_in udpdest; |
282 | __kernel_size_t size; | 283 | __kernel_size_t size; |
283 | int i; | ||
284 | mm_segment_t oldfs; | 284 | mm_segment_t oldfs; |
285 | char *userbuf; | ||
285 | #endif | 286 | #endif |
286 | 287 | ||
287 | /* | 288 | /* |
@@ -297,23 +298,14 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
297 | 298 | ||
298 | mutex_lock(&econet_mutex); | 299 | mutex_lock(&econet_mutex); |
299 | 300 | ||
300 | if (saddr == NULL) { | 301 | if (saddr == NULL || msg->msg_namelen < sizeof(struct sockaddr_ec)) { |
301 | struct econet_sock *eo = ec_sk(sk); | 302 | mutex_unlock(&econet_mutex); |
302 | 303 | return -EINVAL; | |
303 | addr.station = eo->station; | 304 | } |
304 | addr.net = eo->net; | 305 | addr.station = saddr->addr.station; |
305 | port = eo->port; | 306 | addr.net = saddr->addr.net; |
306 | cb = eo->cb; | 307 | port = saddr->port; |
307 | } else { | 308 | cb = saddr->cb; |
308 | if (msg->msg_namelen < sizeof(struct sockaddr_ec)) { | ||
309 | mutex_unlock(&econet_mutex); | ||
310 | return -EINVAL; | ||
311 | } | ||
312 | addr.station = saddr->addr.station; | ||
313 | addr.net = saddr->addr.net; | ||
314 | port = saddr->port; | ||
315 | cb = saddr->cb; | ||
316 | } | ||
317 | 309 | ||
318 | /* Look for a device with the right network number. */ | 310 | /* Look for a device with the right network number. */ |
319 | dev = net2dev_map[addr.net]; | 311 | dev = net2dev_map[addr.net]; |
@@ -328,17 +320,17 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
328 | } | 320 | } |
329 | } | 321 | } |
330 | 322 | ||
331 | if (len + 15 > dev->mtu) { | ||
332 | mutex_unlock(&econet_mutex); | ||
333 | return -EMSGSIZE; | ||
334 | } | ||
335 | |||
336 | if (dev->type == ARPHRD_ECONET) { | 323 | if (dev->type == ARPHRD_ECONET) { |
337 | /* Real hardware Econet. We're not worthy etc. */ | 324 | /* Real hardware Econet. We're not worthy etc. */ |
338 | #ifdef CONFIG_ECONET_NATIVE | 325 | #ifdef CONFIG_ECONET_NATIVE |
339 | unsigned short proto = 0; | 326 | unsigned short proto = 0; |
340 | int res; | 327 | int res; |
341 | 328 | ||
329 | if (len + 15 > dev->mtu) { | ||
330 | mutex_unlock(&econet_mutex); | ||
331 | return -EMSGSIZE; | ||
332 | } | ||
333 | |||
342 | dev_hold(dev); | 334 | dev_hold(dev); |
343 | 335 | ||
344 | skb = sock_alloc_send_skb(sk, len+LL_ALLOCATED_SPACE(dev), | 336 | skb = sock_alloc_send_skb(sk, len+LL_ALLOCATED_SPACE(dev), |
@@ -351,7 +343,6 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
351 | 343 | ||
352 | eb = (struct ec_cb *)&skb->cb; | 344 | eb = (struct ec_cb *)&skb->cb; |
353 | 345 | ||
354 | /* BUG: saddr may be NULL */ | ||
355 | eb->cookie = saddr->cookie; | 346 | eb->cookie = saddr->cookie; |
356 | eb->sec = *saddr; | 347 | eb->sec = *saddr; |
357 | eb->sent = ec_tx_done; | 348 | eb->sent = ec_tx_done; |
@@ -415,6 +406,11 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
415 | return -ENETDOWN; /* No socket - can't send */ | 406 | return -ENETDOWN; /* No socket - can't send */ |
416 | } | 407 | } |
417 | 408 | ||
409 | if (len > 32768) { | ||
410 | err = -E2BIG; | ||
411 | goto error; | ||
412 | } | ||
413 | |||
418 | /* Make up a UDP datagram and hand it off to some higher intellect. */ | 414 | /* Make up a UDP datagram and hand it off to some higher intellect. */ |
419 | 415 | ||
420 | memset(&udpdest, 0, sizeof(udpdest)); | 416 | memset(&udpdest, 0, sizeof(udpdest)); |
@@ -446,36 +442,26 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
446 | 442 | ||
447 | /* tack our header on the front of the iovec */ | 443 | /* tack our header on the front of the iovec */ |
448 | size = sizeof(struct aunhdr); | 444 | size = sizeof(struct aunhdr); |
449 | /* | ||
450 | * XXX: that is b0rken. We can't mix userland and kernel pointers | ||
451 | * in iovec, since on a lot of platforms copy_from_user() will | ||
452 | * *not* work with the kernel and userland ones at the same time, | ||
453 | * regardless of what we do with set_fs(). And we are talking about | ||
454 | * econet-over-ethernet here, so "it's only ARM anyway" doesn't | ||
455 | * apply. Any suggestions on fixing that code? -- AV | ||
456 | */ | ||
457 | iov[0].iov_base = (void *)&ah; | 445 | iov[0].iov_base = (void *)&ah; |
458 | iov[0].iov_len = size; | 446 | iov[0].iov_len = size; |
459 | for (i = 0; i < msg->msg_iovlen; i++) { | 447 | |
460 | void __user *base = msg->msg_iov[i].iov_base; | 448 | userbuf = vmalloc(len); |
461 | size_t iov_len = msg->msg_iov[i].iov_len; | 449 | if (userbuf == NULL) { |
462 | /* Check it now since we switch to KERNEL_DS later. */ | 450 | err = -ENOMEM; |
463 | if (!access_ok(VERIFY_READ, base, iov_len)) { | 451 | goto error; |
464 | mutex_unlock(&econet_mutex); | ||
465 | return -EFAULT; | ||
466 | } | ||
467 | iov[i+1].iov_base = base; | ||
468 | iov[i+1].iov_len = iov_len; | ||
469 | size += iov_len; | ||
470 | } | 452 | } |
471 | 453 | ||
454 | iov[1].iov_base = userbuf; | ||
455 | iov[1].iov_len = len; | ||
456 | err = memcpy_fromiovec(userbuf, msg->msg_iov, len); | ||
457 | if (err) | ||
458 | goto error_free_buf; | ||
459 | |||
472 | /* Get a skbuff (no data, just holds our cb information) */ | 460 | /* Get a skbuff (no data, just holds our cb information) */ |
473 | if ((skb = sock_alloc_send_skb(sk, 0, | 461 | if ((skb = sock_alloc_send_skb(sk, 0, |
474 | msg->msg_flags & MSG_DONTWAIT, | 462 | msg->msg_flags & MSG_DONTWAIT, |
475 | &err)) == NULL) { | 463 | &err)) == NULL) |
476 | mutex_unlock(&econet_mutex); | 464 | goto error_free_buf; |
477 | return err; | ||
478 | } | ||
479 | 465 | ||
480 | eb = (struct ec_cb *)&skb->cb; | 466 | eb = (struct ec_cb *)&skb->cb; |
481 | 467 | ||
@@ -491,7 +477,7 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
491 | udpmsg.msg_name = (void *)&udpdest; | 477 | udpmsg.msg_name = (void *)&udpdest; |
492 | udpmsg.msg_namelen = sizeof(udpdest); | 478 | udpmsg.msg_namelen = sizeof(udpdest); |
493 | udpmsg.msg_iov = &iov[0]; | 479 | udpmsg.msg_iov = &iov[0]; |
494 | udpmsg.msg_iovlen = msg->msg_iovlen + 1; | 480 | udpmsg.msg_iovlen = 2; |
495 | udpmsg.msg_control = NULL; | 481 | udpmsg.msg_control = NULL; |
496 | udpmsg.msg_controllen = 0; | 482 | udpmsg.msg_controllen = 0; |
497 | udpmsg.msg_flags=0; | 483 | udpmsg.msg_flags=0; |
@@ -499,9 +485,13 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
499 | oldfs = get_fs(); set_fs(KERNEL_DS); /* More privs :-) */ | 485 | oldfs = get_fs(); set_fs(KERNEL_DS); /* More privs :-) */ |
500 | err = sock_sendmsg(udpsock, &udpmsg, size); | 486 | err = sock_sendmsg(udpsock, &udpmsg, size); |
501 | set_fs(oldfs); | 487 | set_fs(oldfs); |
488 | |||
489 | error_free_buf: | ||
490 | vfree(userbuf); | ||
502 | #else | 491 | #else |
503 | err = -EPROTOTYPE; | 492 | err = -EPROTOTYPE; |
504 | #endif | 493 | #endif |
494 | error: | ||
505 | mutex_unlock(&econet_mutex); | 495 | mutex_unlock(&econet_mutex); |
506 | 496 | ||
507 | return err; | 497 | return err; |
@@ -671,6 +661,11 @@ static int ec_dev_ioctl(struct socket *sock, unsigned int cmd, void __user *arg) | |||
671 | err = 0; | 661 | err = 0; |
672 | switch (cmd) { | 662 | switch (cmd) { |
673 | case SIOCSIFADDR: | 663 | case SIOCSIFADDR: |
664 | if (!capable(CAP_NET_ADMIN)) { | ||
665 | err = -EPERM; | ||
666 | break; | ||
667 | } | ||
668 | |||
674 | edev = dev->ec_ptr; | 669 | edev = dev->ec_ptr; |
675 | if (edev == NULL) { | 670 | if (edev == NULL) { |
676 | /* Magic up a new one. */ | 671 | /* Magic up a new one. */ |
@@ -856,9 +851,13 @@ static void aun_incoming(struct sk_buff *skb, struct aunhdr *ah, size_t len) | |||
856 | { | 851 | { |
857 | struct iphdr *ip = ip_hdr(skb); | 852 | struct iphdr *ip = ip_hdr(skb); |
858 | unsigned char stn = ntohl(ip->saddr) & 0xff; | 853 | unsigned char stn = ntohl(ip->saddr) & 0xff; |
854 | struct dst_entry *dst = skb_dst(skb); | ||
855 | struct ec_device *edev = NULL; | ||
859 | struct sock *sk = NULL; | 856 | struct sock *sk = NULL; |
860 | struct sk_buff *newskb; | 857 | struct sk_buff *newskb; |
861 | struct ec_device *edev = skb->dev->ec_ptr; | 858 | |
859 | if (dst) | ||
860 | edev = dst->dev->ec_ptr; | ||
862 | 861 | ||
863 | if (! edev) | 862 | if (! edev) |
864 | goto bad; | 863 | goto bad; |
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index f115ea68a4ef..6adb1abf05e0 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
@@ -2246,7 +2246,7 @@ static int do_tcp_setsockopt(struct sock *sk, int level, | |||
2246 | /* Values greater than interface MTU won't take effect. However | 2246 | /* Values greater than interface MTU won't take effect. However |
2247 | * at the point when this call is done we typically don't yet | 2247 | * at the point when this call is done we typically don't yet |
2248 | * know which interface is going to be used */ | 2248 | * know which interface is going to be used */ |
2249 | if (val < 8 || val > MAX_TCP_WINDOW) { | 2249 | if (val < TCP_MIN_MSS || val > MAX_TCP_WINDOW) { |
2250 | err = -EINVAL; | 2250 | err = -EINVAL; |
2251 | break; | 2251 | break; |
2252 | } | 2252 | } |
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 020766292bb0..cb8d305cb5b4 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
@@ -415,6 +415,9 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info) | |||
415 | !icsk->icsk_backoff) | 415 | !icsk->icsk_backoff) |
416 | break; | 416 | break; |
417 | 417 | ||
418 | if (sock_owned_by_user(sk)) | ||
419 | break; | ||
420 | |||
418 | icsk->icsk_backoff--; | 421 | icsk->icsk_backoff--; |
419 | inet_csk(sk)->icsk_rto = __tcp_set_rto(tp) << | 422 | inet_csk(sk)->icsk_rto = __tcp_set_rto(tp) << |
420 | icsk->icsk_backoff; | 423 | icsk->icsk_backoff; |
@@ -429,11 +432,6 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info) | |||
429 | if (remaining) { | 432 | if (remaining) { |
430 | inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, | 433 | inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, |
431 | remaining, TCP_RTO_MAX); | 434 | remaining, TCP_RTO_MAX); |
432 | } else if (sock_owned_by_user(sk)) { | ||
433 | /* RTO revert clocked out retransmission, | ||
434 | * but socket is locked. Will defer. */ | ||
435 | inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, | ||
436 | HZ/20, TCP_RTO_MAX); | ||
437 | } else { | 435 | } else { |
438 | /* RTO revert clocked out retransmission. | 436 | /* RTO revert clocked out retransmission. |
439 | * Will retransmit now */ | 437 | * Will retransmit now */ |
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index de3bd8458588..7abecf73add9 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
@@ -237,11 +237,10 @@ void tcp_select_initial_window(int __space, __u32 mss, | |||
237 | /* when initializing use the value from init_rcv_wnd | 237 | /* when initializing use the value from init_rcv_wnd |
238 | * rather than the default from above | 238 | * rather than the default from above |
239 | */ | 239 | */ |
240 | if (init_rcv_wnd && | 240 | if (init_rcv_wnd) |
241 | (*rcv_wnd > init_rcv_wnd * mss)) | 241 | *rcv_wnd = min(*rcv_wnd, init_rcv_wnd * mss); |
242 | *rcv_wnd = init_rcv_wnd * mss; | 242 | else |
243 | else if (*rcv_wnd > init_cwnd * mss) | 243 | *rcv_wnd = min(*rcv_wnd, init_cwnd * mss); |
244 | *rcv_wnd = init_cwnd * mss; | ||
245 | } | 244 | } |
246 | 245 | ||
247 | /* Set the clamp no higher than max representable value */ | 246 | /* Set the clamp no higher than max representable value */ |
@@ -392,27 +391,30 @@ struct tcp_out_options { | |||
392 | */ | 391 | */ |
393 | static u8 tcp_cookie_size_check(u8 desired) | 392 | static u8 tcp_cookie_size_check(u8 desired) |
394 | { | 393 | { |
395 | if (desired > 0) { | 394 | int cookie_size; |
395 | |||
396 | if (desired > 0) | ||
396 | /* previously specified */ | 397 | /* previously specified */ |
397 | return desired; | 398 | return desired; |
398 | } | 399 | |
399 | if (sysctl_tcp_cookie_size <= 0) { | 400 | cookie_size = ACCESS_ONCE(sysctl_tcp_cookie_size); |
401 | if (cookie_size <= 0) | ||
400 | /* no default specified */ | 402 | /* no default specified */ |
401 | return 0; | 403 | return 0; |
402 | } | 404 | |
403 | if (sysctl_tcp_cookie_size <= TCP_COOKIE_MIN) { | 405 | if (cookie_size <= TCP_COOKIE_MIN) |
404 | /* value too small, specify minimum */ | 406 | /* value too small, specify minimum */ |
405 | return TCP_COOKIE_MIN; | 407 | return TCP_COOKIE_MIN; |
406 | } | 408 | |
407 | if (sysctl_tcp_cookie_size >= TCP_COOKIE_MAX) { | 409 | if (cookie_size >= TCP_COOKIE_MAX) |
408 | /* value too large, specify maximum */ | 410 | /* value too large, specify maximum */ |
409 | return TCP_COOKIE_MAX; | 411 | return TCP_COOKIE_MAX; |
410 | } | 412 | |
411 | if (0x1 & sysctl_tcp_cookie_size) { | 413 | if (cookie_size & 1) |
412 | /* 8-bit multiple, illegal, fix it */ | 414 | /* 8-bit multiple, illegal, fix it */ |
413 | return (u8)(sysctl_tcp_cookie_size + 0x1); | 415 | cookie_size++; |
414 | } | 416 | |
415 | return (u8)sysctl_tcp_cookie_size; | 417 | return (u8)cookie_size; |
416 | } | 418 | } |
417 | 419 | ||
418 | /* Write previously computed TCP options to the packet. | 420 | /* Write previously computed TCP options to the packet. |
@@ -1519,6 +1521,7 @@ static int tcp_tso_should_defer(struct sock *sk, struct sk_buff *skb) | |||
1519 | struct tcp_sock *tp = tcp_sk(sk); | 1521 | struct tcp_sock *tp = tcp_sk(sk); |
1520 | const struct inet_connection_sock *icsk = inet_csk(sk); | 1522 | const struct inet_connection_sock *icsk = inet_csk(sk); |
1521 | u32 send_win, cong_win, limit, in_flight; | 1523 | u32 send_win, cong_win, limit, in_flight; |
1524 | int win_divisor; | ||
1522 | 1525 | ||
1523 | if (TCP_SKB_CB(skb)->flags & TCPHDR_FIN) | 1526 | if (TCP_SKB_CB(skb)->flags & TCPHDR_FIN) |
1524 | goto send_now; | 1527 | goto send_now; |
@@ -1550,13 +1553,14 @@ static int tcp_tso_should_defer(struct sock *sk, struct sk_buff *skb) | |||
1550 | if ((skb != tcp_write_queue_tail(sk)) && (limit >= skb->len)) | 1553 | if ((skb != tcp_write_queue_tail(sk)) && (limit >= skb->len)) |
1551 | goto send_now; | 1554 | goto send_now; |
1552 | 1555 | ||
1553 | if (sysctl_tcp_tso_win_divisor) { | 1556 | win_divisor = ACCESS_ONCE(sysctl_tcp_tso_win_divisor); |
1557 | if (win_divisor) { | ||
1554 | u32 chunk = min(tp->snd_wnd, tp->snd_cwnd * tp->mss_cache); | 1558 | u32 chunk = min(tp->snd_wnd, tp->snd_cwnd * tp->mss_cache); |
1555 | 1559 | ||
1556 | /* If at least some fraction of a window is available, | 1560 | /* If at least some fraction of a window is available, |
1557 | * just use it. | 1561 | * just use it. |
1558 | */ | 1562 | */ |
1559 | chunk /= sysctl_tcp_tso_win_divisor; | 1563 | chunk /= win_divisor; |
1560 | if (limit >= chunk) | 1564 | if (limit >= chunk) |
1561 | goto send_now; | 1565 | goto send_now; |
1562 | } else { | 1566 | } else { |
diff --git a/net/irda/iriap.c b/net/irda/iriap.c index fce364c6c71a..5b743bdd89ba 100644 --- a/net/irda/iriap.c +++ b/net/irda/iriap.c | |||
@@ -502,7 +502,8 @@ static void iriap_getvaluebyclass_confirm(struct iriap_cb *self, | |||
502 | IRDA_DEBUG(4, "%s(), strlen=%d\n", __func__, value_len); | 502 | IRDA_DEBUG(4, "%s(), strlen=%d\n", __func__, value_len); |
503 | 503 | ||
504 | /* Make sure the string is null-terminated */ | 504 | /* Make sure the string is null-terminated */ |
505 | fp[n+value_len] = 0x00; | 505 | if (n + value_len < skb->len) |
506 | fp[n + value_len] = 0x00; | ||
506 | IRDA_DEBUG(4, "Got string %s\n", fp+n); | 507 | IRDA_DEBUG(4, "Got string %s\n", fp+n); |
507 | 508 | ||
508 | /* Will truncate to IAS_MAX_STRING bytes */ | 509 | /* Will truncate to IAS_MAX_STRING bytes */ |
diff --git a/net/irda/parameters.c b/net/irda/parameters.c index fc1a20565e2d..71cd38c1a67f 100644 --- a/net/irda/parameters.c +++ b/net/irda/parameters.c | |||
@@ -298,6 +298,8 @@ static int irda_extract_string(void *self, __u8 *buf, int len, __u8 pi, | |||
298 | 298 | ||
299 | p.pi = pi; /* In case handler needs to know */ | 299 | p.pi = pi; /* In case handler needs to know */ |
300 | p.pl = buf[1]; /* Extract length of value */ | 300 | p.pl = buf[1]; /* Extract length of value */ |
301 | if (p.pl > 32) | ||
302 | p.pl = 32; | ||
301 | 303 | ||
302 | IRDA_DEBUG(2, "%s(), pi=%#x, pl=%d\n", __func__, | 304 | IRDA_DEBUG(2, "%s(), pi=%#x, pl=%d\n", __func__, |
303 | p.pi, p.pl); | 305 | p.pi, p.pl); |
@@ -318,7 +320,7 @@ static int irda_extract_string(void *self, __u8 *buf, int len, __u8 pi, | |||
318 | (__u8) str[0], (__u8) str[1]); | 320 | (__u8) str[0], (__u8) str[1]); |
319 | 321 | ||
320 | /* Null terminate string */ | 322 | /* Null terminate string */ |
321 | str[p.pl+1] = '\0'; | 323 | str[p.pl] = '\0'; |
322 | 324 | ||
323 | p.pv.c = str; /* Handler will need to take a copy */ | 325 | p.pv.c = str; /* Handler will need to take a copy */ |
324 | 326 | ||
diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c index 226a0ae3bcfd..a2cec796a321 100644 --- a/net/l2tp/l2tp_ip.c +++ b/net/l2tp/l2tp_ip.c | |||
@@ -676,4 +676,8 @@ MODULE_LICENSE("GPL"); | |||
676 | MODULE_AUTHOR("James Chapman <jchapman@katalix.com>"); | 676 | MODULE_AUTHOR("James Chapman <jchapman@katalix.com>"); |
677 | MODULE_DESCRIPTION("L2TP over IP"); | 677 | MODULE_DESCRIPTION("L2TP over IP"); |
678 | MODULE_VERSION("1.0"); | 678 | MODULE_VERSION("1.0"); |
679 | MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET, SOCK_DGRAM, IPPROTO_L2TP); | 679 | |
680 | /* Use the value of SOCK_DGRAM (2) directory, because __stringify does't like | ||
681 | * enums | ||
682 | */ | ||
683 | MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET, 2, IPPROTO_L2TP); | ||
diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c index 582612998211..e35dbe55f520 100644 --- a/net/llc/af_llc.c +++ b/net/llc/af_llc.c | |||
@@ -317,8 +317,9 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen) | |||
317 | goto out; | 317 | goto out; |
318 | rc = -ENODEV; | 318 | rc = -ENODEV; |
319 | rtnl_lock(); | 319 | rtnl_lock(); |
320 | rcu_read_lock(); | ||
320 | if (sk->sk_bound_dev_if) { | 321 | if (sk->sk_bound_dev_if) { |
321 | llc->dev = dev_get_by_index(&init_net, sk->sk_bound_dev_if); | 322 | llc->dev = dev_get_by_index_rcu(&init_net, sk->sk_bound_dev_if); |
322 | if (llc->dev) { | 323 | if (llc->dev) { |
323 | if (!addr->sllc_arphrd) | 324 | if (!addr->sllc_arphrd) |
324 | addr->sllc_arphrd = llc->dev->type; | 325 | addr->sllc_arphrd = llc->dev->type; |
@@ -329,13 +330,13 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen) | |||
329 | !llc_mac_match(addr->sllc_mac, | 330 | !llc_mac_match(addr->sllc_mac, |
330 | llc->dev->dev_addr)) { | 331 | llc->dev->dev_addr)) { |
331 | rc = -EINVAL; | 332 | rc = -EINVAL; |
332 | dev_put(llc->dev); | ||
333 | llc->dev = NULL; | 333 | llc->dev = NULL; |
334 | } | 334 | } |
335 | } | 335 | } |
336 | } else | 336 | } else |
337 | llc->dev = dev_getbyhwaddr(&init_net, addr->sllc_arphrd, | 337 | llc->dev = dev_getbyhwaddr(&init_net, addr->sllc_arphrd, |
338 | addr->sllc_mac); | 338 | addr->sllc_mac); |
339 | rcu_read_unlock(); | ||
339 | rtnl_unlock(); | 340 | rtnl_unlock(); |
340 | if (!llc->dev) | 341 | if (!llc->dev) |
341 | goto out; | 342 | goto out; |
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c index 965b272499fd..2f6903e48dd9 100644 --- a/net/mac80211/agg-rx.c +++ b/net/mac80211/agg-rx.c | |||
@@ -172,8 +172,6 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, | |||
172 | struct ieee80211_mgmt *mgmt, | 172 | struct ieee80211_mgmt *mgmt, |
173 | size_t len) | 173 | size_t len) |
174 | { | 174 | { |
175 | struct ieee80211_hw *hw = &local->hw; | ||
176 | struct ieee80211_conf *conf = &hw->conf; | ||
177 | struct tid_ampdu_rx *tid_agg_rx; | 175 | struct tid_ampdu_rx *tid_agg_rx; |
178 | u16 capab, tid, timeout, ba_policy, buf_size, start_seq_num, status; | 176 | u16 capab, tid, timeout, ba_policy, buf_size, start_seq_num, status; |
179 | u8 dialog_token; | 177 | u8 dialog_token; |
@@ -218,13 +216,8 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, | |||
218 | goto end_no_lock; | 216 | goto end_no_lock; |
219 | } | 217 | } |
220 | /* determine default buffer size */ | 218 | /* determine default buffer size */ |
221 | if (buf_size == 0) { | 219 | if (buf_size == 0) |
222 | struct ieee80211_supported_band *sband; | 220 | buf_size = IEEE80211_MAX_AMPDU_BUF; |
223 | |||
224 | sband = local->hw.wiphy->bands[conf->channel->band]; | ||
225 | buf_size = IEEE80211_MIN_AMPDU_BUF; | ||
226 | buf_size = buf_size << sband->ht_cap.ampdu_factor; | ||
227 | } | ||
228 | 221 | ||
229 | 222 | ||
230 | /* examine state machine */ | 223 | /* examine state machine */ |
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 29ac8e1a509e..2095602dcc3a 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -634,6 +634,7 @@ static void sta_apply_parameters(struct ieee80211_local *local, | |||
634 | struct sta_info *sta, | 634 | struct sta_info *sta, |
635 | struct station_parameters *params) | 635 | struct station_parameters *params) |
636 | { | 636 | { |
637 | unsigned long flags; | ||
637 | u32 rates; | 638 | u32 rates; |
638 | int i, j; | 639 | int i, j; |
639 | struct ieee80211_supported_band *sband; | 640 | struct ieee80211_supported_band *sband; |
@@ -642,7 +643,7 @@ static void sta_apply_parameters(struct ieee80211_local *local, | |||
642 | 643 | ||
643 | sband = local->hw.wiphy->bands[local->oper_channel->band]; | 644 | sband = local->hw.wiphy->bands[local->oper_channel->band]; |
644 | 645 | ||
645 | spin_lock_bh(&sta->lock); | 646 | spin_lock_irqsave(&sta->flaglock, flags); |
646 | mask = params->sta_flags_mask; | 647 | mask = params->sta_flags_mask; |
647 | set = params->sta_flags_set; | 648 | set = params->sta_flags_set; |
648 | 649 | ||
@@ -669,7 +670,7 @@ static void sta_apply_parameters(struct ieee80211_local *local, | |||
669 | if (set & BIT(NL80211_STA_FLAG_MFP)) | 670 | if (set & BIT(NL80211_STA_FLAG_MFP)) |
670 | sta->flags |= WLAN_STA_MFP; | 671 | sta->flags |= WLAN_STA_MFP; |
671 | } | 672 | } |
672 | spin_unlock_bh(&sta->lock); | 673 | spin_unlock_irqrestore(&sta->flaglock, flags); |
673 | 674 | ||
674 | /* | 675 | /* |
675 | * cfg80211 validates this (1-2007) and allows setting the AID | 676 | * cfg80211 validates this (1-2007) and allows setting the AID |
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index c691780725a7..45c99f096c7b 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
@@ -435,6 +435,7 @@ struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, | |||
435 | if (!sta) | 435 | if (!sta) |
436 | return NULL; | 436 | return NULL; |
437 | 437 | ||
438 | sta->last_rx = jiffies; | ||
438 | set_sta_flags(sta, WLAN_STA_AUTHORIZED); | 439 | set_sta_flags(sta, WLAN_STA_AUTHORIZED); |
439 | 440 | ||
440 | /* make sure mandatory rates are always added */ | 441 | /* make sure mandatory rates are always added */ |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 65e0ed6c2975..3546054505ab 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -1003,6 +1003,8 @@ void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata); | |||
1003 | void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata); | 1003 | void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata); |
1004 | void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, | 1004 | void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, |
1005 | struct sk_buff *skb); | 1005 | struct sk_buff *skb); |
1006 | void ieee80211_sta_reset_beacon_monitor(struct ieee80211_sub_if_data *sdata); | ||
1007 | void ieee80211_sta_reset_conn_monitor(struct ieee80211_sub_if_data *sdata); | ||
1006 | 1008 | ||
1007 | /* IBSS code */ | 1009 | /* IBSS code */ |
1008 | void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local); | 1010 | void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local); |
diff --git a/net/mac80211/key.c b/net/mac80211/key.c index 1b9d87ed143a..3f76484221a2 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c | |||
@@ -323,6 +323,12 @@ static void __ieee80211_key_destroy(struct ieee80211_key *key) | |||
323 | if (!key) | 323 | if (!key) |
324 | return; | 324 | return; |
325 | 325 | ||
326 | /* | ||
327 | * Synchronize so the TX path can no longer be using | ||
328 | * this key before we free/remove it. | ||
329 | */ | ||
330 | synchronize_rcu(); | ||
331 | |||
326 | if (key->local) | 332 | if (key->local) |
327 | ieee80211_key_disable_hw_accel(key); | 333 | ieee80211_key_disable_hw_accel(key); |
328 | 334 | ||
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index ded5c3843e06..e8acdb2fb2ca 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -108,7 +108,8 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) | |||
108 | chan = scan_chan; | 108 | chan = scan_chan; |
109 | channel_type = NL80211_CHAN_NO_HT; | 109 | channel_type = NL80211_CHAN_NO_HT; |
110 | local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL; | 110 | local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL; |
111 | } else if (local->tmp_channel) { | 111 | } else if (local->tmp_channel && |
112 | local->oper_channel != local->tmp_channel) { | ||
112 | chan = scan_chan = local->tmp_channel; | 113 | chan = scan_chan = local->tmp_channel; |
113 | channel_type = local->tmp_channel_type; | 114 | channel_type = local->tmp_channel_type; |
114 | local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL; | 115 | local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL; |
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index ea13a80a476c..1c91f0f3c307 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c | |||
@@ -412,7 +412,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m | |||
412 | enum plink_event event; | 412 | enum plink_event event; |
413 | enum plink_frame_type ftype; | 413 | enum plink_frame_type ftype; |
414 | size_t baselen; | 414 | size_t baselen; |
415 | bool deactivated; | 415 | bool deactivated, matches_local = true; |
416 | u8 ie_len; | 416 | u8 ie_len; |
417 | u8 *baseaddr; | 417 | u8 *baseaddr; |
418 | __le16 plid, llid, reason; | 418 | __le16 plid, llid, reason; |
@@ -487,6 +487,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m | |||
487 | /* Now we will figure out the appropriate event... */ | 487 | /* Now we will figure out the appropriate event... */ |
488 | event = PLINK_UNDEFINED; | 488 | event = PLINK_UNDEFINED; |
489 | if (ftype != PLINK_CLOSE && (!mesh_matches_local(&elems, sdata))) { | 489 | if (ftype != PLINK_CLOSE && (!mesh_matches_local(&elems, sdata))) { |
490 | matches_local = false; | ||
490 | switch (ftype) { | 491 | switch (ftype) { |
491 | case PLINK_OPEN: | 492 | case PLINK_OPEN: |
492 | event = OPN_RJCT; | 493 | event = OPN_RJCT; |
@@ -498,7 +499,15 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m | |||
498 | /* avoid warning */ | 499 | /* avoid warning */ |
499 | break; | 500 | break; |
500 | } | 501 | } |
501 | spin_lock_bh(&sta->lock); | 502 | } |
503 | |||
504 | if (!sta && !matches_local) { | ||
505 | rcu_read_unlock(); | ||
506 | reason = cpu_to_le16(MESH_CAPABILITY_POLICY_VIOLATION); | ||
507 | llid = 0; | ||
508 | mesh_plink_frame_tx(sdata, PLINK_CLOSE, mgmt->sa, llid, | ||
509 | plid, reason); | ||
510 | return; | ||
502 | } else if (!sta) { | 511 | } else if (!sta) { |
503 | /* ftype == PLINK_OPEN */ | 512 | /* ftype == PLINK_OPEN */ |
504 | u32 rates; | 513 | u32 rates; |
@@ -522,7 +531,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m | |||
522 | } | 531 | } |
523 | event = OPN_ACPT; | 532 | event = OPN_ACPT; |
524 | spin_lock_bh(&sta->lock); | 533 | spin_lock_bh(&sta->lock); |
525 | } else { | 534 | } else if (matches_local) { |
526 | spin_lock_bh(&sta->lock); | 535 | spin_lock_bh(&sta->lock); |
527 | switch (ftype) { | 536 | switch (ftype) { |
528 | case PLINK_OPEN: | 537 | case PLINK_OPEN: |
@@ -564,6 +573,8 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m | |||
564 | rcu_read_unlock(); | 573 | rcu_read_unlock(); |
565 | return; | 574 | return; |
566 | } | 575 | } |
576 | } else { | ||
577 | spin_lock_bh(&sta->lock); | ||
567 | } | 578 | } |
568 | 579 | ||
569 | mpl_dbg("Mesh plink (peer, state, llid, plid, event): %pM %s %d %d %d\n", | 580 | mpl_dbg("Mesh plink (peer, state, llid, plid, event): %pM %s %d %d %d\n", |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index b6c163ac22da..4c5eed9446f4 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -109,7 +109,7 @@ static void run_again(struct ieee80211_if_managed *ifmgd, | |||
109 | mod_timer(&ifmgd->timer, timeout); | 109 | mod_timer(&ifmgd->timer, timeout); |
110 | } | 110 | } |
111 | 111 | ||
112 | static void mod_beacon_timer(struct ieee80211_sub_if_data *sdata) | 112 | void ieee80211_sta_reset_beacon_monitor(struct ieee80211_sub_if_data *sdata) |
113 | { | 113 | { |
114 | if (sdata->local->hw.flags & IEEE80211_HW_BEACON_FILTER) | 114 | if (sdata->local->hw.flags & IEEE80211_HW_BEACON_FILTER) |
115 | return; | 115 | return; |
@@ -118,6 +118,19 @@ static void mod_beacon_timer(struct ieee80211_sub_if_data *sdata) | |||
118 | round_jiffies_up(jiffies + IEEE80211_BEACON_LOSS_TIME)); | 118 | round_jiffies_up(jiffies + IEEE80211_BEACON_LOSS_TIME)); |
119 | } | 119 | } |
120 | 120 | ||
121 | void ieee80211_sta_reset_conn_monitor(struct ieee80211_sub_if_data *sdata) | ||
122 | { | ||
123 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | ||
124 | |||
125 | if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR) | ||
126 | return; | ||
127 | |||
128 | mod_timer(&sdata->u.mgd.conn_mon_timer, | ||
129 | round_jiffies_up(jiffies + IEEE80211_CONNECTION_IDLE_TIME)); | ||
130 | |||
131 | ifmgd->probe_send_count = 0; | ||
132 | } | ||
133 | |||
121 | static int ecw2cw(int ecw) | 134 | static int ecw2cw(int ecw) |
122 | { | 135 | { |
123 | return (1 << ecw) - 1; | 136 | return (1 << ecw) - 1; |
@@ -1006,21 +1019,26 @@ void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata, | |||
1006 | if (is_multicast_ether_addr(hdr->addr1)) | 1019 | if (is_multicast_ether_addr(hdr->addr1)) |
1007 | return; | 1020 | return; |
1008 | 1021 | ||
1009 | if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR) | 1022 | ieee80211_sta_reset_conn_monitor(sdata); |
1010 | return; | ||
1011 | |||
1012 | mod_timer(&sdata->u.mgd.conn_mon_timer, | ||
1013 | round_jiffies_up(jiffies + IEEE80211_CONNECTION_IDLE_TIME)); | ||
1014 | } | 1023 | } |
1015 | 1024 | ||
1016 | static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata) | 1025 | static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata) |
1017 | { | 1026 | { |
1018 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 1027 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
1019 | const u8 *ssid; | 1028 | const u8 *ssid; |
1029 | u8 *dst = ifmgd->associated->bssid; | ||
1030 | u8 unicast_limit = max(1, IEEE80211_MAX_PROBE_TRIES - 3); | ||
1031 | |||
1032 | /* | ||
1033 | * Try sending broadcast probe requests for the last three | ||
1034 | * probe requests after the first ones failed since some | ||
1035 | * buggy APs only support broadcast probe requests. | ||
1036 | */ | ||
1037 | if (ifmgd->probe_send_count >= unicast_limit) | ||
1038 | dst = NULL; | ||
1020 | 1039 | ||
1021 | ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID); | 1040 | ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID); |
1022 | ieee80211_send_probe_req(sdata, ifmgd->associated->bssid, | 1041 | ieee80211_send_probe_req(sdata, dst, ssid + 2, ssid[1], NULL, 0); |
1023 | ssid + 2, ssid[1], NULL, 0); | ||
1024 | 1042 | ||
1025 | ifmgd->probe_send_count++; | 1043 | ifmgd->probe_send_count++; |
1026 | ifmgd->probe_timeout = jiffies + IEEE80211_PROBE_WAIT; | 1044 | ifmgd->probe_timeout = jiffies + IEEE80211_PROBE_WAIT; |
@@ -1262,7 +1280,7 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk, | |||
1262 | 1280 | ||
1263 | rates = 0; | 1281 | rates = 0; |
1264 | basic_rates = 0; | 1282 | basic_rates = 0; |
1265 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | 1283 | sband = local->hw.wiphy->bands[wk->chan->band]; |
1266 | 1284 | ||
1267 | for (i = 0; i < elems.supp_rates_len; i++) { | 1285 | for (i = 0; i < elems.supp_rates_len; i++) { |
1268 | int rate = (elems.supp_rates[i] & 0x7f) * 5; | 1286 | int rate = (elems.supp_rates[i] & 0x7f) * 5; |
@@ -1298,11 +1316,11 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk, | |||
1298 | } | 1316 | } |
1299 | } | 1317 | } |
1300 | 1318 | ||
1301 | sta->sta.supp_rates[local->hw.conf.channel->band] = rates; | 1319 | sta->sta.supp_rates[wk->chan->band] = rates; |
1302 | sdata->vif.bss_conf.basic_rates = basic_rates; | 1320 | sdata->vif.bss_conf.basic_rates = basic_rates; |
1303 | 1321 | ||
1304 | /* cf. IEEE 802.11 9.2.12 */ | 1322 | /* cf. IEEE 802.11 9.2.12 */ |
1305 | if (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ && | 1323 | if (wk->chan->band == IEEE80211_BAND_2GHZ && |
1306 | have_higher_than_11mbit) | 1324 | have_higher_than_11mbit) |
1307 | sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE; | 1325 | sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE; |
1308 | else | 1326 | else |
@@ -1362,7 +1380,7 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk, | |||
1362 | * Also start the timer that will detect beacon loss. | 1380 | * Also start the timer that will detect beacon loss. |
1363 | */ | 1381 | */ |
1364 | ieee80211_sta_rx_notify(sdata, (struct ieee80211_hdr *)mgmt); | 1382 | ieee80211_sta_rx_notify(sdata, (struct ieee80211_hdr *)mgmt); |
1365 | mod_beacon_timer(sdata); | 1383 | ieee80211_sta_reset_beacon_monitor(sdata); |
1366 | 1384 | ||
1367 | return true; | 1385 | return true; |
1368 | } | 1386 | } |
@@ -1465,7 +1483,7 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata, | |||
1465 | * we have or will be receiving any beacons or data, so let's | 1483 | * we have or will be receiving any beacons or data, so let's |
1466 | * schedule the timers again, just in case. | 1484 | * schedule the timers again, just in case. |
1467 | */ | 1485 | */ |
1468 | mod_beacon_timer(sdata); | 1486 | ieee80211_sta_reset_beacon_monitor(sdata); |
1469 | 1487 | ||
1470 | mod_timer(&ifmgd->conn_mon_timer, | 1488 | mod_timer(&ifmgd->conn_mon_timer, |
1471 | round_jiffies_up(jiffies + | 1489 | round_jiffies_up(jiffies + |
@@ -1540,7 +1558,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
1540 | ifmgd->last_beacon_signal = rx_status->signal; | 1558 | ifmgd->last_beacon_signal = rx_status->signal; |
1541 | if (ifmgd->flags & IEEE80211_STA_RESET_SIGNAL_AVE) { | 1559 | if (ifmgd->flags & IEEE80211_STA_RESET_SIGNAL_AVE) { |
1542 | ifmgd->flags &= ~IEEE80211_STA_RESET_SIGNAL_AVE; | 1560 | ifmgd->flags &= ~IEEE80211_STA_RESET_SIGNAL_AVE; |
1543 | ifmgd->ave_beacon_signal = rx_status->signal; | 1561 | ifmgd->ave_beacon_signal = rx_status->signal * 16; |
1544 | ifmgd->last_cqm_event_signal = 0; | 1562 | ifmgd->last_cqm_event_signal = 0; |
1545 | } else { | 1563 | } else { |
1546 | ifmgd->ave_beacon_signal = | 1564 | ifmgd->ave_beacon_signal = |
@@ -1588,7 +1606,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
1588 | * Push the beacon loss detection into the future since | 1606 | * Push the beacon loss detection into the future since |
1589 | * we are processing a beacon from the AP just now. | 1607 | * we are processing a beacon from the AP just now. |
1590 | */ | 1608 | */ |
1591 | mod_beacon_timer(sdata); | 1609 | ieee80211_sta_reset_beacon_monitor(sdata); |
1592 | 1610 | ||
1593 | ncrc = crc32_be(0, (void *)&mgmt->u.beacon.beacon_int, 4); | 1611 | ncrc = crc32_be(0, (void *)&mgmt->u.beacon.beacon_int, 4); |
1594 | ncrc = ieee802_11_parse_elems_crc(mgmt->u.beacon.variable, | 1612 | ncrc = ieee802_11_parse_elems_crc(mgmt->u.beacon.variable, |
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c index c36b1911987a..cf5ee305785b 100644 --- a/net/mac80211/offchannel.c +++ b/net/mac80211/offchannel.c | |||
@@ -22,12 +22,16 @@ | |||
22 | static void ieee80211_offchannel_ps_enable(struct ieee80211_sub_if_data *sdata) | 22 | static void ieee80211_offchannel_ps_enable(struct ieee80211_sub_if_data *sdata) |
23 | { | 23 | { |
24 | struct ieee80211_local *local = sdata->local; | 24 | struct ieee80211_local *local = sdata->local; |
25 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | ||
25 | 26 | ||
26 | local->offchannel_ps_enabled = false; | 27 | local->offchannel_ps_enabled = false; |
27 | 28 | ||
28 | /* FIXME: what to do when local->pspolling is true? */ | 29 | /* FIXME: what to do when local->pspolling is true? */ |
29 | 30 | ||
30 | del_timer_sync(&local->dynamic_ps_timer); | 31 | del_timer_sync(&local->dynamic_ps_timer); |
32 | del_timer_sync(&ifmgd->bcn_mon_timer); | ||
33 | del_timer_sync(&ifmgd->conn_mon_timer); | ||
34 | |||
31 | cancel_work_sync(&local->dynamic_ps_enable_work); | 35 | cancel_work_sync(&local->dynamic_ps_enable_work); |
32 | 36 | ||
33 | if (local->hw.conf.flags & IEEE80211_CONF_PS) { | 37 | if (local->hw.conf.flags & IEEE80211_CONF_PS) { |
@@ -85,6 +89,9 @@ static void ieee80211_offchannel_ps_disable(struct ieee80211_sub_if_data *sdata) | |||
85 | mod_timer(&local->dynamic_ps_timer, jiffies + | 89 | mod_timer(&local->dynamic_ps_timer, jiffies + |
86 | msecs_to_jiffies(local->hw.conf.dynamic_ps_timeout)); | 90 | msecs_to_jiffies(local->hw.conf.dynamic_ps_timeout)); |
87 | } | 91 | } |
92 | |||
93 | ieee80211_sta_reset_beacon_monitor(sdata); | ||
94 | ieee80211_sta_reset_conn_monitor(sdata); | ||
88 | } | 95 | } |
89 | 96 | ||
90 | void ieee80211_offchannel_stop_beaconing(struct ieee80211_local *local) | 97 | void ieee80211_offchannel_stop_beaconing(struct ieee80211_local *local) |
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c index be04d46110fe..82d5750a110a 100644 --- a/net/mac80211/rate.c +++ b/net/mac80211/rate.c | |||
@@ -328,6 +328,9 @@ void rate_control_get_rate(struct ieee80211_sub_if_data *sdata, | |||
328 | * if needed. | 328 | * if needed. |
329 | */ | 329 | */ |
330 | for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { | 330 | for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { |
331 | /* Skip invalid rates */ | ||
332 | if (info->control.rates[i].idx < 0) | ||
333 | break; | ||
331 | /* Rate masking supports only legacy rates for now */ | 334 | /* Rate masking supports only legacy rates for now */ |
332 | if (info->control.rates[i].flags & IEEE80211_TX_RC_MCS) | 335 | if (info->control.rates[i].flags & IEEE80211_TX_RC_MCS) |
333 | continue; | 336 | continue; |
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c index c5b465904e3b..2a18d6602d4a 100644 --- a/net/mac80211/rc80211_minstrel_ht.c +++ b/net/mac80211/rc80211_minstrel_ht.c | |||
@@ -397,8 +397,9 @@ minstrel_ht_tx_status(void *priv, struct ieee80211_supported_band *sband, | |||
397 | !(info->flags & IEEE80211_TX_STAT_AMPDU)) | 397 | !(info->flags & IEEE80211_TX_STAT_AMPDU)) |
398 | return; | 398 | return; |
399 | 399 | ||
400 | if (!info->status.ampdu_len) { | 400 | if (!(info->flags & IEEE80211_TX_STAT_AMPDU)) { |
401 | info->status.ampdu_ack_len = 1; | 401 | info->status.ampdu_ack_len = |
402 | (info->flags & IEEE80211_TX_STAT_ACK ? 1 : 0); | ||
402 | info->status.ampdu_len = 1; | 403 | info->status.ampdu_len = 1; |
403 | } | 404 | } |
404 | 405 | ||
@@ -426,7 +427,7 @@ minstrel_ht_tx_status(void *priv, struct ieee80211_supported_band *sband, | |||
426 | group = minstrel_ht_get_group_idx(&ar[i]); | 427 | group = minstrel_ht_get_group_idx(&ar[i]); |
427 | rate = &mi->groups[group].rates[ar[i].idx % 8]; | 428 | rate = &mi->groups[group].rates[ar[i].idx % 8]; |
428 | 429 | ||
429 | if (last && (info->flags & IEEE80211_TX_STAT_ACK)) | 430 | if (last) |
430 | rate->success += info->status.ampdu_ack_len; | 431 | rate->success += info->status.ampdu_ack_len; |
431 | 432 | ||
432 | rate->attempts += ar[i].count * info->status.ampdu_len; | 433 | rate->attempts += ar[i].count * info->status.ampdu_len; |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 28624282c5f3..2bec9b9dba09 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -1715,6 +1715,8 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) | |||
1715 | if (!fwd_skb && net_ratelimit()) | 1715 | if (!fwd_skb && net_ratelimit()) |
1716 | printk(KERN_DEBUG "%s: failed to clone mesh frame\n", | 1716 | printk(KERN_DEBUG "%s: failed to clone mesh frame\n", |
1717 | sdata->name); | 1717 | sdata->name); |
1718 | if (!fwd_skb) | ||
1719 | goto out; | ||
1718 | 1720 | ||
1719 | fwd_hdr = (struct ieee80211_hdr *) fwd_skb->data; | 1721 | fwd_hdr = (struct ieee80211_hdr *) fwd_skb->data; |
1720 | memcpy(fwd_hdr->addr2, sdata->vif.addr, ETH_ALEN); | 1722 | memcpy(fwd_hdr->addr2, sdata->vif.addr, ETH_ALEN); |
@@ -1752,6 +1754,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) | |||
1752 | } | 1754 | } |
1753 | } | 1755 | } |
1754 | 1756 | ||
1757 | out: | ||
1755 | if (is_multicast_ether_addr(hdr->addr1) || | 1758 | if (is_multicast_ether_addr(hdr->addr1) || |
1756 | sdata->dev->flags & IFF_PROMISC) | 1759 | sdata->dev->flags & IFF_PROMISC) |
1757 | return RX_CONTINUE; | 1760 | return RX_CONTINUE; |
diff --git a/net/mac80211/status.c b/net/mac80211/status.c index 34da67995d94..6ffa26a9de39 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c | |||
@@ -58,6 +58,7 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, | |||
58 | info->control.vif = &sta->sdata->vif; | 58 | info->control.vif = &sta->sdata->vif; |
59 | info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING | | 59 | info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING | |
60 | IEEE80211_TX_INTFL_RETRANSMISSION; | 60 | IEEE80211_TX_INTFL_RETRANSMISSION; |
61 | info->flags &= ~IEEE80211_TX_TEMPORARY_FLAGS; | ||
61 | 62 | ||
62 | sta->tx_filtered_count++; | 63 | sta->tx_filtered_count++; |
63 | 64 | ||
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index c54db966926b..9d5af5dd0d98 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -1694,7 +1694,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1694 | { | 1694 | { |
1695 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 1695 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
1696 | struct ieee80211_local *local = sdata->local; | 1696 | struct ieee80211_local *local = sdata->local; |
1697 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 1697 | struct ieee80211_tx_info *info; |
1698 | int ret = NETDEV_TX_BUSY, head_need; | 1698 | int ret = NETDEV_TX_BUSY, head_need; |
1699 | u16 ethertype, hdrlen, meshhdrlen = 0; | 1699 | u16 ethertype, hdrlen, meshhdrlen = 0; |
1700 | __le16 fc; | 1700 | __le16 fc; |
@@ -1705,15 +1705,13 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1705 | int nh_pos, h_pos; | 1705 | int nh_pos, h_pos; |
1706 | struct sta_info *sta = NULL; | 1706 | struct sta_info *sta = NULL; |
1707 | u32 sta_flags = 0; | 1707 | u32 sta_flags = 0; |
1708 | struct sk_buff *tmp_skb; | ||
1708 | 1709 | ||
1709 | if (unlikely(skb->len < ETH_HLEN)) { | 1710 | if (unlikely(skb->len < ETH_HLEN)) { |
1710 | ret = NETDEV_TX_OK; | 1711 | ret = NETDEV_TX_OK; |
1711 | goto fail; | 1712 | goto fail; |
1712 | } | 1713 | } |
1713 | 1714 | ||
1714 | nh_pos = skb_network_header(skb) - skb->data; | ||
1715 | h_pos = skb_transport_header(skb) - skb->data; | ||
1716 | |||
1717 | /* convert Ethernet header to proper 802.11 header (based on | 1715 | /* convert Ethernet header to proper 802.11 header (based on |
1718 | * operation mode) */ | 1716 | * operation mode) */ |
1719 | ethertype = (skb->data[12] << 8) | skb->data[13]; | 1717 | ethertype = (skb->data[12] << 8) | skb->data[13]; |
@@ -1885,6 +1883,20 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1885 | goto fail; | 1883 | goto fail; |
1886 | } | 1884 | } |
1887 | 1885 | ||
1886 | /* | ||
1887 | * If the skb is shared we need to obtain our own copy. | ||
1888 | */ | ||
1889 | if (skb_shared(skb)) { | ||
1890 | tmp_skb = skb; | ||
1891 | skb = skb_copy(skb, GFP_ATOMIC); | ||
1892 | kfree_skb(tmp_skb); | ||
1893 | |||
1894 | if (!skb) { | ||
1895 | ret = NETDEV_TX_OK; | ||
1896 | goto fail; | ||
1897 | } | ||
1898 | } | ||
1899 | |||
1888 | hdr.frame_control = fc; | 1900 | hdr.frame_control = fc; |
1889 | hdr.duration_id = 0; | 1901 | hdr.duration_id = 0; |
1890 | hdr.seq_ctrl = 0; | 1902 | hdr.seq_ctrl = 0; |
@@ -1903,6 +1915,9 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1903 | encaps_len = 0; | 1915 | encaps_len = 0; |
1904 | } | 1916 | } |
1905 | 1917 | ||
1918 | nh_pos = skb_network_header(skb) - skb->data; | ||
1919 | h_pos = skb_transport_header(skb) - skb->data; | ||
1920 | |||
1906 | skb_pull(skb, skip_header_bytes); | 1921 | skb_pull(skb, skip_header_bytes); |
1907 | nh_pos -= skip_header_bytes; | 1922 | nh_pos -= skip_header_bytes; |
1908 | h_pos -= skip_header_bytes; | 1923 | h_pos -= skip_header_bytes; |
@@ -1969,6 +1984,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1969 | skb_set_network_header(skb, nh_pos); | 1984 | skb_set_network_header(skb, nh_pos); |
1970 | skb_set_transport_header(skb, h_pos); | 1985 | skb_set_transport_header(skb, h_pos); |
1971 | 1986 | ||
1987 | info = IEEE80211_SKB_CB(skb); | ||
1972 | memset(info, 0, sizeof(*info)); | 1988 | memset(info, 0, sizeof(*info)); |
1973 | 1989 | ||
1974 | dev->trans_start = jiffies; | 1990 | dev->trans_start = jiffies; |
@@ -2160,6 +2176,9 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw, | |||
2160 | 2176 | ||
2161 | sdata = vif_to_sdata(vif); | 2177 | sdata = vif_to_sdata(vif); |
2162 | 2178 | ||
2179 | if (!ieee80211_sdata_running(sdata)) | ||
2180 | goto out; | ||
2181 | |||
2163 | if (tim_offset) | 2182 | if (tim_offset) |
2164 | *tim_offset = 0; | 2183 | *tim_offset = 0; |
2165 | if (tim_length) | 2184 | if (tim_length) |
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index df3eedb142ff..a37a6b188eda 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c | |||
@@ -1260,7 +1260,8 @@ void *nf_ct_alloc_hashtable(unsigned int *sizep, int *vmalloced, int nulls) | |||
1260 | if (!hash) { | 1260 | if (!hash) { |
1261 | *vmalloced = 1; | 1261 | *vmalloced = 1; |
1262 | printk(KERN_WARNING "nf_conntrack: falling back to vmalloc.\n"); | 1262 | printk(KERN_WARNING "nf_conntrack: falling back to vmalloc.\n"); |
1263 | hash = __vmalloc(sz, GFP_KERNEL | __GFP_ZERO, PAGE_KERNEL); | 1263 | hash = __vmalloc(sz, GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, |
1264 | PAGE_KERNEL); | ||
1264 | } | 1265 | } |
1265 | 1266 | ||
1266 | if (hash && nulls) | 1267 | if (hash && nulls) |
diff --git a/net/netfilter/xt_SECMARK.c b/net/netfilter/xt_SECMARK.c index 23b2d6c486b5..364ad1600129 100644 --- a/net/netfilter/xt_SECMARK.c +++ b/net/netfilter/xt_SECMARK.c | |||
@@ -101,7 +101,7 @@ static int secmark_tg_check(const struct xt_tgchk_param *par) | |||
101 | switch (info->mode) { | 101 | switch (info->mode) { |
102 | case SECMARK_MODE_SEL: | 102 | case SECMARK_MODE_SEL: |
103 | err = checkentry_selinux(info); | 103 | err = checkentry_selinux(info); |
104 | if (err <= 0) | 104 | if (err) |
105 | return err; | 105 | return err; |
106 | break; | 106 | break; |
107 | 107 | ||
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 9a17f28b1253..9ba70146a4fe 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
@@ -1610,9 +1610,11 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
1610 | 1610 | ||
1611 | err = -EINVAL; | 1611 | err = -EINVAL; |
1612 | vnet_hdr_len = sizeof(vnet_hdr); | 1612 | vnet_hdr_len = sizeof(vnet_hdr); |
1613 | if ((len -= vnet_hdr_len) < 0) | 1613 | if (len < vnet_hdr_len) |
1614 | goto out_free; | 1614 | goto out_free; |
1615 | 1615 | ||
1616 | len -= vnet_hdr_len; | ||
1617 | |||
1616 | if (skb_is_gso(skb)) { | 1618 | if (skb_is_gso(skb)) { |
1617 | struct skb_shared_info *sinfo = skb_shinfo(skb); | 1619 | struct skb_shared_info *sinfo = skb_shinfo(skb); |
1618 | 1620 | ||
@@ -1719,7 +1721,7 @@ static int packet_getname_spkt(struct socket *sock, struct sockaddr *uaddr, | |||
1719 | rcu_read_lock(); | 1721 | rcu_read_lock(); |
1720 | dev = dev_get_by_index_rcu(sock_net(sk), pkt_sk(sk)->ifindex); | 1722 | dev = dev_get_by_index_rcu(sock_net(sk), pkt_sk(sk)->ifindex); |
1721 | if (dev) | 1723 | if (dev) |
1722 | strlcpy(uaddr->sa_data, dev->name, 15); | 1724 | strncpy(uaddr->sa_data, dev->name, 14); |
1723 | else | 1725 | else |
1724 | memset(uaddr->sa_data, 0, 14); | 1726 | memset(uaddr->sa_data, 0, 14); |
1725 | rcu_read_unlock(); | 1727 | rcu_read_unlock(); |
@@ -1742,6 +1744,7 @@ static int packet_getname(struct socket *sock, struct sockaddr *uaddr, | |||
1742 | sll->sll_family = AF_PACKET; | 1744 | sll->sll_family = AF_PACKET; |
1743 | sll->sll_ifindex = po->ifindex; | 1745 | sll->sll_ifindex = po->ifindex; |
1744 | sll->sll_protocol = po->num; | 1746 | sll->sll_protocol = po->num; |
1747 | sll->sll_pkttype = 0; | ||
1745 | rcu_read_lock(); | 1748 | rcu_read_lock(); |
1746 | dev = dev_get_by_index_rcu(sock_net(sk), po->ifindex); | 1749 | dev = dev_get_by_index_rcu(sock_net(sk), po->ifindex); |
1747 | if (dev) { | 1750 | if (dev) { |
diff --git a/net/rds/rdma.c b/net/rds/rdma.c index 75fd13bb631b..39989678c2d2 100644 --- a/net/rds/rdma.c +++ b/net/rds/rdma.c | |||
@@ -474,7 +474,7 @@ static struct rds_rdma_op *rds_rdma_prepare(struct rds_sock *rs, | |||
474 | goto out; | 474 | goto out; |
475 | } | 475 | } |
476 | 476 | ||
477 | if (args->nr_local > (u64)UINT_MAX) { | 477 | if (args->nr_local > UIO_MAXIOV) { |
478 | ret = -EMSGSIZE; | 478 | ret = -EMSGSIZE; |
479 | goto out; | 479 | goto out; |
480 | } | 480 | } |
diff --git a/net/sched/cls_cgroup.c b/net/sched/cls_cgroup.c index 78ef2c5e130b..08be223fb3dc 100644 --- a/net/sched/cls_cgroup.c +++ b/net/sched/cls_cgroup.c | |||
@@ -34,8 +34,6 @@ struct cgroup_subsys net_cls_subsys = { | |||
34 | .populate = cgrp_populate, | 34 | .populate = cgrp_populate, |
35 | #ifdef CONFIG_NET_CLS_CGROUP | 35 | #ifdef CONFIG_NET_CLS_CGROUP |
36 | .subsys_id = net_cls_subsys_id, | 36 | .subsys_id = net_cls_subsys_id, |
37 | #else | ||
38 | #define net_cls_subsys_id net_cls_subsys.subsys_id | ||
39 | #endif | 37 | #endif |
40 | .module = THIS_MODULE, | 38 | .module = THIS_MODULE, |
41 | }; | 39 | }; |
diff --git a/net/socket.c b/net/socket.c index 2270b941bcc7..58dfc915a3a5 100644 --- a/net/socket.c +++ b/net/socket.c | |||
@@ -1651,6 +1651,8 @@ SYSCALL_DEFINE6(sendto, int, fd, void __user *, buff, size_t, len, | |||
1651 | struct iovec iov; | 1651 | struct iovec iov; |
1652 | int fput_needed; | 1652 | int fput_needed; |
1653 | 1653 | ||
1654 | if (len > INT_MAX) | ||
1655 | len = INT_MAX; | ||
1654 | sock = sockfd_lookup_light(fd, &err, &fput_needed); | 1656 | sock = sockfd_lookup_light(fd, &err, &fput_needed); |
1655 | if (!sock) | 1657 | if (!sock) |
1656 | goto out; | 1658 | goto out; |
@@ -1708,6 +1710,8 @@ SYSCALL_DEFINE6(recvfrom, int, fd, void __user *, ubuf, size_t, size, | |||
1708 | int err, err2; | 1710 | int err, err2; |
1709 | int fput_needed; | 1711 | int fput_needed; |
1710 | 1712 | ||
1713 | if (size > INT_MAX) | ||
1714 | size = INT_MAX; | ||
1711 | sock = sockfd_lookup_light(fd, &err, &fput_needed); | 1715 | sock = sockfd_lookup_light(fd, &err, &fput_needed); |
1712 | if (!sock) | 1716 | if (!sock) |
1713 | goto out; | 1717 | goto out; |
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index fa5549079d79..cbc5b8ccc8be 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c | |||
@@ -1675,7 +1675,7 @@ rpc_verify_header(struct rpc_task *task) | |||
1675 | rpcauth_invalcred(task); | 1675 | rpcauth_invalcred(task); |
1676 | /* Ensure we obtain a new XID! */ | 1676 | /* Ensure we obtain a new XID! */ |
1677 | xprt_release(task); | 1677 | xprt_release(task); |
1678 | task->tk_action = call_refresh; | 1678 | task->tk_action = call_reserve; |
1679 | goto out_retry; | 1679 | goto out_retry; |
1680 | case RPC_AUTH_BADCRED: | 1680 | case RPC_AUTH_BADCRED: |
1681 | case RPC_AUTH_BADVERF: | 1681 | case RPC_AUTH_BADVERF: |
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c index cbc084939dd8..2f5fb71854d3 100644 --- a/net/sunrpc/svc_xprt.c +++ b/net/sunrpc/svc_xprt.c | |||
@@ -212,6 +212,7 @@ int svc_create_xprt(struct svc_serv *serv, const char *xprt_name, | |||
212 | spin_lock(&svc_xprt_class_lock); | 212 | spin_lock(&svc_xprt_class_lock); |
213 | list_for_each_entry(xcl, &svc_xprt_class_list, xcl_list) { | 213 | list_for_each_entry(xcl, &svc_xprt_class_list, xcl_list) { |
214 | struct svc_xprt *newxprt; | 214 | struct svc_xprt *newxprt; |
215 | unsigned short newport; | ||
215 | 216 | ||
216 | if (strcmp(xprt_name, xcl->xcl_name)) | 217 | if (strcmp(xprt_name, xcl->xcl_name)) |
217 | continue; | 218 | continue; |
@@ -230,8 +231,9 @@ int svc_create_xprt(struct svc_serv *serv, const char *xprt_name, | |||
230 | spin_lock_bh(&serv->sv_lock); | 231 | spin_lock_bh(&serv->sv_lock); |
231 | list_add(&newxprt->xpt_list, &serv->sv_permsocks); | 232 | list_add(&newxprt->xpt_list, &serv->sv_permsocks); |
232 | spin_unlock_bh(&serv->sv_lock); | 233 | spin_unlock_bh(&serv->sv_lock); |
234 | newport = svc_xprt_local_port(newxprt); | ||
233 | clear_bit(XPT_BUSY, &newxprt->xpt_flags); | 235 | clear_bit(XPT_BUSY, &newxprt->xpt_flags); |
234 | return svc_xprt_local_port(newxprt); | 236 | return newport; |
235 | } | 237 | } |
236 | err: | 238 | err: |
237 | spin_unlock(&svc_xprt_class_lock); | 239 | spin_unlock(&svc_xprt_class_lock); |
@@ -431,8 +433,13 @@ void svc_xprt_received(struct svc_xprt *xprt) | |||
431 | { | 433 | { |
432 | BUG_ON(!test_bit(XPT_BUSY, &xprt->xpt_flags)); | 434 | BUG_ON(!test_bit(XPT_BUSY, &xprt->xpt_flags)); |
433 | xprt->xpt_pool = NULL; | 435 | xprt->xpt_pool = NULL; |
436 | /* As soon as we clear busy, the xprt could be closed and | ||
437 | * 'put', so we need a reference to call svc_xprt_enqueue with: | ||
438 | */ | ||
439 | svc_xprt_get(xprt); | ||
434 | clear_bit(XPT_BUSY, &xprt->xpt_flags); | 440 | clear_bit(XPT_BUSY, &xprt->xpt_flags); |
435 | svc_xprt_enqueue(xprt); | 441 | svc_xprt_enqueue(xprt); |
442 | svc_xprt_put(xprt); | ||
436 | } | 443 | } |
437 | EXPORT_SYMBOL_GPL(svc_xprt_received); | 444 | EXPORT_SYMBOL_GPL(svc_xprt_received); |
438 | 445 | ||
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 0b39b2451ea5..b4cfe207a6ac 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c | |||
@@ -1343,9 +1343,25 @@ static void unix_destruct_scm(struct sk_buff *skb) | |||
1343 | sock_wfree(skb); | 1343 | sock_wfree(skb); |
1344 | } | 1344 | } |
1345 | 1345 | ||
1346 | #define MAX_RECURSION_LEVEL 4 | ||
1347 | |||
1346 | static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb) | 1348 | static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb) |
1347 | { | 1349 | { |
1348 | int i; | 1350 | int i; |
1351 | unsigned char max_level = 0; | ||
1352 | int unix_sock_count = 0; | ||
1353 | |||
1354 | for (i = scm->fp->count - 1; i >= 0; i--) { | ||
1355 | struct sock *sk = unix_get_socket(scm->fp->fp[i]); | ||
1356 | |||
1357 | if (sk) { | ||
1358 | unix_sock_count++; | ||
1359 | max_level = max(max_level, | ||
1360 | unix_sk(sk)->recursion_level); | ||
1361 | } | ||
1362 | } | ||
1363 | if (unlikely(max_level > MAX_RECURSION_LEVEL)) | ||
1364 | return -ETOOMANYREFS; | ||
1349 | 1365 | ||
1350 | /* | 1366 | /* |
1351 | * Need to duplicate file references for the sake of garbage | 1367 | * Need to duplicate file references for the sake of garbage |
@@ -1356,9 +1372,11 @@ static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb) | |||
1356 | if (!UNIXCB(skb).fp) | 1372 | if (!UNIXCB(skb).fp) |
1357 | return -ENOMEM; | 1373 | return -ENOMEM; |
1358 | 1374 | ||
1359 | for (i = scm->fp->count-1; i >= 0; i--) | 1375 | if (unix_sock_count) { |
1360 | unix_inflight(scm->fp->fp[i]); | 1376 | for (i = scm->fp->count - 1; i >= 0; i--) |
1361 | return 0; | 1377 | unix_inflight(scm->fp->fp[i]); |
1378 | } | ||
1379 | return max_level; | ||
1362 | } | 1380 | } |
1363 | 1381 | ||
1364 | static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool send_fds) | 1382 | static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool send_fds) |
@@ -1393,6 +1411,7 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
1393 | struct sk_buff *skb; | 1411 | struct sk_buff *skb; |
1394 | long timeo; | 1412 | long timeo; |
1395 | struct scm_cookie tmp_scm; | 1413 | struct scm_cookie tmp_scm; |
1414 | int max_level; | ||
1396 | 1415 | ||
1397 | if (NULL == siocb->scm) | 1416 | if (NULL == siocb->scm) |
1398 | siocb->scm = &tmp_scm; | 1417 | siocb->scm = &tmp_scm; |
@@ -1431,8 +1450,9 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
1431 | goto out; | 1450 | goto out; |
1432 | 1451 | ||
1433 | err = unix_scm_to_skb(siocb->scm, skb, true); | 1452 | err = unix_scm_to_skb(siocb->scm, skb, true); |
1434 | if (err) | 1453 | if (err < 0) |
1435 | goto out_free; | 1454 | goto out_free; |
1455 | max_level = err + 1; | ||
1436 | unix_get_secdata(siocb->scm, skb); | 1456 | unix_get_secdata(siocb->scm, skb); |
1437 | 1457 | ||
1438 | skb_reset_transport_header(skb); | 1458 | skb_reset_transport_header(skb); |
@@ -1512,6 +1532,8 @@ restart: | |||
1512 | } | 1532 | } |
1513 | 1533 | ||
1514 | skb_queue_tail(&other->sk_receive_queue, skb); | 1534 | skb_queue_tail(&other->sk_receive_queue, skb); |
1535 | if (max_level > unix_sk(other)->recursion_level) | ||
1536 | unix_sk(other)->recursion_level = max_level; | ||
1515 | unix_state_unlock(other); | 1537 | unix_state_unlock(other); |
1516 | other->sk_data_ready(other, len); | 1538 | other->sk_data_ready(other, len); |
1517 | sock_put(other); | 1539 | sock_put(other); |
@@ -1542,6 +1564,7 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
1542 | int sent = 0; | 1564 | int sent = 0; |
1543 | struct scm_cookie tmp_scm; | 1565 | struct scm_cookie tmp_scm; |
1544 | bool fds_sent = false; | 1566 | bool fds_sent = false; |
1567 | int max_level; | ||
1545 | 1568 | ||
1546 | if (NULL == siocb->scm) | 1569 | if (NULL == siocb->scm) |
1547 | siocb->scm = &tmp_scm; | 1570 | siocb->scm = &tmp_scm; |
@@ -1605,10 +1628,11 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
1605 | 1628 | ||
1606 | /* Only send the fds in the first buffer */ | 1629 | /* Only send the fds in the first buffer */ |
1607 | err = unix_scm_to_skb(siocb->scm, skb, !fds_sent); | 1630 | err = unix_scm_to_skb(siocb->scm, skb, !fds_sent); |
1608 | if (err) { | 1631 | if (err < 0) { |
1609 | kfree_skb(skb); | 1632 | kfree_skb(skb); |
1610 | goto out_err; | 1633 | goto out_err; |
1611 | } | 1634 | } |
1635 | max_level = err + 1; | ||
1612 | fds_sent = true; | 1636 | fds_sent = true; |
1613 | 1637 | ||
1614 | err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size); | 1638 | err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size); |
@@ -1624,6 +1648,8 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
1624 | goto pipe_err_free; | 1648 | goto pipe_err_free; |
1625 | 1649 | ||
1626 | skb_queue_tail(&other->sk_receive_queue, skb); | 1650 | skb_queue_tail(&other->sk_receive_queue, skb); |
1651 | if (max_level > unix_sk(other)->recursion_level) | ||
1652 | unix_sk(other)->recursion_level = max_level; | ||
1627 | unix_state_unlock(other); | 1653 | unix_state_unlock(other); |
1628 | other->sk_data_ready(other, size); | 1654 | other->sk_data_ready(other, size); |
1629 | sent += size; | 1655 | sent += size; |
@@ -1840,6 +1866,7 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
1840 | unix_state_lock(sk); | 1866 | unix_state_lock(sk); |
1841 | skb = skb_dequeue(&sk->sk_receive_queue); | 1867 | skb = skb_dequeue(&sk->sk_receive_queue); |
1842 | if (skb == NULL) { | 1868 | if (skb == NULL) { |
1869 | unix_sk(sk)->recursion_level = 0; | ||
1843 | if (copied >= target) | 1870 | if (copied >= target) |
1844 | goto unlock; | 1871 | goto unlock; |
1845 | 1872 | ||
diff --git a/net/unix/garbage.c b/net/unix/garbage.c index c8df6fda0b1f..f89f83bf828e 100644 --- a/net/unix/garbage.c +++ b/net/unix/garbage.c | |||
@@ -96,7 +96,7 @@ static DECLARE_WAIT_QUEUE_HEAD(unix_gc_wait); | |||
96 | unsigned int unix_tot_inflight; | 96 | unsigned int unix_tot_inflight; |
97 | 97 | ||
98 | 98 | ||
99 | static struct sock *unix_get_socket(struct file *filp) | 99 | struct sock *unix_get_socket(struct file *filp) |
100 | { | 100 | { |
101 | struct sock *u_sock = NULL; | 101 | struct sock *u_sock = NULL; |
102 | struct inode *inode = filp->f_path.dentry->d_inode; | 102 | struct inode *inode = filp->f_path.dentry->d_inode; |
@@ -259,9 +259,16 @@ static void inc_inflight_move_tail(struct unix_sock *u) | |||
259 | } | 259 | } |
260 | 260 | ||
261 | static bool gc_in_progress = false; | 261 | static bool gc_in_progress = false; |
262 | #define UNIX_INFLIGHT_TRIGGER_GC 16000 | ||
262 | 263 | ||
263 | void wait_for_unix_gc(void) | 264 | void wait_for_unix_gc(void) |
264 | { | 265 | { |
266 | /* | ||
267 | * If number of inflight sockets is insane, | ||
268 | * force a garbage collect right now. | ||
269 | */ | ||
270 | if (unix_tot_inflight > UNIX_INFLIGHT_TRIGGER_GC && !gc_in_progress) | ||
271 | unix_gc(); | ||
265 | wait_event(unix_gc_wait, gc_in_progress == false); | 272 | wait_event(unix_gc_wait, gc_in_progress == false); |
266 | } | 273 | } |
267 | 274 | ||
diff --git a/net/wireless/chan.c b/net/wireless/chan.c index d0c92dddb26b..d8f443b70b08 100644 --- a/net/wireless/chan.c +++ b/net/wireless/chan.c | |||
@@ -44,6 +44,36 @@ rdev_freq_to_chan(struct cfg80211_registered_device *rdev, | |||
44 | return chan; | 44 | return chan; |
45 | } | 45 | } |
46 | 46 | ||
47 | static bool can_beacon_sec_chan(struct wiphy *wiphy, | ||
48 | struct ieee80211_channel *chan, | ||
49 | enum nl80211_channel_type channel_type) | ||
50 | { | ||
51 | struct ieee80211_channel *sec_chan; | ||
52 | int diff; | ||
53 | |||
54 | switch (channel_type) { | ||
55 | case NL80211_CHAN_HT40PLUS: | ||
56 | diff = 20; | ||
57 | case NL80211_CHAN_HT40MINUS: | ||
58 | diff = -20; | ||
59 | default: | ||
60 | return false; | ||
61 | } | ||
62 | |||
63 | sec_chan = ieee80211_get_channel(wiphy, chan->center_freq + diff); | ||
64 | if (!sec_chan) | ||
65 | return false; | ||
66 | |||
67 | /* we'll need a DFS capability later */ | ||
68 | if (sec_chan->flags & (IEEE80211_CHAN_DISABLED | | ||
69 | IEEE80211_CHAN_PASSIVE_SCAN | | ||
70 | IEEE80211_CHAN_NO_IBSS | | ||
71 | IEEE80211_CHAN_RADAR)) | ||
72 | return false; | ||
73 | |||
74 | return true; | ||
75 | } | ||
76 | |||
47 | int cfg80211_set_freq(struct cfg80211_registered_device *rdev, | 77 | int cfg80211_set_freq(struct cfg80211_registered_device *rdev, |
48 | struct wireless_dev *wdev, int freq, | 78 | struct wireless_dev *wdev, int freq, |
49 | enum nl80211_channel_type channel_type) | 79 | enum nl80211_channel_type channel_type) |
@@ -68,6 +98,27 @@ int cfg80211_set_freq(struct cfg80211_registered_device *rdev, | |||
68 | if (!chan) | 98 | if (!chan) |
69 | return -EINVAL; | 99 | return -EINVAL; |
70 | 100 | ||
101 | /* Both channels should be able to initiate communication */ | ||
102 | if (wdev && (wdev->iftype == NL80211_IFTYPE_ADHOC || | ||
103 | wdev->iftype == NL80211_IFTYPE_AP || | ||
104 | wdev->iftype == NL80211_IFTYPE_AP_VLAN || | ||
105 | wdev->iftype == NL80211_IFTYPE_MESH_POINT)) { | ||
106 | switch (channel_type) { | ||
107 | case NL80211_CHAN_HT40PLUS: | ||
108 | case NL80211_CHAN_HT40MINUS: | ||
109 | if (!can_beacon_sec_chan(&rdev->wiphy, chan, | ||
110 | channel_type)) { | ||
111 | printk(KERN_DEBUG | ||
112 | "cfg80211: Secondary channel not " | ||
113 | "allowed to initiate communication\n"); | ||
114 | return -EINVAL; | ||
115 | } | ||
116 | break; | ||
117 | default: | ||
118 | break; | ||
119 | } | ||
120 | } | ||
121 | |||
71 | result = rdev->ops->set_channel(&rdev->wiphy, | 122 | result = rdev->ops->set_channel(&rdev->wiphy, |
72 | wdev ? wdev->netdev : NULL, | 123 | wdev ? wdev->netdev : NULL, |
73 | chan, channel_type); | 124 | chan, channel_type); |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 37902a54e9c1..9a8cde999955 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -761,11 +761,13 @@ static int nl80211_set_channel(struct sk_buff *skb, struct genl_info *info) | |||
761 | 761 | ||
762 | result = get_rdev_dev_by_info_ifindex(info, &rdev, &netdev); | 762 | result = get_rdev_dev_by_info_ifindex(info, &rdev, &netdev); |
763 | if (result) | 763 | if (result) |
764 | goto unlock; | 764 | goto unlock_rtnl; |
765 | 765 | ||
766 | result = __nl80211_set_channel(rdev, netdev->ieee80211_ptr, info); | 766 | result = __nl80211_set_channel(rdev, netdev->ieee80211_ptr, info); |
767 | 767 | ||
768 | unlock: | 768 | dev_put(netdev); |
769 | cfg80211_unlock_rdev(rdev); | ||
770 | unlock_rtnl: | ||
769 | rtnl_unlock(); | 771 | rtnl_unlock(); |
770 | 772 | ||
771 | return result; | 773 | return result; |
@@ -4996,7 +4998,7 @@ static int nl80211_set_cqm_rssi(struct genl_info *info, | |||
4996 | 4998 | ||
4997 | err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); | 4999 | err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); |
4998 | if (err) | 5000 | if (err) |
4999 | goto unlock_rdev; | 5001 | goto unlock_rtnl; |
5000 | 5002 | ||
5001 | wdev = dev->ieee80211_ptr; | 5003 | wdev = dev->ieee80211_ptr; |
5002 | 5004 | ||
@@ -5013,9 +5015,10 @@ static int nl80211_set_cqm_rssi(struct genl_info *info, | |||
5013 | err = rdev->ops->set_cqm_rssi_config(wdev->wiphy, dev, | 5015 | err = rdev->ops->set_cqm_rssi_config(wdev->wiphy, dev, |
5014 | threshold, hysteresis); | 5016 | threshold, hysteresis); |
5015 | 5017 | ||
5016 | unlock_rdev: | 5018 | unlock_rdev: |
5017 | cfg80211_unlock_rdev(rdev); | 5019 | cfg80211_unlock_rdev(rdev); |
5018 | dev_put(dev); | 5020 | dev_put(dev); |
5021 | unlock_rtnl: | ||
5019 | rtnl_unlock(); | 5022 | rtnl_unlock(); |
5020 | 5023 | ||
5021 | return err; | 5024 | return err; |
diff --git a/net/wireless/reg.c b/net/wireless/reg.c index f180db0de66c..edccc093e71b 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c | |||
@@ -723,7 +723,9 @@ EXPORT_SYMBOL(freq_reg_info); | |||
723 | * on the wiphy with the target_bw specified. Then we can simply use | 723 | * on the wiphy with the target_bw specified. Then we can simply use |
724 | * that below for the desired_bw_khz below. | 724 | * that below for the desired_bw_khz below. |
725 | */ | 725 | */ |
726 | static void handle_channel(struct wiphy *wiphy, enum ieee80211_band band, | 726 | static void handle_channel(struct wiphy *wiphy, |
727 | enum nl80211_reg_initiator initiator, | ||
728 | enum ieee80211_band band, | ||
727 | unsigned int chan_idx) | 729 | unsigned int chan_idx) |
728 | { | 730 | { |
729 | int r; | 731 | int r; |
@@ -787,7 +789,9 @@ static void handle_channel(struct wiphy *wiphy, enum ieee80211_band band, | |||
787 | chan->max_power = (int) MBM_TO_DBM(power_rule->max_eirp); | 789 | chan->max_power = (int) MBM_TO_DBM(power_rule->max_eirp); |
788 | } | 790 | } |
789 | 791 | ||
790 | static void handle_band(struct wiphy *wiphy, enum ieee80211_band band) | 792 | static void handle_band(struct wiphy *wiphy, |
793 | enum ieee80211_band band, | ||
794 | enum nl80211_reg_initiator initiator) | ||
791 | { | 795 | { |
792 | unsigned int i; | 796 | unsigned int i; |
793 | struct ieee80211_supported_band *sband; | 797 | struct ieee80211_supported_band *sband; |
@@ -796,7 +800,7 @@ static void handle_band(struct wiphy *wiphy, enum ieee80211_band band) | |||
796 | sband = wiphy->bands[band]; | 800 | sband = wiphy->bands[band]; |
797 | 801 | ||
798 | for (i = 0; i < sband->n_channels; i++) | 802 | for (i = 0; i < sband->n_channels; i++) |
799 | handle_channel(wiphy, band, i); | 803 | handle_channel(wiphy, initiator, band, i); |
800 | } | 804 | } |
801 | 805 | ||
802 | static bool ignore_reg_update(struct wiphy *wiphy, | 806 | static bool ignore_reg_update(struct wiphy *wiphy, |
@@ -812,6 +816,7 @@ static bool ignore_reg_update(struct wiphy *wiphy, | |||
812 | * desired regulatory domain set | 816 | * desired regulatory domain set |
813 | */ | 817 | */ |
814 | if (wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY && !wiphy->regd && | 818 | if (wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY && !wiphy->regd && |
819 | initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE && | ||
815 | !is_world_regdom(last_request->alpha2)) | 820 | !is_world_regdom(last_request->alpha2)) |
816 | return true; | 821 | return true; |
817 | return false; | 822 | return false; |
@@ -1033,7 +1038,7 @@ void wiphy_update_regulatory(struct wiphy *wiphy, | |||
1033 | goto out; | 1038 | goto out; |
1034 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { | 1039 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { |
1035 | if (wiphy->bands[band]) | 1040 | if (wiphy->bands[band]) |
1036 | handle_band(wiphy, band); | 1041 | handle_band(wiphy, band, initiator); |
1037 | } | 1042 | } |
1038 | out: | 1043 | out: |
1039 | reg_process_beacons(wiphy); | 1044 | reg_process_beacons(wiphy); |
@@ -1170,7 +1175,7 @@ static int ignore_request(struct wiphy *wiphy, | |||
1170 | return 0; | 1175 | return 0; |
1171 | return -EALREADY; | 1176 | return -EALREADY; |
1172 | } | 1177 | } |
1173 | return REG_INTERSECT; | 1178 | return 0; |
1174 | case NL80211_REGDOM_SET_BY_DRIVER: | 1179 | case NL80211_REGDOM_SET_BY_DRIVER: |
1175 | if (last_request->initiator == NL80211_REGDOM_SET_BY_CORE) { | 1180 | if (last_request->initiator == NL80211_REGDOM_SET_BY_CORE) { |
1176 | if (regdom_changes(pending_request->alpha2)) | 1181 | if (regdom_changes(pending_request->alpha2)) |
diff --git a/net/wireless/scan.c b/net/wireless/scan.c index 5ca8c7180141..503ebb86ba18 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c | |||
@@ -650,14 +650,14 @@ void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *pub) | |||
650 | bss = container_of(pub, struct cfg80211_internal_bss, pub); | 650 | bss = container_of(pub, struct cfg80211_internal_bss, pub); |
651 | 651 | ||
652 | spin_lock_bh(&dev->bss_lock); | 652 | spin_lock_bh(&dev->bss_lock); |
653 | if (!list_empty(&bss->list)) { | ||
654 | list_del_init(&bss->list); | ||
655 | dev->bss_generation++; | ||
656 | rb_erase(&bss->rbn, &dev->bss_tree); | ||
653 | 657 | ||
654 | list_del(&bss->list); | 658 | kref_put(&bss->ref, bss_release); |
655 | dev->bss_generation++; | 659 | } |
656 | rb_erase(&bss->rbn, &dev->bss_tree); | ||
657 | |||
658 | spin_unlock_bh(&dev->bss_lock); | 660 | spin_unlock_bh(&dev->bss_lock); |
659 | |||
660 | kref_put(&bss->ref, bss_release); | ||
661 | } | 661 | } |
662 | EXPORT_SYMBOL(cfg80211_unlink_bss); | 662 | EXPORT_SYMBOL(cfg80211_unlink_bss); |
663 | 663 | ||
diff --git a/net/x25/x25_facilities.c b/net/x25/x25_facilities.c index 771bab00754b..55187c8f6420 100644 --- a/net/x25/x25_facilities.c +++ b/net/x25/x25_facilities.c | |||
@@ -61,6 +61,8 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities, | |||
61 | while (len > 0) { | 61 | while (len > 0) { |
62 | switch (*p & X25_FAC_CLASS_MASK) { | 62 | switch (*p & X25_FAC_CLASS_MASK) { |
63 | case X25_FAC_CLASS_A: | 63 | case X25_FAC_CLASS_A: |
64 | if (len < 2) | ||
65 | return 0; | ||
64 | switch (*p) { | 66 | switch (*p) { |
65 | case X25_FAC_REVERSE: | 67 | case X25_FAC_REVERSE: |
66 | if((p[1] & 0x81) == 0x81) { | 68 | if((p[1] & 0x81) == 0x81) { |
@@ -104,6 +106,8 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities, | |||
104 | len -= 2; | 106 | len -= 2; |
105 | break; | 107 | break; |
106 | case X25_FAC_CLASS_B: | 108 | case X25_FAC_CLASS_B: |
109 | if (len < 3) | ||
110 | return 0; | ||
107 | switch (*p) { | 111 | switch (*p) { |
108 | case X25_FAC_PACKET_SIZE: | 112 | case X25_FAC_PACKET_SIZE: |
109 | facilities->pacsize_in = p[1]; | 113 | facilities->pacsize_in = p[1]; |
@@ -125,6 +129,8 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities, | |||
125 | len -= 3; | 129 | len -= 3; |
126 | break; | 130 | break; |
127 | case X25_FAC_CLASS_C: | 131 | case X25_FAC_CLASS_C: |
132 | if (len < 4) | ||
133 | return 0; | ||
128 | printk(KERN_DEBUG "X.25: unknown facility %02X, " | 134 | printk(KERN_DEBUG "X.25: unknown facility %02X, " |
129 | "values %02X, %02X, %02X\n", | 135 | "values %02X, %02X, %02X\n", |
130 | p[0], p[1], p[2], p[3]); | 136 | p[0], p[1], p[2], p[3]); |
@@ -132,26 +138,26 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities, | |||
132 | len -= 4; | 138 | len -= 4; |
133 | break; | 139 | break; |
134 | case X25_FAC_CLASS_D: | 140 | case X25_FAC_CLASS_D: |
141 | if (len < p[1] + 2) | ||
142 | return 0; | ||
135 | switch (*p) { | 143 | switch (*p) { |
136 | case X25_FAC_CALLING_AE: | 144 | case X25_FAC_CALLING_AE: |
137 | if (p[1] > X25_MAX_DTE_FACIL_LEN) | 145 | if (p[1] > X25_MAX_DTE_FACIL_LEN || p[1] <= 1) |
138 | break; | 146 | return 0; |
139 | dte_facs->calling_len = p[2]; | 147 | dte_facs->calling_len = p[2]; |
140 | memcpy(dte_facs->calling_ae, &p[3], p[1] - 1); | 148 | memcpy(dte_facs->calling_ae, &p[3], p[1] - 1); |
141 | *vc_fac_mask |= X25_MASK_CALLING_AE; | 149 | *vc_fac_mask |= X25_MASK_CALLING_AE; |
142 | break; | 150 | break; |
143 | case X25_FAC_CALLED_AE: | 151 | case X25_FAC_CALLED_AE: |
144 | if (p[1] > X25_MAX_DTE_FACIL_LEN) | 152 | if (p[1] > X25_MAX_DTE_FACIL_LEN || p[1] <= 1) |
145 | break; | 153 | return 0; |
146 | dte_facs->called_len = p[2]; | 154 | dte_facs->called_len = p[2]; |
147 | memcpy(dte_facs->called_ae, &p[3], p[1] - 1); | 155 | memcpy(dte_facs->called_ae, &p[3], p[1] - 1); |
148 | *vc_fac_mask |= X25_MASK_CALLED_AE; | 156 | *vc_fac_mask |= X25_MASK_CALLED_AE; |
149 | break; | 157 | break; |
150 | default: | 158 | default: |
151 | printk(KERN_DEBUG "X.25: unknown facility %02X," | 159 | printk(KERN_DEBUG "X.25: unknown facility %02X," |
152 | "length %d, values %02X, %02X, " | 160 | "length %d\n", p[0], p[1]); |
153 | "%02X, %02X\n", | ||
154 | p[0], p[1], p[2], p[3], p[4], p[5]); | ||
155 | break; | 161 | break; |
156 | } | 162 | } |
157 | len -= p[1] + 2; | 163 | len -= p[1] + 2; |
diff --git a/net/x25/x25_in.c b/net/x25/x25_in.c index 63178961efac..f729f022be69 100644 --- a/net/x25/x25_in.c +++ b/net/x25/x25_in.c | |||
@@ -119,6 +119,8 @@ static int x25_state1_machine(struct sock *sk, struct sk_buff *skb, int frametyp | |||
119 | &x25->vc_facil_mask); | 119 | &x25->vc_facil_mask); |
120 | if (len > 0) | 120 | if (len > 0) |
121 | skb_pull(skb, len); | 121 | skb_pull(skb, len); |
122 | else | ||
123 | return -1; | ||
122 | /* | 124 | /* |
123 | * Copy any Call User Data. | 125 | * Copy any Call User Data. |
124 | */ | 126 | */ |
diff --git a/net/x25/x25_link.c b/net/x25/x25_link.c index 73e7b954ad28..b25c6463c3e9 100644 --- a/net/x25/x25_link.c +++ b/net/x25/x25_link.c | |||
@@ -394,6 +394,7 @@ void __exit x25_link_free(void) | |||
394 | list_for_each_safe(entry, tmp, &x25_neigh_list) { | 394 | list_for_each_safe(entry, tmp, &x25_neigh_list) { |
395 | nb = list_entry(entry, struct x25_neigh, node); | 395 | nb = list_entry(entry, struct x25_neigh, node); |
396 | __x25_remove_neigh(nb); | 396 | __x25_remove_neigh(nb); |
397 | dev_put(nb->dev); | ||
397 | } | 398 | } |
398 | write_unlock_bh(&x25_neigh_list_lock); | 399 | write_unlock_bh(&x25_neigh_list_lock); |
399 | } | 400 | } |