Contents of /trunk/kernel-lts/patches-3.4/0172-3.4.73-all-fixes.patch
Parent Directory | Revision Log
Revision 2337 -
(show annotations)
(download)
Thu Dec 12 08:43:43 2013 UTC (10 years, 9 months ago) by niro
File size: 78315 byte(s)
Thu Dec 12 08:43:43 2013 UTC (10 years, 9 months ago) by niro
File size: 78315 byte(s)
-linux-3.4.73
1 | diff --git a/block/blk-core.c b/block/blk-core.c |
2 | index a02cfb7e4123..279f05dcbc87 100644 |
3 | --- a/block/blk-core.c |
4 | +++ b/block/blk-core.c |
5 | @@ -499,7 +499,7 @@ struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id) |
6 | goto fail_id; |
7 | |
8 | if (blk_throtl_init(q)) |
9 | - goto fail_id; |
10 | + goto fail_bdi; |
11 | |
12 | setup_timer(&q->backing_dev_info.laptop_mode_wb_timer, |
13 | laptop_mode_timer_fn, (unsigned long) q); |
14 | @@ -524,6 +524,8 @@ struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id) |
15 | |
16 | return q; |
17 | |
18 | +fail_bdi: |
19 | + bdi_destroy(&q->backing_dev_info); |
20 | fail_id: |
21 | ida_simple_remove(&blk_queue_ida, q->id); |
22 | fail_q: |
23 | diff --git a/block/elevator.c b/block/elevator.c |
24 | index f016855a46b0..dcef5d1bf999 100644 |
25 | --- a/block/elevator.c |
26 | +++ b/block/elevator.c |
27 | @@ -961,7 +961,7 @@ fail_register: |
28 | /* |
29 | * Switch this queue to the given IO scheduler. |
30 | */ |
31 | -int elevator_change(struct request_queue *q, const char *name) |
32 | +static int __elevator_change(struct request_queue *q, const char *name) |
33 | { |
34 | char elevator_name[ELV_NAME_MAX]; |
35 | struct elevator_type *e; |
36 | @@ -983,6 +983,18 @@ int elevator_change(struct request_queue *q, const char *name) |
37 | |
38 | return elevator_switch(q, e); |
39 | } |
40 | + |
41 | +int elevator_change(struct request_queue *q, const char *name) |
42 | +{ |
43 | + int ret; |
44 | + |
45 | + /* Protect q->elevator from elevator_init() */ |
46 | + mutex_lock(&q->sysfs_lock); |
47 | + ret = __elevator_change(q, name); |
48 | + mutex_unlock(&q->sysfs_lock); |
49 | + |
50 | + return ret; |
51 | +} |
52 | EXPORT_SYMBOL(elevator_change); |
53 | |
54 | ssize_t elv_iosched_store(struct request_queue *q, const char *name, |
55 | @@ -993,7 +1005,7 @@ ssize_t elv_iosched_store(struct request_queue *q, const char *name, |
56 | if (!q->elevator) |
57 | return count; |
58 | |
59 | - ret = elevator_change(q, name); |
60 | + ret = __elevator_change(q, name); |
61 | if (!ret) |
62 | return count; |
63 | |
64 | diff --git a/crypto/algif_hash.c b/crypto/algif_hash.c |
65 | index 0262210cad38..850246206b12 100644 |
66 | --- a/crypto/algif_hash.c |
67 | +++ b/crypto/algif_hash.c |
68 | @@ -114,6 +114,9 @@ static ssize_t hash_sendpage(struct socket *sock, struct page *page, |
69 | struct hash_ctx *ctx = ask->private; |
70 | int err; |
71 | |
72 | + if (flags & MSG_SENDPAGE_NOTLAST) |
73 | + flags |= MSG_MORE; |
74 | + |
75 | lock_sock(sk); |
76 | sg_init_table(ctx->sgl.sg, 1); |
77 | sg_set_page(ctx->sgl.sg, page, size, offset); |
78 | @@ -161,8 +164,6 @@ static int hash_recvmsg(struct kiocb *unused, struct socket *sock, |
79 | else if (len < ds) |
80 | msg->msg_flags |= MSG_TRUNC; |
81 | |
82 | - msg->msg_namelen = 0; |
83 | - |
84 | lock_sock(sk); |
85 | if (ctx->more) { |
86 | ctx->more = 0; |
87 | diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c |
88 | index a1c4f0a55583..a19c027b29bd 100644 |
89 | --- a/crypto/algif_skcipher.c |
90 | +++ b/crypto/algif_skcipher.c |
91 | @@ -378,6 +378,9 @@ static ssize_t skcipher_sendpage(struct socket *sock, struct page *page, |
92 | struct skcipher_sg_list *sgl; |
93 | int err = -EINVAL; |
94 | |
95 | + if (flags & MSG_SENDPAGE_NOTLAST) |
96 | + flags |= MSG_MORE; |
97 | + |
98 | lock_sock(sk); |
99 | if (!ctx->more && ctx->used) |
100 | goto unlock; |
101 | @@ -432,7 +435,6 @@ static int skcipher_recvmsg(struct kiocb *unused, struct socket *sock, |
102 | long copied = 0; |
103 | |
104 | lock_sock(sk); |
105 | - msg->msg_namelen = 0; |
106 | for (iov = msg->msg_iov, iovlen = msg->msg_iovlen; iovlen > 0; |
107 | iovlen--, iov++) { |
108 | unsigned long seglen = iov->iov_len; |
109 | diff --git a/drivers/atm/idt77252.c b/drivers/atm/idt77252.c |
110 | index 1c052127548c..b0e75ce3c8fc 100644 |
111 | --- a/drivers/atm/idt77252.c |
112 | +++ b/drivers/atm/idt77252.c |
113 | @@ -3513,7 +3513,7 @@ init_card(struct atm_dev *dev) |
114 | tmp = dev_get_by_name(&init_net, tname); /* jhs: was "tmp = dev_get(tname);" */ |
115 | if (tmp) { |
116 | memcpy(card->atmdev->esi, tmp->dev_addr, 6); |
117 | - |
118 | + dev_put(tmp); |
119 | printk("%s: ESI %pM\n", card->name, card->atmdev->esi); |
120 | } |
121 | /* |
122 | diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c |
123 | index 2894461e0bdb..ff18e41f5b22 100644 |
124 | --- a/drivers/connector/cn_proc.c |
125 | +++ b/drivers/connector/cn_proc.c |
126 | @@ -31,11 +31,23 @@ |
127 | #include <linux/ptrace.h> |
128 | #include <linux/atomic.h> |
129 | |
130 | -#include <asm/unaligned.h> |
131 | - |
132 | #include <linux/cn_proc.h> |
133 | |
134 | -#define CN_PROC_MSG_SIZE (sizeof(struct cn_msg) + sizeof(struct proc_event)) |
135 | +/* |
136 | + * Size of a cn_msg followed by a proc_event structure. Since the |
137 | + * sizeof struct cn_msg is a multiple of 4 bytes, but not 8 bytes, we |
138 | + * add one 4-byte word to the size here, and then start the actual |
139 | + * cn_msg structure 4 bytes into the stack buffer. The result is that |
140 | + * the immediately following proc_event structure is aligned to 8 bytes. |
141 | + */ |
142 | +#define CN_PROC_MSG_SIZE (sizeof(struct cn_msg) + sizeof(struct proc_event) + 4) |
143 | + |
144 | +/* See comment above; we test our assumption about sizeof struct cn_msg here. */ |
145 | +static inline struct cn_msg *buffer_to_cn_msg(__u8 *buffer) |
146 | +{ |
147 | + BUILD_BUG_ON(sizeof(struct cn_msg) != 20); |
148 | + return (struct cn_msg *)(buffer + 4); |
149 | +} |
150 | |
151 | static atomic_t proc_event_num_listeners = ATOMIC_INIT(0); |
152 | static struct cb_id cn_proc_event_id = { CN_IDX_PROC, CN_VAL_PROC }; |
153 | @@ -55,19 +67,19 @@ void proc_fork_connector(struct task_struct *task) |
154 | { |
155 | struct cn_msg *msg; |
156 | struct proc_event *ev; |
157 | - __u8 buffer[CN_PROC_MSG_SIZE]; |
158 | + __u8 buffer[CN_PROC_MSG_SIZE] __aligned(8); |
159 | struct timespec ts; |
160 | struct task_struct *parent; |
161 | |
162 | if (atomic_read(&proc_event_num_listeners) < 1) |
163 | return; |
164 | |
165 | - msg = (struct cn_msg*)buffer; |
166 | + msg = buffer_to_cn_msg(buffer); |
167 | ev = (struct proc_event*)msg->data; |
168 | memset(&ev->event_data, 0, sizeof(ev->event_data)); |
169 | get_seq(&msg->seq, &ev->cpu); |
170 | ktime_get_ts(&ts); /* get high res monotonic timestamp */ |
171 | - put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns); |
172 | + ev->timestamp_ns = timespec_to_ns(&ts); |
173 | ev->what = PROC_EVENT_FORK; |
174 | rcu_read_lock(); |
175 | parent = rcu_dereference(task->real_parent); |
176 | @@ -90,17 +102,17 @@ void proc_exec_connector(struct task_struct *task) |
177 | struct cn_msg *msg; |
178 | struct proc_event *ev; |
179 | struct timespec ts; |
180 | - __u8 buffer[CN_PROC_MSG_SIZE]; |
181 | + __u8 buffer[CN_PROC_MSG_SIZE] __aligned(8); |
182 | |
183 | if (atomic_read(&proc_event_num_listeners) < 1) |
184 | return; |
185 | |
186 | - msg = (struct cn_msg*)buffer; |
187 | + msg = buffer_to_cn_msg(buffer); |
188 | ev = (struct proc_event*)msg->data; |
189 | memset(&ev->event_data, 0, sizeof(ev->event_data)); |
190 | get_seq(&msg->seq, &ev->cpu); |
191 | ktime_get_ts(&ts); /* get high res monotonic timestamp */ |
192 | - put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns); |
193 | + ev->timestamp_ns = timespec_to_ns(&ts); |
194 | ev->what = PROC_EVENT_EXEC; |
195 | ev->event_data.exec.process_pid = task->pid; |
196 | ev->event_data.exec.process_tgid = task->tgid; |
197 | @@ -116,14 +128,14 @@ void proc_id_connector(struct task_struct *task, int which_id) |
198 | { |
199 | struct cn_msg *msg; |
200 | struct proc_event *ev; |
201 | - __u8 buffer[CN_PROC_MSG_SIZE]; |
202 | + __u8 buffer[CN_PROC_MSG_SIZE] __aligned(8); |
203 | struct timespec ts; |
204 | const struct cred *cred; |
205 | |
206 | if (atomic_read(&proc_event_num_listeners) < 1) |
207 | return; |
208 | |
209 | - msg = (struct cn_msg*)buffer; |
210 | + msg = buffer_to_cn_msg(buffer); |
211 | ev = (struct proc_event*)msg->data; |
212 | memset(&ev->event_data, 0, sizeof(ev->event_data)); |
213 | ev->what = which_id; |
214 | @@ -144,7 +156,7 @@ void proc_id_connector(struct task_struct *task, int which_id) |
215 | rcu_read_unlock(); |
216 | get_seq(&msg->seq, &ev->cpu); |
217 | ktime_get_ts(&ts); /* get high res monotonic timestamp */ |
218 | - put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns); |
219 | + ev->timestamp_ns = timespec_to_ns(&ts); |
220 | |
221 | memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id)); |
222 | msg->ack = 0; /* not used */ |
223 | @@ -158,17 +170,17 @@ void proc_sid_connector(struct task_struct *task) |
224 | struct cn_msg *msg; |
225 | struct proc_event *ev; |
226 | struct timespec ts; |
227 | - __u8 buffer[CN_PROC_MSG_SIZE]; |
228 | + __u8 buffer[CN_PROC_MSG_SIZE] __aligned(8); |
229 | |
230 | if (atomic_read(&proc_event_num_listeners) < 1) |
231 | return; |
232 | |
233 | - msg = (struct cn_msg *)buffer; |
234 | + msg = buffer_to_cn_msg(buffer); |
235 | ev = (struct proc_event *)msg->data; |
236 | memset(&ev->event_data, 0, sizeof(ev->event_data)); |
237 | get_seq(&msg->seq, &ev->cpu); |
238 | ktime_get_ts(&ts); /* get high res monotonic timestamp */ |
239 | - put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns); |
240 | + ev->timestamp_ns = timespec_to_ns(&ts); |
241 | ev->what = PROC_EVENT_SID; |
242 | ev->event_data.sid.process_pid = task->pid; |
243 | ev->event_data.sid.process_tgid = task->tgid; |
244 | @@ -185,17 +197,17 @@ void proc_ptrace_connector(struct task_struct *task, int ptrace_id) |
245 | struct cn_msg *msg; |
246 | struct proc_event *ev; |
247 | struct timespec ts; |
248 | - __u8 buffer[CN_PROC_MSG_SIZE]; |
249 | + __u8 buffer[CN_PROC_MSG_SIZE] __aligned(8); |
250 | |
251 | if (atomic_read(&proc_event_num_listeners) < 1) |
252 | return; |
253 | |
254 | - msg = (struct cn_msg *)buffer; |
255 | + msg = buffer_to_cn_msg(buffer); |
256 | ev = (struct proc_event *)msg->data; |
257 | memset(&ev->event_data, 0, sizeof(ev->event_data)); |
258 | get_seq(&msg->seq, &ev->cpu); |
259 | ktime_get_ts(&ts); /* get high res monotonic timestamp */ |
260 | - put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns); |
261 | + ev->timestamp_ns = timespec_to_ns(&ts); |
262 | ev->what = PROC_EVENT_PTRACE; |
263 | ev->event_data.ptrace.process_pid = task->pid; |
264 | ev->event_data.ptrace.process_tgid = task->tgid; |
265 | @@ -220,17 +232,17 @@ void proc_comm_connector(struct task_struct *task) |
266 | struct cn_msg *msg; |
267 | struct proc_event *ev; |
268 | struct timespec ts; |
269 | - __u8 buffer[CN_PROC_MSG_SIZE]; |
270 | + __u8 buffer[CN_PROC_MSG_SIZE] __aligned(8); |
271 | |
272 | if (atomic_read(&proc_event_num_listeners) < 1) |
273 | return; |
274 | |
275 | - msg = (struct cn_msg *)buffer; |
276 | + msg = buffer_to_cn_msg(buffer); |
277 | ev = (struct proc_event *)msg->data; |
278 | memset(&ev->event_data, 0, sizeof(ev->event_data)); |
279 | get_seq(&msg->seq, &ev->cpu); |
280 | ktime_get_ts(&ts); /* get high res monotonic timestamp */ |
281 | - put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns); |
282 | + ev->timestamp_ns = timespec_to_ns(&ts); |
283 | ev->what = PROC_EVENT_COMM; |
284 | ev->event_data.comm.process_pid = task->pid; |
285 | ev->event_data.comm.process_tgid = task->tgid; |
286 | @@ -247,18 +259,18 @@ void proc_exit_connector(struct task_struct *task) |
287 | { |
288 | struct cn_msg *msg; |
289 | struct proc_event *ev; |
290 | - __u8 buffer[CN_PROC_MSG_SIZE]; |
291 | + __u8 buffer[CN_PROC_MSG_SIZE] __aligned(8); |
292 | struct timespec ts; |
293 | |
294 | if (atomic_read(&proc_event_num_listeners) < 1) |
295 | return; |
296 | |
297 | - msg = (struct cn_msg*)buffer; |
298 | + msg = buffer_to_cn_msg(buffer); |
299 | ev = (struct proc_event*)msg->data; |
300 | memset(&ev->event_data, 0, sizeof(ev->event_data)); |
301 | get_seq(&msg->seq, &ev->cpu); |
302 | ktime_get_ts(&ts); /* get high res monotonic timestamp */ |
303 | - put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns); |
304 | + ev->timestamp_ns = timespec_to_ns(&ts); |
305 | ev->what = PROC_EVENT_EXIT; |
306 | ev->event_data.exit.process_pid = task->pid; |
307 | ev->event_data.exit.process_tgid = task->tgid; |
308 | @@ -284,18 +296,18 @@ static void cn_proc_ack(int err, int rcvd_seq, int rcvd_ack) |
309 | { |
310 | struct cn_msg *msg; |
311 | struct proc_event *ev; |
312 | - __u8 buffer[CN_PROC_MSG_SIZE]; |
313 | + __u8 buffer[CN_PROC_MSG_SIZE] __aligned(8); |
314 | struct timespec ts; |
315 | |
316 | if (atomic_read(&proc_event_num_listeners) < 1) |
317 | return; |
318 | |
319 | - msg = (struct cn_msg*)buffer; |
320 | + msg = buffer_to_cn_msg(buffer); |
321 | ev = (struct proc_event*)msg->data; |
322 | memset(&ev->event_data, 0, sizeof(ev->event_data)); |
323 | msg->seq = rcvd_seq; |
324 | ktime_get_ts(&ts); /* get high res monotonic timestamp */ |
325 | - put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns); |
326 | + ev->timestamp_ns = timespec_to_ns(&ts); |
327 | ev->cpu = -1; |
328 | ev->what = PROC_EVENT_NONE; |
329 | ev->event_data.ack.err = err; |
330 | diff --git a/drivers/hid/hid-picolcd.c b/drivers/hid/hid-picolcd.c |
331 | index 45c3433f7986..95f90479f285 100644 |
332 | --- a/drivers/hid/hid-picolcd.c |
333 | +++ b/drivers/hid/hid-picolcd.c |
334 | @@ -1424,7 +1424,7 @@ static ssize_t picolcd_operation_mode_store(struct device *dev, |
335 | buf += 10; |
336 | cnt -= 10; |
337 | } |
338 | - if (!report) |
339 | + if (!report || report->maxfield != 1) |
340 | return -EINVAL; |
341 | |
342 | while (cnt > 0 && (buf[cnt-1] == '\n' || buf[cnt-1] == '\r')) |
343 | diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c |
344 | index a60a54d8593a..abc6ac855598 100644 |
345 | --- a/drivers/iommu/intel-iommu.c |
346 | +++ b/drivers/iommu/intel-iommu.c |
347 | @@ -778,7 +778,11 @@ static struct dma_pte *pfn_to_dma_pte(struct dmar_domain *domain, |
348 | int offset; |
349 | |
350 | BUG_ON(!domain->pgd); |
351 | - BUG_ON(addr_width < BITS_PER_LONG && pfn >> addr_width); |
352 | + |
353 | + if (addr_width < BITS_PER_LONG && pfn >> addr_width) |
354 | + /* Address beyond IOMMU's addressing capabilities. */ |
355 | + return NULL; |
356 | + |
357 | parent = domain->pgd; |
358 | |
359 | while (level > 0) { |
360 | diff --git a/drivers/isdn/isdnloop/isdnloop.c b/drivers/isdn/isdnloop/isdnloop.c |
361 | index baf2686aa8eb..02125e6a9109 100644 |
362 | --- a/drivers/isdn/isdnloop/isdnloop.c |
363 | +++ b/drivers/isdn/isdnloop/isdnloop.c |
364 | @@ -1083,8 +1083,10 @@ isdnloop_start(isdnloop_card *card, isdnloop_sdef *sdefp) |
365 | spin_unlock_irqrestore(&card->isdnloop_lock, flags); |
366 | return -ENOMEM; |
367 | } |
368 | - for (i = 0; i < 3; i++) |
369 | - strcpy(card->s0num[i], sdef.num[i]); |
370 | + for (i = 0; i < 3; i++) { |
371 | + strlcpy(card->s0num[i], sdef.num[i], |
372 | + sizeof(card->s0num[0])); |
373 | + } |
374 | break; |
375 | case ISDN_PTYPE_1TR6: |
376 | if (isdnloop_fake(card, "DRV1.04TC-1TR6-CAPI-CNS-BASIS-29.11.95", |
377 | @@ -1097,7 +1099,7 @@ isdnloop_start(isdnloop_card *card, isdnloop_sdef *sdefp) |
378 | spin_unlock_irqrestore(&card->isdnloop_lock, flags); |
379 | return -ENOMEM; |
380 | } |
381 | - strcpy(card->s0num[0], sdef.num[0]); |
382 | + strlcpy(card->s0num[0], sdef.num[0], sizeof(card->s0num[0])); |
383 | card->s0num[1][0] = '\0'; |
384 | card->s0num[2][0] = '\0'; |
385 | break; |
386 | diff --git a/drivers/isdn/mISDN/socket.c b/drivers/isdn/mISDN/socket.c |
387 | index abe2d699b6f3..ade1bcfb0e6d 100644 |
388 | --- a/drivers/isdn/mISDN/socket.c |
389 | +++ b/drivers/isdn/mISDN/socket.c |
390 | @@ -117,7 +117,6 @@ mISDN_sock_recvmsg(struct kiocb *iocb, struct socket *sock, |
391 | { |
392 | struct sk_buff *skb; |
393 | struct sock *sk = sock->sk; |
394 | - struct sockaddr_mISDN *maddr; |
395 | |
396 | int copied, err; |
397 | |
398 | @@ -135,9 +134,9 @@ mISDN_sock_recvmsg(struct kiocb *iocb, struct socket *sock, |
399 | if (!skb) |
400 | return err; |
401 | |
402 | - if (msg->msg_namelen >= sizeof(struct sockaddr_mISDN)) { |
403 | - msg->msg_namelen = sizeof(struct sockaddr_mISDN); |
404 | - maddr = (struct sockaddr_mISDN *)msg->msg_name; |
405 | + if (msg->msg_name) { |
406 | + struct sockaddr_mISDN *maddr = msg->msg_name; |
407 | + |
408 | maddr->family = AF_ISDN; |
409 | maddr->dev = _pms(sk)->dev->id; |
410 | if ((sk->sk_protocol == ISDN_P_LAPD_TE) || |
411 | @@ -150,11 +149,7 @@ mISDN_sock_recvmsg(struct kiocb *iocb, struct socket *sock, |
412 | maddr->sapi = _pms(sk)->ch.addr & 0xFF; |
413 | maddr->tei = (_pms(sk)->ch.addr >> 8) & 0xFF; |
414 | } |
415 | - } else { |
416 | - if (msg->msg_namelen) |
417 | - printk(KERN_WARNING "%s: too small namelen %d\n", |
418 | - __func__, msg->msg_namelen); |
419 | - msg->msg_namelen = 0; |
420 | + msg->msg_namelen = sizeof(*maddr); |
421 | } |
422 | |
423 | copied = skb->len + MISDN_HEADER_LEN; |
424 | diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c |
425 | index 3f06df59fd82..535c3e276fc7 100644 |
426 | --- a/drivers/md/dm-crypt.c |
427 | +++ b/drivers/md/dm-crypt.c |
428 | @@ -1262,20 +1262,6 @@ static int crypt_decode_key(u8 *key, char *hex, unsigned int size) |
429 | return 0; |
430 | } |
431 | |
432 | -/* |
433 | - * Encode key into its hex representation |
434 | - */ |
435 | -static void crypt_encode_key(char *hex, u8 *key, unsigned int size) |
436 | -{ |
437 | - unsigned int i; |
438 | - |
439 | - for (i = 0; i < size; i++) { |
440 | - sprintf(hex, "%02x", *key); |
441 | - hex += 2; |
442 | - key++; |
443 | - } |
444 | -} |
445 | - |
446 | static void crypt_free_tfms(struct crypt_config *cc, int cpu) |
447 | { |
448 | struct crypt_cpu *cpu_cc = per_cpu_ptr(cc->cpu, cpu); |
449 | @@ -1741,11 +1727,11 @@ static int crypt_map(struct dm_target *ti, struct bio *bio, |
450 | return DM_MAPIO_SUBMITTED; |
451 | } |
452 | |
453 | -static int crypt_status(struct dm_target *ti, status_type_t type, |
454 | - char *result, unsigned int maxlen) |
455 | +static void crypt_status(struct dm_target *ti, status_type_t type, |
456 | + char *result, unsigned int maxlen) |
457 | { |
458 | struct crypt_config *cc = ti->private; |
459 | - unsigned int sz = 0; |
460 | + unsigned i, sz = 0; |
461 | |
462 | switch (type) { |
463 | case STATUSTYPE_INFO: |
464 | @@ -1755,17 +1741,11 @@ static int crypt_status(struct dm_target *ti, status_type_t type, |
465 | case STATUSTYPE_TABLE: |
466 | DMEMIT("%s ", cc->cipher_string); |
467 | |
468 | - if (cc->key_size > 0) { |
469 | - if ((maxlen - sz) < ((cc->key_size << 1) + 1)) |
470 | - return -ENOMEM; |
471 | - |
472 | - crypt_encode_key(result + sz, cc->key, cc->key_size); |
473 | - sz += cc->key_size << 1; |
474 | - } else { |
475 | - if (sz >= maxlen) |
476 | - return -ENOMEM; |
477 | - result[sz++] = '-'; |
478 | - } |
479 | + if (cc->key_size > 0) |
480 | + for (i = 0; i < cc->key_size; i++) |
481 | + DMEMIT("%02x", cc->key[i]); |
482 | + else |
483 | + DMEMIT("-"); |
484 | |
485 | DMEMIT(" %llu %s %llu", (unsigned long long)cc->iv_offset, |
486 | cc->dev->name, (unsigned long long)cc->start); |
487 | @@ -1775,7 +1755,6 @@ static int crypt_status(struct dm_target *ti, status_type_t type, |
488 | |
489 | break; |
490 | } |
491 | - return 0; |
492 | } |
493 | |
494 | static void crypt_postsuspend(struct dm_target *ti) |
495 | diff --git a/drivers/md/dm-delay.c b/drivers/md/dm-delay.c |
496 | index 2dc22dddb2ae..ee99912596cb 100644 |
497 | --- a/drivers/md/dm-delay.c |
498 | +++ b/drivers/md/dm-delay.c |
499 | @@ -294,8 +294,8 @@ static int delay_map(struct dm_target *ti, struct bio *bio, |
500 | return delay_bio(dc, dc->read_delay, bio); |
501 | } |
502 | |
503 | -static int delay_status(struct dm_target *ti, status_type_t type, |
504 | - char *result, unsigned maxlen) |
505 | +static void delay_status(struct dm_target *ti, status_type_t type, |
506 | + char *result, unsigned maxlen) |
507 | { |
508 | struct delay_c *dc = ti->private; |
509 | int sz = 0; |
510 | @@ -315,8 +315,6 @@ static int delay_status(struct dm_target *ti, status_type_t type, |
511 | dc->write_delay); |
512 | break; |
513 | } |
514 | - |
515 | - return 0; |
516 | } |
517 | |
518 | static int delay_iterate_devices(struct dm_target *ti, |
519 | diff --git a/drivers/md/dm-flakey.c b/drivers/md/dm-flakey.c |
520 | index ac49c01f1a44..f29d665fe83a 100644 |
521 | --- a/drivers/md/dm-flakey.c |
522 | +++ b/drivers/md/dm-flakey.c |
523 | @@ -332,8 +332,8 @@ static int flakey_end_io(struct dm_target *ti, struct bio *bio, |
524 | return error; |
525 | } |
526 | |
527 | -static int flakey_status(struct dm_target *ti, status_type_t type, |
528 | - char *result, unsigned int maxlen) |
529 | +static void flakey_status(struct dm_target *ti, status_type_t type, |
530 | + char *result, unsigned int maxlen) |
531 | { |
532 | unsigned sz = 0; |
533 | struct flakey_c *fc = ti->private; |
534 | @@ -363,7 +363,6 @@ static int flakey_status(struct dm_target *ti, status_type_t type, |
535 | |
536 | break; |
537 | } |
538 | - return 0; |
539 | } |
540 | |
541 | static int flakey_ioctl(struct dm_target *ti, unsigned int cmd, unsigned long arg) |
542 | diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c |
543 | index f011d4b3c139..d365365bdb99 100644 |
544 | --- a/drivers/md/dm-ioctl.c |
545 | +++ b/drivers/md/dm-ioctl.c |
546 | @@ -1066,6 +1066,7 @@ static void retrieve_status(struct dm_table *table, |
547 | num_targets = dm_table_get_num_targets(table); |
548 | for (i = 0; i < num_targets; i++) { |
549 | struct dm_target *ti = dm_table_get_target(table, i); |
550 | + size_t l; |
551 | |
552 | remaining = len - (outptr - outbuf); |
553 | if (remaining <= sizeof(struct dm_target_spec)) { |
554 | @@ -1089,15 +1090,18 @@ static void retrieve_status(struct dm_table *table, |
555 | } |
556 | |
557 | /* Get the status/table string from the target driver */ |
558 | - if (ti->type->status) { |
559 | - if (ti->type->status(ti, type, outptr, remaining)) { |
560 | - param->flags |= DM_BUFFER_FULL_FLAG; |
561 | - break; |
562 | - } |
563 | - } else |
564 | + if (ti->type->status) |
565 | + ti->type->status(ti, type, outptr, remaining); |
566 | + else |
567 | outptr[0] = '\0'; |
568 | |
569 | - outptr += strlen(outptr) + 1; |
570 | + l = strlen(outptr) + 1; |
571 | + if (l == remaining) { |
572 | + param->flags |= DM_BUFFER_FULL_FLAG; |
573 | + break; |
574 | + } |
575 | + |
576 | + outptr += l; |
577 | used = param->data_start + (outptr - outbuf); |
578 | |
579 | outptr = align_ptr(outptr); |
580 | diff --git a/drivers/md/dm-linear.c b/drivers/md/dm-linear.c |
581 | index 3639eeab6042..5a5e9c8b29a7 100644 |
582 | --- a/drivers/md/dm-linear.c |
583 | +++ b/drivers/md/dm-linear.c |
584 | @@ -95,8 +95,8 @@ static int linear_map(struct dm_target *ti, struct bio *bio, |
585 | return DM_MAPIO_REMAPPED; |
586 | } |
587 | |
588 | -static int linear_status(struct dm_target *ti, status_type_t type, |
589 | - char *result, unsigned int maxlen) |
590 | +static void linear_status(struct dm_target *ti, status_type_t type, |
591 | + char *result, unsigned int maxlen) |
592 | { |
593 | struct linear_c *lc = (struct linear_c *) ti->private; |
594 | |
595 | @@ -110,7 +110,6 @@ static int linear_status(struct dm_target *ti, status_type_t type, |
596 | (unsigned long long)lc->start); |
597 | break; |
598 | } |
599 | - return 0; |
600 | } |
601 | |
602 | static int linear_ioctl(struct dm_target *ti, unsigned int cmd, |
603 | diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c |
604 | index 754f38f8a692..b74cb796c17c 100644 |
605 | --- a/drivers/md/dm-mpath.c |
606 | +++ b/drivers/md/dm-mpath.c |
607 | @@ -1343,8 +1343,8 @@ static void multipath_resume(struct dm_target *ti) |
608 | * [priority selector-name num_ps_args [ps_args]* |
609 | * num_paths num_selector_args [path_dev [selector_args]* ]+ ]+ |
610 | */ |
611 | -static int multipath_status(struct dm_target *ti, status_type_t type, |
612 | - char *result, unsigned int maxlen) |
613 | +static void multipath_status(struct dm_target *ti, status_type_t type, |
614 | + char *result, unsigned int maxlen) |
615 | { |
616 | int sz = 0; |
617 | unsigned long flags; |
618 | @@ -1447,8 +1447,6 @@ static int multipath_status(struct dm_target *ti, status_type_t type, |
619 | } |
620 | |
621 | spin_unlock_irqrestore(&m->lock, flags); |
622 | - |
623 | - return 0; |
624 | } |
625 | |
626 | static int multipath_message(struct dm_target *ti, unsigned argc, char **argv) |
627 | diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c |
628 | index 68965e663248..ead5ca99a749 100644 |
629 | --- a/drivers/md/dm-raid.c |
630 | +++ b/drivers/md/dm-raid.c |
631 | @@ -1067,8 +1067,8 @@ static int raid_map(struct dm_target *ti, struct bio *bio, union map_info *map_c |
632 | return DM_MAPIO_SUBMITTED; |
633 | } |
634 | |
635 | -static int raid_status(struct dm_target *ti, status_type_t type, |
636 | - char *result, unsigned maxlen) |
637 | +static void raid_status(struct dm_target *ti, status_type_t type, |
638 | + char *result, unsigned maxlen) |
639 | { |
640 | struct raid_set *rs = ti->private; |
641 | unsigned raid_param_cnt = 1; /* at least 1 for chunksize */ |
642 | @@ -1203,8 +1203,6 @@ static int raid_status(struct dm_target *ti, status_type_t type, |
643 | DMEMIT(" -"); |
644 | } |
645 | } |
646 | - |
647 | - return 0; |
648 | } |
649 | |
650 | static int raid_iterate_devices(struct dm_target *ti, iterate_devices_callout_fn fn, void *data) |
651 | diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c |
652 | index b58b7a33914a..a3cf259275af 100644 |
653 | --- a/drivers/md/dm-raid1.c |
654 | +++ b/drivers/md/dm-raid1.c |
655 | @@ -1362,8 +1362,8 @@ static char device_status_char(struct mirror *m) |
656 | } |
657 | |
658 | |
659 | -static int mirror_status(struct dm_target *ti, status_type_t type, |
660 | - char *result, unsigned int maxlen) |
661 | +static void mirror_status(struct dm_target *ti, status_type_t type, |
662 | + char *result, unsigned int maxlen) |
663 | { |
664 | unsigned int m, sz = 0; |
665 | struct mirror_set *ms = (struct mirror_set *) ti->private; |
666 | @@ -1398,8 +1398,6 @@ static int mirror_status(struct dm_target *ti, status_type_t type, |
667 | if (ms->features & DM_RAID1_HANDLE_ERRORS) |
668 | DMEMIT(" 1 handle_errors"); |
669 | } |
670 | - |
671 | - return 0; |
672 | } |
673 | |
674 | static int mirror_iterate_devices(struct dm_target *ti, |
675 | diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c |
676 | index 448050c87be0..db77ac693323 100644 |
677 | --- a/drivers/md/dm-snap.c |
678 | +++ b/drivers/md/dm-snap.c |
679 | @@ -1845,8 +1845,8 @@ static void snapshot_merge_resume(struct dm_target *ti) |
680 | start_merge(s); |
681 | } |
682 | |
683 | -static int snapshot_status(struct dm_target *ti, status_type_t type, |
684 | - char *result, unsigned int maxlen) |
685 | +static void snapshot_status(struct dm_target *ti, status_type_t type, |
686 | + char *result, unsigned int maxlen) |
687 | { |
688 | unsigned sz = 0; |
689 | struct dm_snapshot *snap = ti->private; |
690 | @@ -1892,8 +1892,6 @@ static int snapshot_status(struct dm_target *ti, status_type_t type, |
691 | maxlen - sz); |
692 | break; |
693 | } |
694 | - |
695 | - return 0; |
696 | } |
697 | |
698 | static int snapshot_iterate_devices(struct dm_target *ti, |
699 | @@ -2148,8 +2146,8 @@ static void origin_resume(struct dm_target *ti) |
700 | ti->split_io = get_origin_minimum_chunksize(dev->bdev); |
701 | } |
702 | |
703 | -static int origin_status(struct dm_target *ti, status_type_t type, char *result, |
704 | - unsigned int maxlen) |
705 | +static void origin_status(struct dm_target *ti, status_type_t type, char *result, |
706 | + unsigned int maxlen) |
707 | { |
708 | struct dm_dev *dev = ti->private; |
709 | |
710 | @@ -2162,8 +2160,6 @@ static int origin_status(struct dm_target *ti, status_type_t type, char *result, |
711 | snprintf(result, maxlen, "%s", dev->name); |
712 | break; |
713 | } |
714 | - |
715 | - return 0; |
716 | } |
717 | |
718 | static int origin_merge(struct dm_target *ti, struct bvec_merge_data *bvm, |
719 | diff --git a/drivers/md/dm-stripe.c b/drivers/md/dm-stripe.c |
720 | index 35c94ff24ad5..58ffcda3dab3 100644 |
721 | --- a/drivers/md/dm-stripe.c |
722 | +++ b/drivers/md/dm-stripe.c |
723 | @@ -302,8 +302,8 @@ static int stripe_map(struct dm_target *ti, struct bio *bio, |
724 | * |
725 | */ |
726 | |
727 | -static int stripe_status(struct dm_target *ti, |
728 | - status_type_t type, char *result, unsigned int maxlen) |
729 | +static void stripe_status(struct dm_target *ti, |
730 | + status_type_t type, char *result, unsigned int maxlen) |
731 | { |
732 | struct stripe_c *sc = (struct stripe_c *) ti->private; |
733 | char buffer[sc->stripes + 1]; |
734 | @@ -330,7 +330,6 @@ static int stripe_status(struct dm_target *ti, |
735 | (unsigned long long)sc->stripe[i].physical_start); |
736 | break; |
737 | } |
738 | - return 0; |
739 | } |
740 | |
741 | static int stripe_end_io(struct dm_target *ti, struct bio *bio, |
742 | diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c |
743 | index 7c3ab8fcdbd3..c540dfff1f81 100644 |
744 | --- a/drivers/md/dm-thin.c |
745 | +++ b/drivers/md/dm-thin.c |
746 | @@ -2325,8 +2325,8 @@ static int pool_message(struct dm_target *ti, unsigned argc, char **argv) |
747 | * <transaction id> <used metadata sectors>/<total metadata sectors> |
748 | * <used data sectors>/<total data sectors> <held metadata root> |
749 | */ |
750 | -static int pool_status(struct dm_target *ti, status_type_t type, |
751 | - char *result, unsigned maxlen) |
752 | +static void pool_status(struct dm_target *ti, status_type_t type, |
753 | + char *result, unsigned maxlen) |
754 | { |
755 | int r, count; |
756 | unsigned sz = 0; |
757 | @@ -2343,32 +2343,41 @@ static int pool_status(struct dm_target *ti, status_type_t type, |
758 | |
759 | switch (type) { |
760 | case STATUSTYPE_INFO: |
761 | - r = dm_pool_get_metadata_transaction_id(pool->pmd, |
762 | - &transaction_id); |
763 | - if (r) |
764 | - return r; |
765 | + r = dm_pool_get_metadata_transaction_id(pool->pmd, &transaction_id); |
766 | + if (r) { |
767 | + DMERR("dm_pool_get_metadata_transaction_id returned %d", r); |
768 | + goto err; |
769 | + } |
770 | |
771 | - r = dm_pool_get_free_metadata_block_count(pool->pmd, |
772 | - &nr_free_blocks_metadata); |
773 | - if (r) |
774 | - return r; |
775 | + r = dm_pool_get_free_metadata_block_count(pool->pmd, &nr_free_blocks_metadata); |
776 | + if (r) { |
777 | + DMERR("dm_pool_get_free_metadata_block_count returned %d", r); |
778 | + goto err; |
779 | + } |
780 | |
781 | r = dm_pool_get_metadata_dev_size(pool->pmd, &nr_blocks_metadata); |
782 | - if (r) |
783 | - return r; |
784 | + if (r) { |
785 | + DMERR("dm_pool_get_metadata_dev_size returned %d", r); |
786 | + goto err; |
787 | + } |
788 | |
789 | - r = dm_pool_get_free_block_count(pool->pmd, |
790 | - &nr_free_blocks_data); |
791 | - if (r) |
792 | - return r; |
793 | + r = dm_pool_get_free_block_count(pool->pmd, &nr_free_blocks_data); |
794 | + if (r) { |
795 | + DMERR("dm_pool_get_free_block_count returned %d", r); |
796 | + goto err; |
797 | + } |
798 | |
799 | r = dm_pool_get_data_dev_size(pool->pmd, &nr_blocks_data); |
800 | - if (r) |
801 | - return r; |
802 | + if (r) { |
803 | + DMERR("dm_pool_get_data_dev_size returned %d", r); |
804 | + goto err; |
805 | + } |
806 | |
807 | r = dm_pool_get_held_metadata_root(pool->pmd, &held_root); |
808 | - if (r) |
809 | - return r; |
810 | + if (r) { |
811 | + DMERR("dm_pool_get_metadata_snap returned %d", r); |
812 | + goto err; |
813 | + } |
814 | |
815 | DMEMIT("%llu %llu/%llu %llu/%llu ", |
816 | (unsigned long long)transaction_id, |
817 | @@ -2406,8 +2415,10 @@ static int pool_status(struct dm_target *ti, status_type_t type, |
818 | |
819 | break; |
820 | } |
821 | + return; |
822 | |
823 | - return 0; |
824 | +err: |
825 | + DMEMIT("Error"); |
826 | } |
827 | |
828 | static int pool_iterate_devices(struct dm_target *ti, |
829 | @@ -2659,8 +2670,8 @@ static void thin_postsuspend(struct dm_target *ti) |
830 | /* |
831 | * <nr mapped sectors> <highest mapped sector> |
832 | */ |
833 | -static int thin_status(struct dm_target *ti, status_type_t type, |
834 | - char *result, unsigned maxlen) |
835 | +static void thin_status(struct dm_target *ti, status_type_t type, |
836 | + char *result, unsigned maxlen) |
837 | { |
838 | int r; |
839 | ssize_t sz = 0; |
840 | @@ -2674,12 +2685,16 @@ static int thin_status(struct dm_target *ti, status_type_t type, |
841 | switch (type) { |
842 | case STATUSTYPE_INFO: |
843 | r = dm_thin_get_mapped_count(tc->td, &mapped); |
844 | - if (r) |
845 | - return r; |
846 | + if (r) { |
847 | + DMERR("dm_thin_get_mapped_count returned %d", r); |
848 | + goto err; |
849 | + } |
850 | |
851 | r = dm_thin_get_highest_mapped_block(tc->td, &highest); |
852 | - if (r < 0) |
853 | - return r; |
854 | + if (r < 0) { |
855 | + DMERR("dm_thin_get_highest_mapped_block returned %d", r); |
856 | + goto err; |
857 | + } |
858 | |
859 | DMEMIT("%llu ", mapped * tc->pool->sectors_per_block); |
860 | if (r) |
861 | @@ -2699,7 +2714,10 @@ static int thin_status(struct dm_target *ti, status_type_t type, |
862 | } |
863 | } |
864 | |
865 | - return 0; |
866 | + return; |
867 | + |
868 | +err: |
869 | + DMEMIT("Error"); |
870 | } |
871 | |
872 | static int thin_iterate_devices(struct dm_target *ti, |
873 | diff --git a/drivers/md/dm-verity.c b/drivers/md/dm-verity.c |
874 | index 9ab2a6a582b6..ac099847a4b3 100644 |
875 | --- a/drivers/md/dm-verity.c |
876 | +++ b/drivers/md/dm-verity.c |
877 | @@ -514,8 +514,8 @@ static int verity_map(struct dm_target *ti, struct bio *bio, |
878 | /* |
879 | * Status: V (valid) or C (corruption found) |
880 | */ |
881 | -static int verity_status(struct dm_target *ti, status_type_t type, |
882 | - char *result, unsigned maxlen) |
883 | +static void verity_status(struct dm_target *ti, status_type_t type, |
884 | + char *result, unsigned maxlen) |
885 | { |
886 | struct dm_verity *v = ti->private; |
887 | unsigned sz = 0; |
888 | @@ -546,8 +546,6 @@ static int verity_status(struct dm_target *ti, status_type_t type, |
889 | DMEMIT("%02x", v->salt[x]); |
890 | break; |
891 | } |
892 | - |
893 | - return 0; |
894 | } |
895 | |
896 | static int verity_ioctl(struct dm_target *ti, unsigned cmd, |
897 | diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c |
898 | index 833ff16f5fe1..c32a9093159a 100644 |
899 | --- a/drivers/mmc/card/block.c |
900 | +++ b/drivers/mmc/card/block.c |
901 | @@ -701,7 +701,7 @@ static int mmc_blk_cmd_error(struct request *req, const char *name, int error, |
902 | * Otherwise we don't understand what happened, so abort. |
903 | */ |
904 | static int mmc_blk_cmd_recovery(struct mmc_card *card, struct request *req, |
905 | - struct mmc_blk_request *brq, int *ecc_err) |
906 | + struct mmc_blk_request *brq, int *ecc_err, int *gen_err) |
907 | { |
908 | bool prev_cmd_status_valid = true; |
909 | u32 status, stop_status = 0; |
910 | @@ -739,6 +739,16 @@ static int mmc_blk_cmd_recovery(struct mmc_card *card, struct request *req, |
911 | (brq->cmd.resp[0] & R1_CARD_ECC_FAILED)) |
912 | *ecc_err = 1; |
913 | |
914 | + /* Flag General errors */ |
915 | + if (!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ) |
916 | + if ((status & R1_ERROR) || |
917 | + (brq->stop.resp[0] & R1_ERROR)) { |
918 | + pr_err("%s: %s: general error sending stop or status command, stop cmd response %#x, card status %#x\n", |
919 | + req->rq_disk->disk_name, __func__, |
920 | + brq->stop.resp[0], status); |
921 | + *gen_err = 1; |
922 | + } |
923 | + |
924 | /* |
925 | * Check the current card state. If it is in some data transfer |
926 | * mode, tell it to stop (and hopefully transition back to TRAN.) |
927 | @@ -758,6 +768,13 @@ static int mmc_blk_cmd_recovery(struct mmc_card *card, struct request *req, |
928 | return ERR_ABORT; |
929 | if (stop_status & R1_CARD_ECC_FAILED) |
930 | *ecc_err = 1; |
931 | + if (!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ) |
932 | + if (stop_status & R1_ERROR) { |
933 | + pr_err("%s: %s: general error sending stop command, stop cmd response %#x\n", |
934 | + req->rq_disk->disk_name, __func__, |
935 | + stop_status); |
936 | + *gen_err = 1; |
937 | + } |
938 | } |
939 | |
940 | /* Check for set block count errors */ |
941 | @@ -1007,7 +1024,7 @@ static int mmc_blk_err_check(struct mmc_card *card, |
942 | mmc_active); |
943 | struct mmc_blk_request *brq = &mq_mrq->brq; |
944 | struct request *req = mq_mrq->req; |
945 | - int ecc_err = 0; |
946 | + int ecc_err = 0, gen_err = 0; |
947 | |
948 | /* |
949 | * sbc.error indicates a problem with the set block count |
950 | @@ -1021,7 +1038,7 @@ static int mmc_blk_err_check(struct mmc_card *card, |
951 | */ |
952 | if (brq->sbc.error || brq->cmd.error || brq->stop.error || |
953 | brq->data.error) { |
954 | - switch (mmc_blk_cmd_recovery(card, req, brq, &ecc_err)) { |
955 | + switch (mmc_blk_cmd_recovery(card, req, brq, &ecc_err, &gen_err)) { |
956 | case ERR_RETRY: |
957 | return MMC_BLK_RETRY; |
958 | case ERR_ABORT: |
959 | @@ -1051,6 +1068,15 @@ static int mmc_blk_err_check(struct mmc_card *card, |
960 | */ |
961 | if (!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ) { |
962 | u32 status; |
963 | + |
964 | + /* Check stop command response */ |
965 | + if (brq->stop.resp[0] & R1_ERROR) { |
966 | + pr_err("%s: %s: general error sending stop command, stop cmd response %#x\n", |
967 | + req->rq_disk->disk_name, __func__, |
968 | + brq->stop.resp[0]); |
969 | + gen_err = 1; |
970 | + } |
971 | + |
972 | do { |
973 | int err = get_card_status(card, &status, 5); |
974 | if (err) { |
975 | @@ -1058,6 +1084,14 @@ static int mmc_blk_err_check(struct mmc_card *card, |
976 | req->rq_disk->disk_name, err); |
977 | return MMC_BLK_CMD_ERR; |
978 | } |
979 | + |
980 | + if (status & R1_ERROR) { |
981 | + pr_err("%s: %s: general error sending status command, card status %#x\n", |
982 | + req->rq_disk->disk_name, __func__, |
983 | + status); |
984 | + gen_err = 1; |
985 | + } |
986 | + |
987 | /* |
988 | * Some cards mishandle the status bits, |
989 | * so make sure to check both the busy |
990 | @@ -1067,6 +1101,13 @@ static int mmc_blk_err_check(struct mmc_card *card, |
991 | (R1_CURRENT_STATE(status) == R1_STATE_PRG)); |
992 | } |
993 | |
994 | + /* if general error occurs, retry the write operation. */ |
995 | + if (gen_err) { |
996 | + pr_warning("%s: retrying write for general error\n", |
997 | + req->rq_disk->disk_name); |
998 | + return MMC_BLK_RETRY; |
999 | + } |
1000 | + |
1001 | if (brq->data.error) { |
1002 | pr_err("%s: error %d transferring data, sector %u, nr %u, cmd response %#x, card status %#x\n", |
1003 | req->rq_disk->disk_name, brq->data.error, |
1004 | diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c |
1005 | index c40c0a871818..f42a00ac38d7 100644 |
1006 | --- a/drivers/net/bonding/bond_sysfs.c |
1007 | +++ b/drivers/net/bonding/bond_sysfs.c |
1008 | @@ -533,8 +533,9 @@ static ssize_t bonding_store_arp_interval(struct device *d, |
1009 | goto out; |
1010 | } |
1011 | if (bond->params.mode == BOND_MODE_ALB || |
1012 | - bond->params.mode == BOND_MODE_TLB) { |
1013 | - pr_info("%s: ARP monitoring cannot be used with ALB/TLB. Only MII monitoring is supported on %s.\n", |
1014 | + bond->params.mode == BOND_MODE_TLB || |
1015 | + bond->params.mode == BOND_MODE_8023AD) { |
1016 | + pr_info("%s: ARP monitoring cannot be used with ALB/TLB/802.3ad. Only MII monitoring is supported on %s.\n", |
1017 | bond->dev->name, bond->dev->name); |
1018 | ret = -EINVAL; |
1019 | goto out; |
1020 | @@ -692,6 +693,8 @@ static ssize_t bonding_store_downdelay(struct device *d, |
1021 | int new_value, ret = count; |
1022 | struct bonding *bond = to_bond(d); |
1023 | |
1024 | + if (!rtnl_trylock()) |
1025 | + return restart_syscall(); |
1026 | if (!(bond->params.miimon)) { |
1027 | pr_err("%s: Unable to set down delay as MII monitoring is disabled\n", |
1028 | bond->dev->name); |
1029 | @@ -725,6 +728,7 @@ static ssize_t bonding_store_downdelay(struct device *d, |
1030 | } |
1031 | |
1032 | out: |
1033 | + rtnl_unlock(); |
1034 | return ret; |
1035 | } |
1036 | static DEVICE_ATTR(downdelay, S_IRUGO | S_IWUSR, |
1037 | @@ -747,6 +751,8 @@ static ssize_t bonding_store_updelay(struct device *d, |
1038 | int new_value, ret = count; |
1039 | struct bonding *bond = to_bond(d); |
1040 | |
1041 | + if (!rtnl_trylock()) |
1042 | + return restart_syscall(); |
1043 | if (!(bond->params.miimon)) { |
1044 | pr_err("%s: Unable to set up delay as MII monitoring is disabled\n", |
1045 | bond->dev->name); |
1046 | @@ -780,6 +786,7 @@ static ssize_t bonding_store_updelay(struct device *d, |
1047 | } |
1048 | |
1049 | out: |
1050 | + rtnl_unlock(); |
1051 | return ret; |
1052 | } |
1053 | static DEVICE_ATTR(updelay, S_IRUGO | S_IWUSR, |
1054 | diff --git a/drivers/net/ppp/pppoe.c b/drivers/net/ppp/pppoe.c |
1055 | index 2e0d8762bb52..bac88c22d990 100644 |
1056 | --- a/drivers/net/ppp/pppoe.c |
1057 | +++ b/drivers/net/ppp/pppoe.c |
1058 | @@ -985,8 +985,6 @@ static int pppoe_recvmsg(struct kiocb *iocb, struct socket *sock, |
1059 | if (error < 0) |
1060 | goto end; |
1061 | |
1062 | - m->msg_namelen = 0; |
1063 | - |
1064 | if (skb) { |
1065 | total_len = min_t(size_t, total_len, skb->len); |
1066 | error = skb_copy_datagram_iovec(skb, 0, m->msg_iov, total_len); |
1067 | diff --git a/drivers/video/kyro/fbdev.c b/drivers/video/kyro/fbdev.c |
1068 | index acb9370fdb14..7aa8668f0a0c 100644 |
1069 | --- a/drivers/video/kyro/fbdev.c |
1070 | +++ b/drivers/video/kyro/fbdev.c |
1071 | @@ -625,15 +625,15 @@ static int kyrofb_ioctl(struct fb_info *info, |
1072 | } |
1073 | break; |
1074 | case KYRO_IOCTL_UVSTRIDE: |
1075 | - if (copy_to_user(argp, &deviceInfo.ulOverlayUVStride, sizeof(unsigned long))) |
1076 | + if (copy_to_user(argp, &deviceInfo.ulOverlayUVStride, sizeof(deviceInfo.ulOverlayUVStride))) |
1077 | return -EFAULT; |
1078 | break; |
1079 | case KYRO_IOCTL_STRIDE: |
1080 | - if (copy_to_user(argp, &deviceInfo.ulOverlayStride, sizeof(unsigned long))) |
1081 | + if (copy_to_user(argp, &deviceInfo.ulOverlayStride, sizeof(deviceInfo.ulOverlayStride))) |
1082 | return -EFAULT; |
1083 | break; |
1084 | case KYRO_IOCTL_OVERLAY_OFFSET: |
1085 | - if (copy_to_user(argp, &deviceInfo.ulOverlayOffset, sizeof(unsigned long))) |
1086 | + if (copy_to_user(argp, &deviceInfo.ulOverlayOffset, sizeof(deviceInfo.ulOverlayOffset))) |
1087 | return -EFAULT; |
1088 | break; |
1089 | } |
1090 | diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c |
1091 | index 53459b055cfc..25d839ed0ae1 100644 |
1092 | --- a/fs/nfsd/nfssvc.c |
1093 | +++ b/fs/nfsd/nfssvc.c |
1094 | @@ -11,7 +11,6 @@ |
1095 | #include <linux/module.h> |
1096 | #include <linux/fs_struct.h> |
1097 | #include <linux/swap.h> |
1098 | -#include <linux/nsproxy.h> |
1099 | |
1100 | #include <linux/sunrpc/stats.h> |
1101 | #include <linux/sunrpc/svcsock.h> |
1102 | @@ -330,7 +329,7 @@ static int nfsd_get_default_max_blksize(void) |
1103 | int nfsd_create_serv(void) |
1104 | { |
1105 | int error; |
1106 | - struct net *net = current->nsproxy->net_ns; |
1107 | + struct net *net = &init_net; |
1108 | |
1109 | WARN_ON(!mutex_is_locked(&nfsd_mutex)); |
1110 | if (nfsd_serv) { |
1111 | diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h |
1112 | index 98f34b886f95..fa09b579f67c 100644 |
1113 | --- a/include/linux/device-mapper.h |
1114 | +++ b/include/linux/device-mapper.h |
1115 | @@ -72,8 +72,8 @@ typedef void (*dm_postsuspend_fn) (struct dm_target *ti); |
1116 | typedef int (*dm_preresume_fn) (struct dm_target *ti); |
1117 | typedef void (*dm_resume_fn) (struct dm_target *ti); |
1118 | |
1119 | -typedef int (*dm_status_fn) (struct dm_target *ti, status_type_t status_type, |
1120 | - char *result, unsigned int maxlen); |
1121 | +typedef void (*dm_status_fn) (struct dm_target *ti, status_type_t status_type, |
1122 | + char *result, unsigned int maxlen); |
1123 | |
1124 | typedef int (*dm_message_fn) (struct dm_target *ti, unsigned argc, char **argv); |
1125 | |
1126 | diff --git a/include/linux/net.h b/include/linux/net.h |
1127 | index 95fea1432dd3..45232814fc03 100644 |
1128 | --- a/include/linux/net.h |
1129 | +++ b/include/linux/net.h |
1130 | @@ -198,6 +198,14 @@ struct proto_ops { |
1131 | #endif |
1132 | int (*sendmsg) (struct kiocb *iocb, struct socket *sock, |
1133 | struct msghdr *m, size_t total_len); |
1134 | + /* Notes for implementing recvmsg: |
1135 | + * =============================== |
1136 | + * msg->msg_namelen should get updated by the recvmsg handlers |
1137 | + * iff msg_name != NULL. It is by default 0 to prevent |
1138 | + * returning uninitialized memory to user space. The recvfrom |
1139 | + * handlers can assume that msg.msg_name is either NULL or has |
1140 | + * a minimum size of sizeof(struct sockaddr_storage). |
1141 | + */ |
1142 | int (*recvmsg) (struct kiocb *iocb, struct socket *sock, |
1143 | struct msghdr *m, size_t total_len, |
1144 | int flags); |
1145 | diff --git a/include/linux/random.h b/include/linux/random.h |
1146 | index 7e58ad27b7ff..54b1fd3efdfa 100644 |
1147 | --- a/include/linux/random.h |
1148 | +++ b/include/linux/random.h |
1149 | @@ -87,9 +87,9 @@ static inline void prandom32_seed(struct rnd_state *state, u64 seed) |
1150 | { |
1151 | u32 i = (seed >> 32) ^ (seed << 10) ^ seed; |
1152 | |
1153 | - state->s1 = __seed(i, 1); |
1154 | - state->s2 = __seed(i, 7); |
1155 | - state->s3 = __seed(i, 15); |
1156 | + state->s1 = __seed(i, 2); |
1157 | + state->s2 = __seed(i, 8); |
1158 | + state->s3 = __seed(i, 16); |
1159 | } |
1160 | |
1161 | #ifdef CONFIG_ARCH_RANDOM |
1162 | diff --git a/include/net/ip.h b/include/net/ip.h |
1163 | index 0750bf7d424f..6d6b12f4753c 100644 |
1164 | --- a/include/net/ip.h |
1165 | +++ b/include/net/ip.h |
1166 | @@ -466,7 +466,7 @@ extern int compat_ip_getsockopt(struct sock *sk, int level, |
1167 | int optname, char __user *optval, int __user *optlen); |
1168 | extern int ip_ra_control(struct sock *sk, unsigned char on, void (*destructor)(struct sock *)); |
1169 | |
1170 | -extern int ip_recv_error(struct sock *sk, struct msghdr *msg, int len); |
1171 | +extern int ip_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len); |
1172 | extern void ip_icmp_error(struct sock *sk, struct sk_buff *skb, int err, |
1173 | __be16 port, u32 info, u8 *payload); |
1174 | extern void ip_local_error(struct sock *sk, int err, __be32 daddr, __be16 dport, |
1175 | diff --git a/include/net/ipv6.h b/include/net/ipv6.h |
1176 | index 12a1bd2e9879..fa7af9183dc9 100644 |
1177 | --- a/include/net/ipv6.h |
1178 | +++ b/include/net/ipv6.h |
1179 | @@ -606,8 +606,10 @@ extern int compat_ipv6_getsockopt(struct sock *sk, |
1180 | extern int ip6_datagram_connect(struct sock *sk, |
1181 | struct sockaddr *addr, int addr_len); |
1182 | |
1183 | -extern int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len); |
1184 | -extern int ipv6_recv_rxpmtu(struct sock *sk, struct msghdr *msg, int len); |
1185 | +extern int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len, |
1186 | + int *addr_len); |
1187 | +extern int ipv6_recv_rxpmtu(struct sock *sk, struct msghdr *msg, int len, |
1188 | + int *addr_len); |
1189 | extern void ipv6_icmp_error(struct sock *sk, struct sk_buff *skb, int err, __be16 port, |
1190 | u32 info, u8 *payload); |
1191 | extern void ipv6_local_error(struct sock *sk, int err, struct flowi6 *fl6, u32 info); |
1192 | diff --git a/lib/random32.c b/lib/random32.c |
1193 | index 938bde5876ac..aa95712c1431 100644 |
1194 | --- a/lib/random32.c |
1195 | +++ b/lib/random32.c |
1196 | @@ -92,7 +92,7 @@ void srandom32(u32 entropy) |
1197 | */ |
1198 | for_each_possible_cpu (i) { |
1199 | struct rnd_state *state = &per_cpu(net_rand_state, i); |
1200 | - state->s1 = __seed(state->s1 ^ entropy, 1); |
1201 | + state->s1 = __seed(state->s1 ^ entropy, 2); |
1202 | } |
1203 | } |
1204 | EXPORT_SYMBOL(srandom32); |
1205 | @@ -109,9 +109,9 @@ static int __init random32_init(void) |
1206 | struct rnd_state *state = &per_cpu(net_rand_state,i); |
1207 | |
1208 | #define LCG(x) ((x) * 69069) /* super-duper LCG */ |
1209 | - state->s1 = __seed(LCG(i + jiffies), 1); |
1210 | - state->s2 = __seed(LCG(state->s1), 7); |
1211 | - state->s3 = __seed(LCG(state->s2), 15); |
1212 | + state->s1 = __seed(LCG(i + jiffies), 2); |
1213 | + state->s2 = __seed(LCG(state->s1), 8); |
1214 | + state->s3 = __seed(LCG(state->s2), 16); |
1215 | |
1216 | /* "warm it up" */ |
1217 | prandom32(state); |
1218 | @@ -138,9 +138,9 @@ static int __init random32_reseed(void) |
1219 | u32 seeds[3]; |
1220 | |
1221 | get_random_bytes(&seeds, sizeof(seeds)); |
1222 | - state->s1 = __seed(seeds[0], 1); |
1223 | - state->s2 = __seed(seeds[1], 7); |
1224 | - state->s3 = __seed(seeds[2], 15); |
1225 | + state->s1 = __seed(seeds[0], 2); |
1226 | + state->s2 = __seed(seeds[1], 8); |
1227 | + state->s3 = __seed(seeds[2], 16); |
1228 | |
1229 | /* mix it in */ |
1230 | prandom32(state); |
1231 | diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c |
1232 | index bfa9ab93eda5..334d4cd7612f 100644 |
1233 | --- a/net/appletalk/ddp.c |
1234 | +++ b/net/appletalk/ddp.c |
1235 | @@ -1740,7 +1740,6 @@ static int atalk_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr |
1236 | size_t size, int flags) |
1237 | { |
1238 | struct sock *sk = sock->sk; |
1239 | - struct sockaddr_at *sat = (struct sockaddr_at *)msg->msg_name; |
1240 | struct ddpehdr *ddp; |
1241 | int copied = 0; |
1242 | int offset = 0; |
1243 | @@ -1769,14 +1768,13 @@ static int atalk_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr |
1244 | } |
1245 | err = skb_copy_datagram_iovec(skb, offset, msg->msg_iov, copied); |
1246 | |
1247 | - if (!err) { |
1248 | - if (sat) { |
1249 | - sat->sat_family = AF_APPLETALK; |
1250 | - sat->sat_port = ddp->deh_sport; |
1251 | - sat->sat_addr.s_node = ddp->deh_snode; |
1252 | - sat->sat_addr.s_net = ddp->deh_snet; |
1253 | - } |
1254 | - msg->msg_namelen = sizeof(*sat); |
1255 | + if (!err && msg->msg_name) { |
1256 | + struct sockaddr_at *sat = msg->msg_name; |
1257 | + sat->sat_family = AF_APPLETALK; |
1258 | + sat->sat_port = ddp->deh_sport; |
1259 | + sat->sat_addr.s_node = ddp->deh_snode; |
1260 | + sat->sat_addr.s_net = ddp->deh_snet; |
1261 | + msg->msg_namelen = sizeof(*sat); |
1262 | } |
1263 | |
1264 | skb_free_datagram(sk, skb); /* Free the datagram. */ |
1265 | diff --git a/net/atm/common.c b/net/atm/common.c |
1266 | index f0a9b7eb3732..0c0ad930a632 100644 |
1267 | --- a/net/atm/common.c |
1268 | +++ b/net/atm/common.c |
1269 | @@ -520,8 +520,6 @@ int vcc_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, |
1270 | struct sk_buff *skb; |
1271 | int copied, error = -EINVAL; |
1272 | |
1273 | - msg->msg_namelen = 0; |
1274 | - |
1275 | if (sock->state != SS_CONNECTED) |
1276 | return -ENOTCONN; |
1277 | |
1278 | diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c |
1279 | index 68b39927ecda..ca1820cf22f2 100644 |
1280 | --- a/net/ax25/af_ax25.c |
1281 | +++ b/net/ax25/af_ax25.c |
1282 | @@ -1640,11 +1640,11 @@ static int ax25_recvmsg(struct kiocb *iocb, struct socket *sock, |
1283 | |
1284 | skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied); |
1285 | |
1286 | - if (msg->msg_namelen != 0) { |
1287 | - struct sockaddr_ax25 *sax = (struct sockaddr_ax25 *)msg->msg_name; |
1288 | + if (msg->msg_name) { |
1289 | ax25_digi digi; |
1290 | ax25_address src; |
1291 | const unsigned char *mac = skb_mac_header(skb); |
1292 | + struct sockaddr_ax25 *sax = msg->msg_name; |
1293 | |
1294 | memset(sax, 0, sizeof(struct full_sockaddr_ax25)); |
1295 | ax25_addr_parse(mac + 1, skb->data - mac - 1, &src, NULL, |
1296 | diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c |
1297 | index c2943484eab4..af3775f3d640 100644 |
1298 | --- a/net/bluetooth/af_bluetooth.c |
1299 | +++ b/net/bluetooth/af_bluetooth.c |
1300 | @@ -240,8 +240,6 @@ int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock, |
1301 | if (flags & (MSG_OOB)) |
1302 | return -EOPNOTSUPP; |
1303 | |
1304 | - msg->msg_namelen = 0; |
1305 | - |
1306 | skb = skb_recv_datagram(sk, flags, noblock, &err); |
1307 | if (!skb) { |
1308 | if (sk->sk_shutdown & RCV_SHUTDOWN) |
1309 | @@ -306,8 +304,6 @@ int bt_sock_stream_recvmsg(struct kiocb *iocb, struct socket *sock, |
1310 | if (flags & MSG_OOB) |
1311 | return -EOPNOTSUPP; |
1312 | |
1313 | - msg->msg_namelen = 0; |
1314 | - |
1315 | BT_DBG("sk %p size %zu", sk, size); |
1316 | |
1317 | lock_sock(sk); |
1318 | diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c |
1319 | index bedc768c8cdf..8c2cb05e50ea 100644 |
1320 | --- a/net/bluetooth/hci_sock.c |
1321 | +++ b/net/bluetooth/hci_sock.c |
1322 | @@ -767,8 +767,6 @@ static int hci_sock_recvmsg(struct kiocb *iocb, struct socket *sock, |
1323 | if (!skb) |
1324 | return err; |
1325 | |
1326 | - msg->msg_namelen = 0; |
1327 | - |
1328 | copied = skb->len; |
1329 | if (len < copied) { |
1330 | msg->msg_flags |= MSG_TRUNC; |
1331 | diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c |
1332 | index c79db7f7533b..8d1edd7207df 100644 |
1333 | --- a/net/bluetooth/rfcomm/sock.c |
1334 | +++ b/net/bluetooth/rfcomm/sock.c |
1335 | @@ -628,7 +628,6 @@ static int rfcomm_sock_recvmsg(struct kiocb *iocb, struct socket *sock, |
1336 | |
1337 | if (test_and_clear_bit(RFCOMM_DEFER_SETUP, &d->flags)) { |
1338 | rfcomm_dlc_accept(d); |
1339 | - msg->msg_namelen = 0; |
1340 | return 0; |
1341 | } |
1342 | |
1343 | diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c |
1344 | index e1144e1617be..ff44f5f16780 100644 |
1345 | --- a/net/bridge/br_if.c |
1346 | +++ b/net/bridge/br_if.c |
1347 | @@ -170,6 +170,8 @@ void br_dev_delete(struct net_device *dev, struct list_head *head) |
1348 | del_nbp(p); |
1349 | } |
1350 | |
1351 | + br_fdb_delete_by_port(br, NULL, 1); |
1352 | + |
1353 | del_timer_sync(&br->gc_timer); |
1354 | |
1355 | br_sysfs_delbr(br->dev); |
1356 | diff --git a/net/caif/caif_socket.c b/net/caif/caif_socket.c |
1357 | index 24a68861881c..9e8351598f8a 100644 |
1358 | --- a/net/caif/caif_socket.c |
1359 | +++ b/net/caif/caif_socket.c |
1360 | @@ -287,8 +287,6 @@ static int caif_seqpkt_recvmsg(struct kiocb *iocb, struct socket *sock, |
1361 | if (m->msg_flags&MSG_OOB) |
1362 | goto read_error; |
1363 | |
1364 | - m->msg_namelen = 0; |
1365 | - |
1366 | skb = skb_recv_datagram(sk, flags, 0 , &ret); |
1367 | if (!skb) |
1368 | goto read_error; |
1369 | @@ -362,8 +360,6 @@ static int caif_stream_recvmsg(struct kiocb *iocb, struct socket *sock, |
1370 | if (flags&MSG_OOB) |
1371 | goto out; |
1372 | |
1373 | - msg->msg_namelen = 0; |
1374 | - |
1375 | /* |
1376 | * Lock the socket to prevent queue disordering |
1377 | * while sleeps in memcpy_tomsg |
1378 | diff --git a/net/compat.c b/net/compat.c |
1379 | index ee84d82d7287..17f997e14f63 100644 |
1380 | --- a/net/compat.c |
1381 | +++ b/net/compat.c |
1382 | @@ -72,7 +72,7 @@ int get_compat_msghdr(struct msghdr *kmsg, struct compat_msghdr __user *umsg) |
1383 | __get_user(kmsg->msg_flags, &umsg->msg_flags)) |
1384 | return -EFAULT; |
1385 | if (kmsg->msg_namelen > sizeof(struct sockaddr_storage)) |
1386 | - return -EINVAL; |
1387 | + kmsg->msg_namelen = sizeof(struct sockaddr_storage); |
1388 | kmsg->msg_name = compat_ptr(tmp1); |
1389 | kmsg->msg_iov = compat_ptr(tmp2); |
1390 | kmsg->msg_control = compat_ptr(tmp3); |
1391 | @@ -93,7 +93,8 @@ int verify_compat_iovec(struct msghdr *kern_msg, struct iovec *kern_iov, |
1392 | if (err < 0) |
1393 | return err; |
1394 | } |
1395 | - kern_msg->msg_name = kern_address; |
1396 | + if (kern_msg->msg_name) |
1397 | + kern_msg->msg_name = kern_address; |
1398 | } else |
1399 | kern_msg->msg_name = NULL; |
1400 | |
1401 | diff --git a/net/core/dev.c b/net/core/dev.c |
1402 | index 7db83d64e4f7..cebdc15ce327 100644 |
1403 | --- a/net/core/dev.c |
1404 | +++ b/net/core/dev.c |
1405 | @@ -4443,7 +4443,7 @@ static void dev_change_rx_flags(struct net_device *dev, int flags) |
1406 | { |
1407 | const struct net_device_ops *ops = dev->netdev_ops; |
1408 | |
1409 | - if ((dev->flags & IFF_UP) && ops->ndo_change_rx_flags) |
1410 | + if (ops->ndo_change_rx_flags) |
1411 | ops->ndo_change_rx_flags(dev, flags); |
1412 | } |
1413 | |
1414 | diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c |
1415 | index c02e63c908da..c0c21b1ce1ec 100644 |
1416 | --- a/net/core/fib_rules.c |
1417 | +++ b/net/core/fib_rules.c |
1418 | @@ -443,7 +443,8 @@ static int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) |
1419 | if (frh->action && (frh->action != rule->action)) |
1420 | continue; |
1421 | |
1422 | - if (frh->table && (frh_get_table(frh, tb) != rule->table)) |
1423 | + if (frh_get_table(frh, tb) && |
1424 | + (frh_get_table(frh, tb) != rule->table)) |
1425 | continue; |
1426 | |
1427 | if (tb[FRA_PRIORITY] && |
1428 | diff --git a/net/core/iovec.c b/net/core/iovec.c |
1429 | index 7e7aeb01de45..7fd34a56aeb3 100644 |
1430 | --- a/net/core/iovec.c |
1431 | +++ b/net/core/iovec.c |
1432 | @@ -48,7 +48,8 @@ int verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr_storage *a |
1433 | if (err < 0) |
1434 | return err; |
1435 | } |
1436 | - m->msg_name = address; |
1437 | + if (m->msg_name) |
1438 | + m->msg_name = address; |
1439 | } else { |
1440 | m->msg_name = NULL; |
1441 | } |
1442 | diff --git a/net/core/pktgen.c b/net/core/pktgen.c |
1443 | index 114d8a9e8570..546b1334fad4 100644 |
1444 | --- a/net/core/pktgen.c |
1445 | +++ b/net/core/pktgen.c |
1446 | @@ -2521,6 +2521,8 @@ static int process_ipsec(struct pktgen_dev *pkt_dev, |
1447 | if (x) { |
1448 | int ret; |
1449 | __u8 *eth; |
1450 | + struct iphdr *iph; |
1451 | + |
1452 | nhead = x->props.header_len - skb_headroom(skb); |
1453 | if (nhead > 0) { |
1454 | ret = pskb_expand_head(skb, nhead, 0, GFP_ATOMIC); |
1455 | @@ -2542,6 +2544,11 @@ static int process_ipsec(struct pktgen_dev *pkt_dev, |
1456 | eth = (__u8 *) skb_push(skb, ETH_HLEN); |
1457 | memcpy(eth, pkt_dev->hh, 12); |
1458 | *(u16 *) ð[12] = protocol; |
1459 | + |
1460 | + /* Update IPv4 header len as well as checksum value */ |
1461 | + iph = ip_hdr(skb); |
1462 | + iph->tot_len = htons(skb->len - ETH_HLEN); |
1463 | + ip_send_check(iph); |
1464 | } |
1465 | } |
1466 | return 1; |
1467 | diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c |
1468 | index 840821b90bcd..ddbdceb9594b 100644 |
1469 | --- a/net/ieee802154/6lowpan.c |
1470 | +++ b/net/ieee802154/6lowpan.c |
1471 | @@ -803,7 +803,7 @@ lowpan_process_data(struct sk_buff *skb) |
1472 | * Traffic class carried in-line |
1473 | * ECN + DSCP (1 byte), Flow Label is elided |
1474 | */ |
1475 | - case 1: /* 10b */ |
1476 | + case 2: /* 10b */ |
1477 | if (!skb->len) |
1478 | goto drop; |
1479 | tmp = lowpan_fetch_skb_u8(skb); |
1480 | @@ -816,7 +816,7 @@ lowpan_process_data(struct sk_buff *skb) |
1481 | * Flow Label carried in-line |
1482 | * ECN + 2-bit Pad + Flow Label (3 bytes), DSCP is elided |
1483 | */ |
1484 | - case 2: /* 01b */ |
1485 | + case 1: /* 01b */ |
1486 | if (!skb->len) |
1487 | goto drop; |
1488 | tmp = lowpan_fetch_skb_u8(skb); |
1489 | diff --git a/net/ipv4/datagram.c b/net/ipv4/datagram.c |
1490 | index 424fafbc8cb0..ec0751051db7 100644 |
1491 | --- a/net/ipv4/datagram.c |
1492 | +++ b/net/ipv4/datagram.c |
1493 | @@ -57,7 +57,7 @@ int ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) |
1494 | if (IS_ERR(rt)) { |
1495 | err = PTR_ERR(rt); |
1496 | if (err == -ENETUNREACH) |
1497 | - IP_INC_STATS_BH(sock_net(sk), IPSTATS_MIB_OUTNOROUTES); |
1498 | + IP_INC_STATS(sock_net(sk), IPSTATS_MIB_OUTNOROUTES); |
1499 | goto out; |
1500 | } |
1501 | |
1502 | diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c |
1503 | index 374828487003..0bd174faff8f 100644 |
1504 | --- a/net/ipv4/ip_sockglue.c |
1505 | +++ b/net/ipv4/ip_sockglue.c |
1506 | @@ -367,7 +367,7 @@ void ip_local_error(struct sock *sk, int err, __be32 daddr, __be16 port, u32 inf |
1507 | /* |
1508 | * Handle MSG_ERRQUEUE |
1509 | */ |
1510 | -int ip_recv_error(struct sock *sk, struct msghdr *msg, int len) |
1511 | +int ip_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len) |
1512 | { |
1513 | struct sock_exterr_skb *serr; |
1514 | struct sk_buff *skb, *skb2; |
1515 | @@ -404,6 +404,7 @@ int ip_recv_error(struct sock *sk, struct msghdr *msg, int len) |
1516 | serr->addr_offset); |
1517 | sin->sin_port = serr->port; |
1518 | memset(&sin->sin_zero, 0, sizeof(sin->sin_zero)); |
1519 | + *addr_len = sizeof(*sin); |
1520 | } |
1521 | |
1522 | memcpy(&errhdr.ee, &serr->ee, sizeof(struct sock_extended_err)); |
1523 | diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c |
1524 | index c234bda5b801..e80db1e6b0b2 100644 |
1525 | --- a/net/ipv4/ping.c |
1526 | +++ b/net/ipv4/ping.c |
1527 | @@ -568,7 +568,7 @@ static int ping_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, |
1528 | err = PTR_ERR(rt); |
1529 | rt = NULL; |
1530 | if (err == -ENETUNREACH) |
1531 | - IP_INC_STATS_BH(net, IPSTATS_MIB_OUTNOROUTES); |
1532 | + IP_INC_STATS(net, IPSTATS_MIB_OUTNOROUTES); |
1533 | goto out; |
1534 | } |
1535 | |
1536 | @@ -624,7 +624,6 @@ static int ping_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, |
1537 | size_t len, int noblock, int flags, int *addr_len) |
1538 | { |
1539 | struct inet_sock *isk = inet_sk(sk); |
1540 | - struct sockaddr_in *sin = (struct sockaddr_in *)msg->msg_name; |
1541 | struct sk_buff *skb; |
1542 | int copied, err; |
1543 | |
1544 | @@ -634,11 +633,8 @@ static int ping_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, |
1545 | if (flags & MSG_OOB) |
1546 | goto out; |
1547 | |
1548 | - if (addr_len) |
1549 | - *addr_len = sizeof(*sin); |
1550 | - |
1551 | if (flags & MSG_ERRQUEUE) |
1552 | - return ip_recv_error(sk, msg, len); |
1553 | + return ip_recv_error(sk, msg, len, addr_len); |
1554 | |
1555 | skb = skb_recv_datagram(sk, flags, noblock, &err); |
1556 | if (!skb) |
1557 | @@ -658,11 +654,14 @@ static int ping_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, |
1558 | sock_recv_timestamp(msg, sk, skb); |
1559 | |
1560 | /* Copy the address. */ |
1561 | - if (sin) { |
1562 | + if (msg->msg_name) { |
1563 | + struct sockaddr_in *sin = (struct sockaddr_in *)msg->msg_name; |
1564 | + |
1565 | sin->sin_family = AF_INET; |
1566 | sin->sin_port = 0 /* skb->h.uh->source */; |
1567 | sin->sin_addr.s_addr = ip_hdr(skb)->saddr; |
1568 | memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); |
1569 | + *addr_len = sizeof(*sin); |
1570 | } |
1571 | if (isk->cmsg_flags) |
1572 | ip_cmsg_recv(msg, skb); |
1573 | diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c |
1574 | index c6b9ca651ab3..48c6ebcb7fe0 100644 |
1575 | --- a/net/ipv4/raw.c |
1576 | +++ b/net/ipv4/raw.c |
1577 | @@ -688,11 +688,8 @@ static int raw_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, |
1578 | if (flags & MSG_OOB) |
1579 | goto out; |
1580 | |
1581 | - if (addr_len) |
1582 | - *addr_len = sizeof(*sin); |
1583 | - |
1584 | if (flags & MSG_ERRQUEUE) { |
1585 | - err = ip_recv_error(sk, msg, len); |
1586 | + err = ip_recv_error(sk, msg, len, addr_len); |
1587 | goto out; |
1588 | } |
1589 | |
1590 | @@ -718,6 +715,7 @@ static int raw_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, |
1591 | sin->sin_addr.s_addr = ip_hdr(skb)->saddr; |
1592 | sin->sin_port = 0; |
1593 | memset(&sin->sin_zero, 0, sizeof(sin->sin_zero)); |
1594 | + *addr_len = sizeof(*sin); |
1595 | } |
1596 | if (inet->cmsg_flags) |
1597 | ip_cmsg_recv(msg, skb); |
1598 | diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c |
1599 | index ae03b7b75af6..727678dc7968 100644 |
1600 | --- a/net/ipv4/tcp_ipv4.c |
1601 | +++ b/net/ipv4/tcp_ipv4.c |
1602 | @@ -176,7 +176,7 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) |
1603 | if (IS_ERR(rt)) { |
1604 | err = PTR_ERR(rt); |
1605 | if (err == -ENETUNREACH) |
1606 | - IP_INC_STATS_BH(sock_net(sk), IPSTATS_MIB_OUTNOROUTES); |
1607 | + IP_INC_STATS(sock_net(sk), IPSTATS_MIB_OUTNOROUTES); |
1608 | return err; |
1609 | } |
1610 | |
1611 | diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c |
1612 | index 0b6136d578f6..7949b5d1663f 100644 |
1613 | --- a/net/ipv4/udp.c |
1614 | +++ b/net/ipv4/udp.c |
1615 | @@ -940,7 +940,7 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, |
1616 | err = PTR_ERR(rt); |
1617 | rt = NULL; |
1618 | if (err == -ENETUNREACH) |
1619 | - IP_INC_STATS_BH(net, IPSTATS_MIB_OUTNOROUTES); |
1620 | + IP_INC_STATS(net, IPSTATS_MIB_OUTNOROUTES); |
1621 | goto out; |
1622 | } |
1623 | |
1624 | @@ -1039,6 +1039,9 @@ int udp_sendpage(struct sock *sk, struct page *page, int offset, |
1625 | struct udp_sock *up = udp_sk(sk); |
1626 | int ret; |
1627 | |
1628 | + if (flags & MSG_SENDPAGE_NOTLAST) |
1629 | + flags |= MSG_MORE; |
1630 | + |
1631 | if (!up->pending) { |
1632 | struct msghdr msg = { .msg_flags = flags|MSG_MORE }; |
1633 | |
1634 | @@ -1174,14 +1177,8 @@ int udp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, |
1635 | int is_udplite = IS_UDPLITE(sk); |
1636 | bool slow; |
1637 | |
1638 | - /* |
1639 | - * Check any passed addresses |
1640 | - */ |
1641 | - if (addr_len) |
1642 | - *addr_len = sizeof(*sin); |
1643 | - |
1644 | if (flags & MSG_ERRQUEUE) |
1645 | - return ip_recv_error(sk, msg, len); |
1646 | + return ip_recv_error(sk, msg, len, addr_len); |
1647 | |
1648 | try_again: |
1649 | skb = __skb_recv_datagram(sk, flags | (noblock ? MSG_DONTWAIT : 0), |
1650 | @@ -1234,6 +1231,7 @@ try_again: |
1651 | sin->sin_port = udp_hdr(skb)->source; |
1652 | sin->sin_addr.s_addr = ip_hdr(skb)->saddr; |
1653 | memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); |
1654 | + *addr_len = sizeof(*sin); |
1655 | } |
1656 | if (inet->cmsg_flags) |
1657 | ip_cmsg_recv(msg, skb); |
1658 | diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c |
1659 | index 76832c8dc89d..94e5258f3560 100644 |
1660 | --- a/net/ipv6/datagram.c |
1661 | +++ b/net/ipv6/datagram.c |
1662 | @@ -315,7 +315,7 @@ void ipv6_local_rxpmtu(struct sock *sk, struct flowi6 *fl6, u32 mtu) |
1663 | /* |
1664 | * Handle MSG_ERRQUEUE |
1665 | */ |
1666 | -int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len) |
1667 | +int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len) |
1668 | { |
1669 | struct ipv6_pinfo *np = inet6_sk(sk); |
1670 | struct sock_exterr_skb *serr; |
1671 | @@ -366,6 +366,7 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len) |
1672 | ipv6_addr_set_v4mapped(*(__be32 *)(nh + serr->addr_offset), |
1673 | &sin->sin6_addr); |
1674 | } |
1675 | + *addr_len = sizeof(*sin); |
1676 | } |
1677 | |
1678 | memcpy(&errhdr.ee, &serr->ee, sizeof(struct sock_extended_err)); |
1679 | @@ -374,6 +375,7 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len) |
1680 | if (serr->ee.ee_origin != SO_EE_ORIGIN_LOCAL) { |
1681 | sin->sin6_family = AF_INET6; |
1682 | sin->sin6_flowinfo = 0; |
1683 | + sin->sin6_port = 0; |
1684 | sin->sin6_scope_id = 0; |
1685 | if (skb->protocol == htons(ETH_P_IPV6)) { |
1686 | sin->sin6_addr = ipv6_hdr(skb)->saddr; |
1687 | @@ -418,7 +420,8 @@ out: |
1688 | /* |
1689 | * Handle IPV6_RECVPATHMTU |
1690 | */ |
1691 | -int ipv6_recv_rxpmtu(struct sock *sk, struct msghdr *msg, int len) |
1692 | +int ipv6_recv_rxpmtu(struct sock *sk, struct msghdr *msg, int len, |
1693 | + int *addr_len) |
1694 | { |
1695 | struct ipv6_pinfo *np = inet6_sk(sk); |
1696 | struct sk_buff *skb; |
1697 | @@ -452,6 +455,7 @@ int ipv6_recv_rxpmtu(struct sock *sk, struct msghdr *msg, int len) |
1698 | sin->sin6_port = 0; |
1699 | sin->sin6_scope_id = mtu_info.ip6m_addr.sin6_scope_id; |
1700 | sin->sin6_addr = mtu_info.ip6m_addr.sin6_addr; |
1701 | + *addr_len = sizeof(*sin); |
1702 | } |
1703 | |
1704 | put_cmsg(msg, SOL_IPV6, IPV6_PATHMTU, sizeof(mtu_info), &mtu_info); |
1705 | diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c |
1706 | index 7dabea3a7125..91cd5f1657b7 100644 |
1707 | --- a/net/ipv6/ip6_output.c |
1708 | +++ b/net/ipv6/ip6_output.c |
1709 | @@ -144,8 +144,8 @@ static int ip6_finish_output2(struct sk_buff *skb) |
1710 | return res; |
1711 | } |
1712 | rcu_read_unlock(); |
1713 | - IP6_INC_STATS_BH(dev_net(dst->dev), |
1714 | - ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES); |
1715 | + IP6_INC_STATS(dev_net(dst->dev), |
1716 | + ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES); |
1717 | kfree_skb(skb); |
1718 | return -EINVAL; |
1719 | } |
1720 | diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c |
1721 | index 3ee28700de4c..d6820d019b2b 100644 |
1722 | --- a/net/ipv6/raw.c |
1723 | +++ b/net/ipv6/raw.c |
1724 | @@ -457,14 +457,11 @@ static int rawv6_recvmsg(struct kiocb *iocb, struct sock *sk, |
1725 | if (flags & MSG_OOB) |
1726 | return -EOPNOTSUPP; |
1727 | |
1728 | - if (addr_len) |
1729 | - *addr_len=sizeof(*sin6); |
1730 | - |
1731 | if (flags & MSG_ERRQUEUE) |
1732 | - return ipv6_recv_error(sk, msg, len); |
1733 | + return ipv6_recv_error(sk, msg, len, addr_len); |
1734 | |
1735 | if (np->rxpmtu && np->rxopt.bits.rxpmtu) |
1736 | - return ipv6_recv_rxpmtu(sk, msg, len); |
1737 | + return ipv6_recv_rxpmtu(sk, msg, len, addr_len); |
1738 | |
1739 | skb = skb_recv_datagram(sk, flags, noblock, &err); |
1740 | if (!skb) |
1741 | @@ -499,6 +496,7 @@ static int rawv6_recvmsg(struct kiocb *iocb, struct sock *sk, |
1742 | sin6->sin6_scope_id = 0; |
1743 | if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) |
1744 | sin6->sin6_scope_id = IP6CB(skb)->iif; |
1745 | + *addr_len = sizeof(*sin6); |
1746 | } |
1747 | |
1748 | sock_recv_ts_and_drops(msg, sk, skb); |
1749 | diff --git a/net/ipv6/route.c b/net/ipv6/route.c |
1750 | index 4f768a4c2907..6ac8bc29b43e 100644 |
1751 | --- a/net/ipv6/route.c |
1752 | +++ b/net/ipv6/route.c |
1753 | @@ -617,8 +617,11 @@ int rt6_route_rcv(struct net_device *dev, u8 *opt, int len, |
1754 | prefix = &prefix_buf; |
1755 | } |
1756 | |
1757 | - rt = rt6_get_route_info(net, prefix, rinfo->prefix_len, gwaddr, |
1758 | - dev->ifindex); |
1759 | + if (rinfo->prefix_len == 0) |
1760 | + rt = rt6_get_dflt_router(gwaddr, dev); |
1761 | + else |
1762 | + rt = rt6_get_route_info(net, prefix, rinfo->prefix_len, |
1763 | + gwaddr, dev->ifindex); |
1764 | |
1765 | if (rt && !lifetime) { |
1766 | ip6_del_rt(rt); |
1767 | diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c |
1768 | index f79bfdbc247f..98fd7384c446 100644 |
1769 | --- a/net/ipv6/udp.c |
1770 | +++ b/net/ipv6/udp.c |
1771 | @@ -348,14 +348,11 @@ int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk, |
1772 | int is_udp4; |
1773 | bool slow; |
1774 | |
1775 | - if (addr_len) |
1776 | - *addr_len=sizeof(struct sockaddr_in6); |
1777 | - |
1778 | if (flags & MSG_ERRQUEUE) |
1779 | - return ipv6_recv_error(sk, msg, len); |
1780 | + return ipv6_recv_error(sk, msg, len, addr_len); |
1781 | |
1782 | if (np->rxpmtu && np->rxopt.bits.rxpmtu) |
1783 | - return ipv6_recv_rxpmtu(sk, msg, len); |
1784 | + return ipv6_recv_rxpmtu(sk, msg, len, addr_len); |
1785 | |
1786 | try_again: |
1787 | skb = __skb_recv_datagram(sk, flags | (noblock ? MSG_DONTWAIT : 0), |
1788 | @@ -423,7 +420,7 @@ try_again: |
1789 | if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) |
1790 | sin6->sin6_scope_id = IP6CB(skb)->iif; |
1791 | } |
1792 | - |
1793 | + *addr_len = sizeof(*sin6); |
1794 | } |
1795 | if (is_udp4) { |
1796 | if (inet->cmsg_flags) |
1797 | diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c |
1798 | index 9680226640ef..8c06a5065772 100644 |
1799 | --- a/net/ipx/af_ipx.c |
1800 | +++ b/net/ipx/af_ipx.c |
1801 | @@ -1835,8 +1835,6 @@ static int ipx_recvmsg(struct kiocb *iocb, struct socket *sock, |
1802 | if (skb->tstamp.tv64) |
1803 | sk->sk_stamp = skb->tstamp; |
1804 | |
1805 | - msg->msg_namelen = sizeof(*sipx); |
1806 | - |
1807 | if (sipx) { |
1808 | sipx->sipx_family = AF_IPX; |
1809 | sipx->sipx_port = ipx->ipx_source.sock; |
1810 | @@ -1844,6 +1842,7 @@ static int ipx_recvmsg(struct kiocb *iocb, struct socket *sock, |
1811 | sipx->sipx_network = IPX_SKB_CB(skb)->ipx_source_net; |
1812 | sipx->sipx_type = ipx->ipx_type; |
1813 | sipx->sipx_zero = 0; |
1814 | + msg->msg_namelen = sizeof(*sipx); |
1815 | } |
1816 | rc = copied; |
1817 | |
1818 | diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c |
1819 | index bd25678b1d50..12218f705315 100644 |
1820 | --- a/net/irda/af_irda.c |
1821 | +++ b/net/irda/af_irda.c |
1822 | @@ -1386,8 +1386,6 @@ static int irda_recvmsg_dgram(struct kiocb *iocb, struct socket *sock, |
1823 | |
1824 | IRDA_DEBUG(4, "%s()\n", __func__); |
1825 | |
1826 | - msg->msg_namelen = 0; |
1827 | - |
1828 | skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT, |
1829 | flags & MSG_DONTWAIT, &err); |
1830 | if (!skb) |
1831 | @@ -1452,8 +1450,6 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock, |
1832 | target = sock_rcvlowat(sk, flags & MSG_WAITALL, size); |
1833 | timeo = sock_rcvtimeo(sk, noblock); |
1834 | |
1835 | - msg->msg_namelen = 0; |
1836 | - |
1837 | do { |
1838 | int chunk; |
1839 | struct sk_buff *skb = skb_dequeue(&sk->sk_receive_queue); |
1840 | diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c |
1841 | index 625bc50391cc..cd6f7a991d80 100644 |
1842 | --- a/net/iucv/af_iucv.c |
1843 | +++ b/net/iucv/af_iucv.c |
1844 | @@ -1331,8 +1331,6 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock, |
1845 | struct sk_buff *skb, *rskb, *cskb; |
1846 | int err = 0; |
1847 | |
1848 | - msg->msg_namelen = 0; |
1849 | - |
1850 | if ((sk->sk_state == IUCV_DISCONN) && |
1851 | skb_queue_empty(&iucv->backlog_skb_q) && |
1852 | skb_queue_empty(&sk->sk_receive_queue) && |
1853 | diff --git a/net/key/af_key.c b/net/key/af_key.c |
1854 | index 2f3ce93d3fc1..d5cd43920ccb 100644 |
1855 | --- a/net/key/af_key.c |
1856 | +++ b/net/key/af_key.c |
1857 | @@ -3595,7 +3595,6 @@ static int pfkey_recvmsg(struct kiocb *kiocb, |
1858 | if (flags & ~(MSG_PEEK|MSG_DONTWAIT|MSG_TRUNC|MSG_CMSG_COMPAT)) |
1859 | goto out; |
1860 | |
1861 | - msg->msg_namelen = 0; |
1862 | skb = skb_recv_datagram(sk, flags, flags & MSG_DONTWAIT, &err); |
1863 | if (skb == NULL) |
1864 | goto out; |
1865 | diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c |
1866 | index b1d4370c8962..ea247600f7d9 100644 |
1867 | --- a/net/l2tp/l2tp_ip.c |
1868 | +++ b/net/l2tp/l2tp_ip.c |
1869 | @@ -569,9 +569,6 @@ static int l2tp_ip_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *m |
1870 | if (flags & MSG_OOB) |
1871 | goto out; |
1872 | |
1873 | - if (addr_len) |
1874 | - *addr_len = sizeof(*sin); |
1875 | - |
1876 | skb = skb_recv_datagram(sk, flags, noblock, &err); |
1877 | if (!skb) |
1878 | goto out; |
1879 | @@ -594,6 +591,7 @@ static int l2tp_ip_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *m |
1880 | sin->sin_addr.s_addr = ip_hdr(skb)->saddr; |
1881 | sin->sin_port = 0; |
1882 | memset(&sin->sin_zero, 0, sizeof(sin->sin_zero)); |
1883 | + *addr_len = sizeof(*sin); |
1884 | } |
1885 | if (inet->cmsg_flags) |
1886 | ip_cmsg_recv(msg, skb); |
1887 | diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c |
1888 | index 904bc098790d..22112754ba06 100644 |
1889 | --- a/net/l2tp/l2tp_ppp.c |
1890 | +++ b/net/l2tp/l2tp_ppp.c |
1891 | @@ -200,8 +200,6 @@ static int pppol2tp_recvmsg(struct kiocb *iocb, struct socket *sock, |
1892 | if (sk->sk_state & PPPOX_BOUND) |
1893 | goto end; |
1894 | |
1895 | - msg->msg_namelen = 0; |
1896 | - |
1897 | err = 0; |
1898 | skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT, |
1899 | flags & MSG_DONTWAIT, &err); |
1900 | diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c |
1901 | index e4d2fbb59a7e..df08d7779e1d 100644 |
1902 | --- a/net/llc/af_llc.c |
1903 | +++ b/net/llc/af_llc.c |
1904 | @@ -721,8 +721,6 @@ static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock, |
1905 | int target; /* Read at least this many bytes */ |
1906 | long timeo; |
1907 | |
1908 | - msg->msg_namelen = 0; |
1909 | - |
1910 | lock_sock(sk); |
1911 | copied = -ENOTCONN; |
1912 | if (unlikely(sk->sk_type == SOCK_STREAM && sk->sk_state == TCP_LISTEN)) |
1913 | diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c |
1914 | index 9017e3ef8fee..ff960b792ee4 100644 |
1915 | --- a/net/netlink/af_netlink.c |
1916 | +++ b/net/netlink/af_netlink.c |
1917 | @@ -1443,8 +1443,6 @@ static int netlink_recvmsg(struct kiocb *kiocb, struct socket *sock, |
1918 | } |
1919 | #endif |
1920 | |
1921 | - msg->msg_namelen = 0; |
1922 | - |
1923 | copied = data_skb->len; |
1924 | if (len < copied) { |
1925 | msg->msg_flags |= MSG_TRUNC; |
1926 | diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c |
1927 | index 7ed9b1d0c102..dcf6791ec76d 100644 |
1928 | --- a/net/netrom/af_netrom.c |
1929 | +++ b/net/netrom/af_netrom.c |
1930 | @@ -1181,10 +1181,9 @@ static int nr_recvmsg(struct kiocb *iocb, struct socket *sock, |
1931 | sax->sax25_family = AF_NETROM; |
1932 | skb_copy_from_linear_data_offset(skb, 7, sax->sax25_call.ax25_call, |
1933 | AX25_ADDR_LEN); |
1934 | + msg->msg_namelen = sizeof(*sax); |
1935 | } |
1936 | |
1937 | - msg->msg_namelen = sizeof(*sax); |
1938 | - |
1939 | skb_free_datagram(sk, skb); |
1940 | |
1941 | release_sock(sk); |
1942 | diff --git a/net/nfc/rawsock.c b/net/nfc/rawsock.c |
1943 | index e879dce52818..44835ceb5562 100644 |
1944 | --- a/net/nfc/rawsock.c |
1945 | +++ b/net/nfc/rawsock.c |
1946 | @@ -235,8 +235,6 @@ static int rawsock_recvmsg(struct kiocb *iocb, struct socket *sock, |
1947 | if (!skb) |
1948 | return rc; |
1949 | |
1950 | - msg->msg_namelen = 0; |
1951 | - |
1952 | copied = skb->len; |
1953 | if (len < copied) { |
1954 | msg->msg_flags |= MSG_TRUNC; |
1955 | diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c |
1956 | index 8ed5d9302e88..dbe1715c629f 100644 |
1957 | --- a/net/packet/af_packet.c |
1958 | +++ b/net/packet/af_packet.c |
1959 | @@ -294,6 +294,7 @@ struct packet_sock { |
1960 | unsigned int tp_reserve; |
1961 | unsigned int tp_loss:1; |
1962 | unsigned int tp_tstamp; |
1963 | + struct net_device __rcu *cached_dev; |
1964 | struct packet_type prot_hook ____cacheline_aligned_in_smp; |
1965 | }; |
1966 | |
1967 | @@ -349,11 +350,15 @@ static void __fanout_link(struct sock *sk, struct packet_sock *po); |
1968 | static void register_prot_hook(struct sock *sk) |
1969 | { |
1970 | struct packet_sock *po = pkt_sk(sk); |
1971 | + |
1972 | if (!po->running) { |
1973 | - if (po->fanout) |
1974 | + if (po->fanout) { |
1975 | __fanout_link(sk, po); |
1976 | - else |
1977 | + } else { |
1978 | dev_add_pack(&po->prot_hook); |
1979 | + rcu_assign_pointer(po->cached_dev, po->prot_hook.dev); |
1980 | + } |
1981 | + |
1982 | sock_hold(sk); |
1983 | po->running = 1; |
1984 | } |
1985 | @@ -371,10 +376,13 @@ static void __unregister_prot_hook(struct sock *sk, bool sync) |
1986 | struct packet_sock *po = pkt_sk(sk); |
1987 | |
1988 | po->running = 0; |
1989 | - if (po->fanout) |
1990 | + if (po->fanout) { |
1991 | __fanout_unlink(sk, po); |
1992 | - else |
1993 | + } else { |
1994 | __dev_remove_pack(&po->prot_hook); |
1995 | + RCU_INIT_POINTER(po->cached_dev, NULL); |
1996 | + } |
1997 | + |
1998 | __sock_put(sk); |
1999 | |
2000 | if (sync) { |
2001 | @@ -496,9 +504,9 @@ static void prb_shutdown_retire_blk_timer(struct packet_sock *po, |
2002 | |
2003 | pkc = tx_ring ? &po->tx_ring.prb_bdqc : &po->rx_ring.prb_bdqc; |
2004 | |
2005 | - spin_lock(&rb_queue->lock); |
2006 | + spin_lock_bh(&rb_queue->lock); |
2007 | pkc->delete_blk_timer = 1; |
2008 | - spin_unlock(&rb_queue->lock); |
2009 | + spin_unlock_bh(&rb_queue->lock); |
2010 | |
2011 | prb_del_retire_blk_timer(pkc); |
2012 | } |
2013 | @@ -2044,12 +2052,24 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb, |
2014 | return tp_len; |
2015 | } |
2016 | |
2017 | +static struct net_device *packet_cached_dev_get(struct packet_sock *po) |
2018 | +{ |
2019 | + struct net_device *dev; |
2020 | + |
2021 | + rcu_read_lock(); |
2022 | + dev = rcu_dereference(po->cached_dev); |
2023 | + if (dev) |
2024 | + dev_hold(dev); |
2025 | + rcu_read_unlock(); |
2026 | + |
2027 | + return dev; |
2028 | +} |
2029 | + |
2030 | static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) |
2031 | { |
2032 | struct sk_buff *skb; |
2033 | struct net_device *dev; |
2034 | __be16 proto; |
2035 | - bool need_rls_dev = false; |
2036 | int err, reserve = 0; |
2037 | void *ph; |
2038 | struct sockaddr_ll *saddr = (struct sockaddr_ll *)msg->msg_name; |
2039 | @@ -2063,7 +2083,7 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) |
2040 | |
2041 | err = -EBUSY; |
2042 | if (saddr == NULL) { |
2043 | - dev = po->prot_hook.dev; |
2044 | + dev = packet_cached_dev_get(po); |
2045 | proto = po->num; |
2046 | addr = NULL; |
2047 | } else { |
2048 | @@ -2077,19 +2097,17 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) |
2049 | proto = saddr->sll_protocol; |
2050 | addr = saddr->sll_addr; |
2051 | dev = dev_get_by_index(sock_net(&po->sk), saddr->sll_ifindex); |
2052 | - need_rls_dev = true; |
2053 | } |
2054 | |
2055 | err = -ENXIO; |
2056 | if (unlikely(dev == NULL)) |
2057 | goto out; |
2058 | - |
2059 | - reserve = dev->hard_header_len; |
2060 | - |
2061 | err = -ENETDOWN; |
2062 | if (unlikely(!(dev->flags & IFF_UP))) |
2063 | goto out_put; |
2064 | |
2065 | + reserve = dev->hard_header_len; |
2066 | + |
2067 | size_max = po->tx_ring.frame_size |
2068 | - (po->tp_hdrlen - sizeof(struct sockaddr_ll)); |
2069 | |
2070 | @@ -2166,8 +2184,7 @@ out_status: |
2071 | __packet_set_status(po, ph, status); |
2072 | kfree_skb(skb); |
2073 | out_put: |
2074 | - if (need_rls_dev) |
2075 | - dev_put(dev); |
2076 | + dev_put(dev); |
2077 | out: |
2078 | mutex_unlock(&po->pg_vec_lock); |
2079 | return err; |
2080 | @@ -2205,7 +2222,6 @@ static int packet_snd(struct socket *sock, |
2081 | struct sk_buff *skb; |
2082 | struct net_device *dev; |
2083 | __be16 proto; |
2084 | - bool need_rls_dev = false; |
2085 | unsigned char *addr; |
2086 | int err, reserve = 0; |
2087 | struct virtio_net_hdr vnet_hdr = { 0 }; |
2088 | @@ -2221,7 +2237,7 @@ static int packet_snd(struct socket *sock, |
2089 | */ |
2090 | |
2091 | if (saddr == NULL) { |
2092 | - dev = po->prot_hook.dev; |
2093 | + dev = packet_cached_dev_get(po); |
2094 | proto = po->num; |
2095 | addr = NULL; |
2096 | } else { |
2097 | @@ -2233,19 +2249,17 @@ static int packet_snd(struct socket *sock, |
2098 | proto = saddr->sll_protocol; |
2099 | addr = saddr->sll_addr; |
2100 | dev = dev_get_by_index(sock_net(sk), saddr->sll_ifindex); |
2101 | - need_rls_dev = true; |
2102 | } |
2103 | |
2104 | err = -ENXIO; |
2105 | - if (dev == NULL) |
2106 | + if (unlikely(dev == NULL)) |
2107 | goto out_unlock; |
2108 | - if (sock->type == SOCK_RAW) |
2109 | - reserve = dev->hard_header_len; |
2110 | - |
2111 | err = -ENETDOWN; |
2112 | - if (!(dev->flags & IFF_UP)) |
2113 | + if (unlikely(!(dev->flags & IFF_UP))) |
2114 | goto out_unlock; |
2115 | |
2116 | + if (sock->type == SOCK_RAW) |
2117 | + reserve = dev->hard_header_len; |
2118 | if (po->has_vnet_hdr) { |
2119 | vnet_hdr_len = sizeof(vnet_hdr); |
2120 | |
2121 | @@ -2378,15 +2392,14 @@ static int packet_snd(struct socket *sock, |
2122 | if (err > 0 && (err = net_xmit_errno(err)) != 0) |
2123 | goto out_unlock; |
2124 | |
2125 | - if (need_rls_dev) |
2126 | - dev_put(dev); |
2127 | + dev_put(dev); |
2128 | |
2129 | return len; |
2130 | |
2131 | out_free: |
2132 | kfree_skb(skb); |
2133 | out_unlock: |
2134 | - if (dev && need_rls_dev) |
2135 | + if (dev) |
2136 | dev_put(dev); |
2137 | out: |
2138 | return err; |
2139 | @@ -2603,6 +2616,7 @@ static int packet_create(struct net *net, struct socket *sock, int protocol, |
2140 | po = pkt_sk(sk); |
2141 | sk->sk_family = PF_PACKET; |
2142 | po->num = proto; |
2143 | + RCU_INIT_POINTER(po->cached_dev, NULL); |
2144 | |
2145 | sk->sk_destruct = packet_sock_destruct; |
2146 | sk_refcnt_debug_inc(sk); |
2147 | @@ -2691,7 +2705,6 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock, |
2148 | struct sock *sk = sock->sk; |
2149 | struct sk_buff *skb; |
2150 | int copied, err; |
2151 | - struct sockaddr_ll *sll; |
2152 | int vnet_hdr_len = 0; |
2153 | |
2154 | err = -EINVAL; |
2155 | @@ -2774,22 +2787,10 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock, |
2156 | goto out_free; |
2157 | } |
2158 | |
2159 | - /* |
2160 | - * If the address length field is there to be filled in, we fill |
2161 | - * it in now. |
2162 | + /* You lose any data beyond the buffer you gave. If it worries |
2163 | + * a user program they can ask the device for its MTU |
2164 | + * anyway. |
2165 | */ |
2166 | - |
2167 | - sll = &PACKET_SKB_CB(skb)->sa.ll; |
2168 | - if (sock->type == SOCK_PACKET) |
2169 | - msg->msg_namelen = sizeof(struct sockaddr_pkt); |
2170 | - else |
2171 | - msg->msg_namelen = sll->sll_halen + offsetof(struct sockaddr_ll, sll_addr); |
2172 | - |
2173 | - /* |
2174 | - * You lose any data beyond the buffer you gave. If it worries a |
2175 | - * user program they can ask the device for its MTU anyway. |
2176 | - */ |
2177 | - |
2178 | copied = skb->len; |
2179 | if (copied > len) { |
2180 | copied = len; |
2181 | @@ -2802,9 +2803,20 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock, |
2182 | |
2183 | sock_recv_ts_and_drops(msg, sk, skb); |
2184 | |
2185 | - if (msg->msg_name) |
2186 | + if (msg->msg_name) { |
2187 | + /* If the address length field is there to be filled |
2188 | + * in, we fill it in now. |
2189 | + */ |
2190 | + if (sock->type == SOCK_PACKET) { |
2191 | + msg->msg_namelen = sizeof(struct sockaddr_pkt); |
2192 | + } else { |
2193 | + struct sockaddr_ll *sll = &PACKET_SKB_CB(skb)->sa.ll; |
2194 | + msg->msg_namelen = sll->sll_halen + |
2195 | + offsetof(struct sockaddr_ll, sll_addr); |
2196 | + } |
2197 | memcpy(msg->msg_name, &PACKET_SKB_CB(skb)->sa, |
2198 | msg->msg_namelen); |
2199 | + } |
2200 | |
2201 | if (pkt_sk(sk)->auxdata) { |
2202 | struct tpacket_auxdata aux; |
2203 | diff --git a/net/phonet/datagram.c b/net/phonet/datagram.c |
2204 | index bf35b4e1a14c..b25f2d321e05 100644 |
2205 | --- a/net/phonet/datagram.c |
2206 | +++ b/net/phonet/datagram.c |
2207 | @@ -139,9 +139,6 @@ static int pn_recvmsg(struct kiocb *iocb, struct sock *sk, |
2208 | MSG_CMSG_COMPAT)) |
2209 | goto out_nofree; |
2210 | |
2211 | - if (addr_len) |
2212 | - *addr_len = sizeof(sa); |
2213 | - |
2214 | skb = skb_recv_datagram(sk, flags, noblock, &rval); |
2215 | if (skb == NULL) |
2216 | goto out_nofree; |
2217 | @@ -162,8 +159,10 @@ static int pn_recvmsg(struct kiocb *iocb, struct sock *sk, |
2218 | |
2219 | rval = (flags & MSG_TRUNC) ? skb->len : copylen; |
2220 | |
2221 | - if (msg->msg_name != NULL) |
2222 | - memcpy(msg->msg_name, &sa, sizeof(struct sockaddr_pn)); |
2223 | + if (msg->msg_name != NULL) { |
2224 | + memcpy(msg->msg_name, &sa, sizeof(sa)); |
2225 | + *addr_len = sizeof(sa); |
2226 | + } |
2227 | |
2228 | out: |
2229 | skb_free_datagram(sk, skb); |
2230 | diff --git a/net/rds/recv.c b/net/rds/recv.c |
2231 | index 9f0f17cf6bf9..de339b24ca14 100644 |
2232 | --- a/net/rds/recv.c |
2233 | +++ b/net/rds/recv.c |
2234 | @@ -410,8 +410,6 @@ int rds_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, |
2235 | |
2236 | rdsdebug("size %zu flags 0x%x timeo %ld\n", size, msg_flags, timeo); |
2237 | |
2238 | - msg->msg_namelen = 0; |
2239 | - |
2240 | if (msg_flags & MSG_OOB) |
2241 | goto out; |
2242 | |
2243 | diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c |
2244 | index 7f645d115795..ce5f5b934ea1 100644 |
2245 | --- a/net/rose/af_rose.c |
2246 | +++ b/net/rose/af_rose.c |
2247 | @@ -1220,7 +1220,6 @@ static int rose_recvmsg(struct kiocb *iocb, struct socket *sock, |
2248 | { |
2249 | struct sock *sk = sock->sk; |
2250 | struct rose_sock *rose = rose_sk(sk); |
2251 | - struct sockaddr_rose *srose = (struct sockaddr_rose *)msg->msg_name; |
2252 | size_t copied; |
2253 | unsigned char *asmptr; |
2254 | struct sk_buff *skb; |
2255 | @@ -1256,8 +1255,11 @@ static int rose_recvmsg(struct kiocb *iocb, struct socket *sock, |
2256 | |
2257 | skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied); |
2258 | |
2259 | - if (srose != NULL) { |
2260 | - memset(srose, 0, msg->msg_namelen); |
2261 | + if (msg->msg_name) { |
2262 | + struct sockaddr_rose *srose; |
2263 | + |
2264 | + memset(msg->msg_name, 0, sizeof(struct full_sockaddr_rose)); |
2265 | + srose = msg->msg_name; |
2266 | srose->srose_family = AF_ROSE; |
2267 | srose->srose_addr = rose->dest_addr; |
2268 | srose->srose_call = rose->dest_call; |
2269 | diff --git a/net/rxrpc/ar-recvmsg.c b/net/rxrpc/ar-recvmsg.c |
2270 | index 4b48687c3890..898492a8d61b 100644 |
2271 | --- a/net/rxrpc/ar-recvmsg.c |
2272 | +++ b/net/rxrpc/ar-recvmsg.c |
2273 | @@ -143,10 +143,13 @@ int rxrpc_recvmsg(struct kiocb *iocb, struct socket *sock, |
2274 | |
2275 | /* copy the peer address and timestamp */ |
2276 | if (!continue_call) { |
2277 | - if (msg->msg_name && msg->msg_namelen > 0) |
2278 | + if (msg->msg_name) { |
2279 | + size_t len = |
2280 | + sizeof(call->conn->trans->peer->srx); |
2281 | memcpy(msg->msg_name, |
2282 | - &call->conn->trans->peer->srx, |
2283 | - sizeof(call->conn->trans->peer->srx)); |
2284 | + &call->conn->trans->peer->srx, len); |
2285 | + msg->msg_namelen = len; |
2286 | + } |
2287 | sock_recv_ts_and_drops(msg, &rx->sk, skb); |
2288 | } |
2289 | |
2290 | diff --git a/net/socket.c b/net/socket.c |
2291 | index acc769562707..4006452e8475 100644 |
2292 | --- a/net/socket.c |
2293 | +++ b/net/socket.c |
2294 | @@ -215,12 +215,13 @@ static int move_addr_to_user(struct sockaddr_storage *kaddr, int klen, |
2295 | int err; |
2296 | int len; |
2297 | |
2298 | + BUG_ON(klen > sizeof(struct sockaddr_storage)); |
2299 | err = get_user(len, ulen); |
2300 | if (err) |
2301 | return err; |
2302 | if (len > klen) |
2303 | len = klen; |
2304 | - if (len < 0 || len > sizeof(struct sockaddr_storage)) |
2305 | + if (len < 0) |
2306 | return -EINVAL; |
2307 | if (len) { |
2308 | if (audit_sockaddr(klen, kaddr)) |
2309 | @@ -1775,8 +1776,10 @@ SYSCALL_DEFINE6(recvfrom, int, fd, void __user *, ubuf, size_t, size, |
2310 | msg.msg_iov = &iov; |
2311 | iov.iov_len = size; |
2312 | iov.iov_base = ubuf; |
2313 | - msg.msg_name = (struct sockaddr *)&address; |
2314 | - msg.msg_namelen = sizeof(address); |
2315 | + /* Save some cycles and don't copy the address if not needed */ |
2316 | + msg.msg_name = addr ? (struct sockaddr *)&address : NULL; |
2317 | + /* We assume all kernel code knows the size of sockaddr_storage */ |
2318 | + msg.msg_namelen = 0; |
2319 | if (sock->file->f_flags & O_NONBLOCK) |
2320 | flags |= MSG_DONTWAIT; |
2321 | err = sock_recvmsg(sock, &msg, size, flags); |
2322 | @@ -1905,7 +1908,7 @@ static int copy_msghdr_from_user(struct msghdr *kmsg, |
2323 | if (copy_from_user(kmsg, umsg, sizeof(struct msghdr))) |
2324 | return -EFAULT; |
2325 | if (kmsg->msg_namelen > sizeof(struct sockaddr_storage)) |
2326 | - return -EINVAL; |
2327 | + kmsg->msg_namelen = sizeof(struct sockaddr_storage); |
2328 | return 0; |
2329 | } |
2330 | |
2331 | @@ -2161,16 +2164,14 @@ static int ___sys_recvmsg(struct socket *sock, struct msghdr __user *msg, |
2332 | goto out; |
2333 | } |
2334 | |
2335 | - /* |
2336 | - * Save the user-mode address (verify_iovec will change the |
2337 | - * kernel msghdr to use the kernel address space) |
2338 | + /* Save the user-mode address (verify_iovec will change the |
2339 | + * kernel msghdr to use the kernel address space) |
2340 | */ |
2341 | - |
2342 | uaddr = (__force void __user *)msg_sys->msg_name; |
2343 | uaddr_len = COMPAT_NAMELEN(msg); |
2344 | - if (MSG_CMSG_COMPAT & flags) { |
2345 | + if (MSG_CMSG_COMPAT & flags) |
2346 | err = verify_compat_iovec(msg_sys, iov, &addr, VERIFY_WRITE); |
2347 | - } else |
2348 | + else |
2349 | err = verify_iovec(msg_sys, iov, &addr, VERIFY_WRITE); |
2350 | if (err < 0) |
2351 | goto out_freeiov; |
2352 | @@ -2179,6 +2180,9 @@ static int ___sys_recvmsg(struct socket *sock, struct msghdr __user *msg, |
2353 | cmsg_ptr = (unsigned long)msg_sys->msg_control; |
2354 | msg_sys->msg_flags = flags & (MSG_CMSG_CLOEXEC|MSG_CMSG_COMPAT); |
2355 | |
2356 | + /* We assume all kernel code knows the size of sockaddr_storage */ |
2357 | + msg_sys->msg_namelen = 0; |
2358 | + |
2359 | if (sock->file->f_flags & O_NONBLOCK) |
2360 | flags |= MSG_DONTWAIT; |
2361 | err = (nosec ? sock_recvmsg_nosec : sock_recvmsg)(sock, msg_sys, |
2362 | diff --git a/net/tipc/socket.c b/net/tipc/socket.c |
2363 | index 1441ab70b98c..64b847008ee3 100644 |
2364 | --- a/net/tipc/socket.c |
2365 | +++ b/net/tipc/socket.c |
2366 | @@ -949,9 +949,6 @@ static int recv_msg(struct kiocb *iocb, struct socket *sock, |
2367 | goto exit; |
2368 | } |
2369 | |
2370 | - /* will be updated in set_orig_addr() if needed */ |
2371 | - m->msg_namelen = 0; |
2372 | - |
2373 | timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); |
2374 | restart: |
2375 | |
2376 | @@ -1078,9 +1075,6 @@ static int recv_stream(struct kiocb *iocb, struct socket *sock, |
2377 | goto exit; |
2378 | } |
2379 | |
2380 | - /* will be updated in set_orig_addr() if needed */ |
2381 | - m->msg_namelen = 0; |
2382 | - |
2383 | target = sock_rcvlowat(sk, flags & MSG_WAITALL, buf_len); |
2384 | timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); |
2385 | restart: |
2386 | diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c |
2387 | index ed005b425a7c..0540dd9b0387 100644 |
2388 | --- a/net/unix/af_unix.c |
2389 | +++ b/net/unix/af_unix.c |
2390 | @@ -1755,7 +1755,6 @@ static void unix_copy_addr(struct msghdr *msg, struct sock *sk) |
2391 | { |
2392 | struct unix_sock *u = unix_sk(sk); |
2393 | |
2394 | - msg->msg_namelen = 0; |
2395 | if (u->addr) { |
2396 | msg->msg_namelen = u->addr->len; |
2397 | memcpy(msg->msg_name, u->addr->name, u->addr->len); |
2398 | @@ -1779,8 +1778,6 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock, |
2399 | if (flags&MSG_OOB) |
2400 | goto out; |
2401 | |
2402 | - msg->msg_namelen = 0; |
2403 | - |
2404 | err = mutex_lock_interruptible(&u->readlock); |
2405 | if (err) { |
2406 | err = sock_intr_errno(sock_rcvtimeo(sk, noblock)); |
2407 | @@ -1922,8 +1919,6 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock, |
2408 | target = sock_rcvlowat(sk, flags&MSG_WAITALL, size); |
2409 | timeo = sock_rcvtimeo(sk, flags&MSG_DONTWAIT); |
2410 | |
2411 | - msg->msg_namelen = 0; |
2412 | - |
2413 | /* Lock the socket to prevent queue disordering |
2414 | * while sleeps in memcpy_tomsg |
2415 | */ |
2416 | diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c |
2417 | index b943e3e71bd2..92aed9e45c73 100644 |
2418 | --- a/net/x25/af_x25.c |
2419 | +++ b/net/x25/af_x25.c |
2420 | @@ -1343,10 +1343,9 @@ static int x25_recvmsg(struct kiocb *iocb, struct socket *sock, |
2421 | if (sx25) { |
2422 | sx25->sx25_family = AF_X25; |
2423 | sx25->sx25_addr = x25->dest_addr; |
2424 | + msg->msg_namelen = sizeof(*sx25); |
2425 | } |
2426 | |
2427 | - msg->msg_namelen = sizeof(struct sockaddr_x25); |
2428 | - |
2429 | x25_check_rbuf(sk); |
2430 | rc = copied; |
2431 | out_free_dgram: |