hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/net/compat.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * 32bit Socket syscall emulation. Based on arch/sparc64/kernel/sys_sparc32.c.
34 *
....@@ -32,10 +33,10 @@
3233 #include <linux/uaccess.h>
3334 #include <net/compat.h>
3435
35
-int get_compat_msghdr(struct msghdr *kmsg,
36
- struct compat_msghdr __user *umsg,
37
- struct sockaddr __user **save_addr,
38
- struct iovec **iov)
36
+int __get_compat_msghdr(struct msghdr *kmsg,
37
+ struct compat_msghdr __user *umsg,
38
+ struct sockaddr __user **save_addr,
39
+ compat_uptr_t *ptr, compat_size_t *len)
3940 {
4041 struct compat_msghdr msg;
4142 ssize_t err;
....@@ -55,7 +56,8 @@
5556 if (kmsg->msg_namelen > sizeof(struct sockaddr_storage))
5657 kmsg->msg_namelen = sizeof(struct sockaddr_storage);
5758
58
- kmsg->msg_control = compat_ptr(msg.msg_control);
59
+ kmsg->msg_control_is_user = true;
60
+ kmsg->msg_control_user = compat_ptr(msg.msg_control);
5961 kmsg->msg_controllen = msg.msg_controllen;
6062
6163 if (save_addr)
....@@ -78,10 +80,27 @@
7880 return -EMSGSIZE;
7981
8082 kmsg->msg_iocb = NULL;
83
+ *ptr = msg.msg_iov;
84
+ *len = msg.msg_iovlen;
85
+ return 0;
86
+}
8187
82
- return compat_import_iovec(save_addr ? READ : WRITE,
83
- compat_ptr(msg.msg_iov), msg.msg_iovlen,
84
- UIO_FASTIOV, iov, &kmsg->msg_iter);
88
+int get_compat_msghdr(struct msghdr *kmsg,
89
+ struct compat_msghdr __user *umsg,
90
+ struct sockaddr __user **save_addr,
91
+ struct iovec **iov)
92
+{
93
+ compat_uptr_t ptr;
94
+ compat_size_t len;
95
+ ssize_t err;
96
+
97
+ err = __get_compat_msghdr(kmsg, umsg, save_addr, &ptr, &len);
98
+ if (err)
99
+ return err;
100
+
101
+ err = import_iovec(save_addr ? READ : WRITE, compat_ptr(ptr), len,
102
+ UIO_FASTIOV, iov, &kmsg->msg_iter);
103
+ return err < 0 ? err : 0;
85104 }
86105
87106 /* Bleech... */
....@@ -103,7 +122,7 @@
103122 ((ucmlen) >= sizeof(struct compat_cmsghdr) && \
104123 (ucmlen) <= (unsigned long) \
105124 ((mhdr)->msg_controllen - \
106
- ((char *)(ucmsg) - (char *)(mhdr)->msg_control)))
125
+ ((char __user *)(ucmsg) - (char __user *)(mhdr)->msg_control_user)))
107126
108127 static inline struct compat_cmsghdr __user *cmsg_compat_nxthdr(struct msghdr *msg,
109128 struct compat_cmsghdr __user *cmsg, int cmsg_len)
....@@ -164,25 +183,26 @@
164183 memset(kcmsg, 0, kcmlen);
165184 ucmsg = CMSG_COMPAT_FIRSTHDR(kmsg);
166185 while (ucmsg != NULL) {
167
- if (__get_user(ucmlen, &ucmsg->cmsg_len))
186
+ struct compat_cmsghdr cmsg;
187
+ if (copy_from_user(&cmsg, ucmsg, sizeof(cmsg)))
168188 goto Efault;
169
- if (!CMSG_COMPAT_OK(ucmlen, ucmsg, kmsg))
189
+ if (!CMSG_COMPAT_OK(cmsg.cmsg_len, ucmsg, kmsg))
170190 goto Einval;
171
- tmp = ((ucmlen - sizeof(*ucmsg)) + sizeof(struct cmsghdr));
191
+ tmp = ((cmsg.cmsg_len - sizeof(*ucmsg)) + sizeof(struct cmsghdr));
172192 if ((char *)kcmsg_base + kcmlen - (char *)kcmsg < CMSG_ALIGN(tmp))
173193 goto Einval;
174194 kcmsg->cmsg_len = tmp;
195
+ kcmsg->cmsg_level = cmsg.cmsg_level;
196
+ kcmsg->cmsg_type = cmsg.cmsg_type;
175197 tmp = CMSG_ALIGN(tmp);
176
- if (__get_user(kcmsg->cmsg_level, &ucmsg->cmsg_level) ||
177
- __get_user(kcmsg->cmsg_type, &ucmsg->cmsg_type) ||
178
- copy_from_user(CMSG_DATA(kcmsg),
198
+ if (copy_from_user(CMSG_DATA(kcmsg),
179199 CMSG_COMPAT_DATA(ucmsg),
180
- (ucmlen - sizeof(*ucmsg))))
200
+ (cmsg.cmsg_len - sizeof(*ucmsg))))
181201 goto Efault;
182202
183203 /* Advance. */
184204 kcmsg = (struct cmsghdr *)((char *)kcmsg + tmp);
185
- ucmsg = cmsg_compat_nxthdr(kmsg, ucmsg, ucmlen);
205
+ ucmsg = cmsg_compat_nxthdr(kmsg, ucmsg, cmsg.cmsg_len);
186206 }
187207
188208 /*
....@@ -209,8 +229,8 @@
209229 {
210230 struct compat_cmsghdr __user *cm = (struct compat_cmsghdr __user *) kmsg->msg_control;
211231 struct compat_cmsghdr cmhdr;
212
- struct compat_timeval ctv;
213
- struct compat_timespec cts[3];
232
+ struct old_timeval32 ctv;
233
+ struct old_timespec32 cts[3];
214234 int cmlen;
215235
216236 if (cm == NULL || kmsg->msg_controllen < sizeof(*cm)) {
....@@ -219,18 +239,18 @@
219239 }
220240
221241 if (!COMPAT_USE_64BIT_TIME) {
222
- if (level == SOL_SOCKET && type == SCM_TIMESTAMP) {
223
- struct timeval *tv = (struct timeval *)data;
242
+ if (level == SOL_SOCKET && type == SO_TIMESTAMP_OLD) {
243
+ struct __kernel_old_timeval *tv = (struct __kernel_old_timeval *)data;
224244 ctv.tv_sec = tv->tv_sec;
225245 ctv.tv_usec = tv->tv_usec;
226246 data = &ctv;
227247 len = sizeof(ctv);
228248 }
229249 if (level == SOL_SOCKET &&
230
- (type == SCM_TIMESTAMPNS || type == SCM_TIMESTAMPING)) {
231
- int count = type == SCM_TIMESTAMPNS ? 1 : 3;
250
+ (type == SO_TIMESTAMPNS_OLD || type == SO_TIMESTAMPING_OLD)) {
251
+ int count = type == SO_TIMESTAMPNS_OLD ? 1 : 3;
232252 int i;
233
- struct timespec *ts = (struct timespec *)data;
253
+ struct __kernel_old_timespec *ts = data;
234254 for (i = 0; i < count; i++) {
235255 cts[i].tv_sec = ts[i].tv_sec;
236256 cts[i].tv_nsec = ts[i].tv_nsec;
....@@ -261,40 +281,31 @@
261281 return 0;
262282 }
263283
264
-void scm_detach_fds_compat(struct msghdr *kmsg, struct scm_cookie *scm)
284
+static int scm_max_fds_compat(struct msghdr *msg)
265285 {
266
- struct compat_cmsghdr __user *cm = (struct compat_cmsghdr __user *) kmsg->msg_control;
267
- int fdmax = (kmsg->msg_controllen - sizeof(struct compat_cmsghdr)) / sizeof(int);
268
- int fdnum = scm->fp->count;
269
- struct file **fp = scm->fp->fp;
270
- int __user *cmfptr;
286
+ if (msg->msg_controllen <= sizeof(struct compat_cmsghdr))
287
+ return 0;
288
+ return (msg->msg_controllen - sizeof(struct compat_cmsghdr)) / sizeof(int);
289
+}
290
+
291
+void scm_detach_fds_compat(struct msghdr *msg, struct scm_cookie *scm)
292
+{
293
+ struct compat_cmsghdr __user *cm =
294
+ (struct compat_cmsghdr __user *)msg->msg_control;
295
+ unsigned int o_flags = (msg->msg_flags & MSG_CMSG_CLOEXEC) ? O_CLOEXEC : 0;
296
+ int fdmax = min_t(int, scm_max_fds_compat(msg), scm->fp->count);
297
+ int __user *cmsg_data = CMSG_COMPAT_DATA(cm);
271298 int err = 0, i;
272299
273
- if (fdnum < fdmax)
274
- fdmax = fdnum;
275
-
276
- for (i = 0, cmfptr = (int __user *) CMSG_COMPAT_DATA(cm); i < fdmax; i++, cmfptr++) {
277
- int new_fd;
278
- err = security_file_receive(fp[i]);
279
- if (err)
280
- break;
281
- err = get_unused_fd_flags(MSG_CMSG_CLOEXEC & kmsg->msg_flags
282
- ? O_CLOEXEC : 0);
300
+ for (i = 0; i < fdmax; i++) {
301
+ err = receive_fd_user(scm->fp->fp[i], cmsg_data + i, o_flags);
283302 if (err < 0)
284303 break;
285
- new_fd = err;
286
- err = put_user(new_fd, cmfptr);
287
- if (err) {
288
- put_unused_fd(new_fd);
289
- break;
290
- }
291
- /* Bump the usage count and install the file. */
292
- __receive_sock(fp[i]);
293
- fd_install(new_fd, get_file(fp[i]));
294304 }
295305
296306 if (i > 0) {
297307 int cmlen = CMSG_COMPAT_LEN(i * sizeof(int));
308
+
298309 err = put_user(SOL_SOCKET, &cm->cmsg_level);
299310 if (!err)
300311 err = put_user(SCM_RIGHTS, &cm->cmsg_type);
....@@ -302,444 +313,22 @@
302313 err = put_user(cmlen, &cm->cmsg_len);
303314 if (!err) {
304315 cmlen = CMSG_COMPAT_SPACE(i * sizeof(int));
305
- kmsg->msg_control += cmlen;
306
- kmsg->msg_controllen -= cmlen;
316
+ if (msg->msg_controllen < cmlen)
317
+ cmlen = msg->msg_controllen;
318
+ msg->msg_control += cmlen;
319
+ msg->msg_controllen -= cmlen;
307320 }
308321 }
309
- if (i < fdnum)
310
- kmsg->msg_flags |= MSG_CTRUNC;
322
+
323
+ if (i < scm->fp->count || (scm->fp->count && fdmax <= 0))
324
+ msg->msg_flags |= MSG_CTRUNC;
311325
312326 /*
313
- * All of the files that fit in the message have had their
314
- * usage counts incremented, so we just free the list.
327
+ * All of the files that fit in the message have had their usage counts
328
+ * incremented, so we just free the list.
315329 */
316330 __scm_destroy(scm);
317331 }
318
-
319
-/* allocate a 64-bit sock_fprog on the user stack for duration of syscall. */
320
-struct sock_fprog __user *get_compat_bpf_fprog(char __user *optval)
321
-{
322
- struct compat_sock_fprog __user *fprog32 = (struct compat_sock_fprog __user *)optval;
323
- struct sock_fprog __user *kfprog = compat_alloc_user_space(sizeof(struct sock_fprog));
324
- struct compat_sock_fprog f32;
325
- struct sock_fprog f;
326
-
327
- if (copy_from_user(&f32, fprog32, sizeof(*fprog32)))
328
- return NULL;
329
- memset(&f, 0, sizeof(f));
330
- f.len = f32.len;
331
- f.filter = compat_ptr(f32.filter);
332
- if (copy_to_user(kfprog, &f, sizeof(struct sock_fprog)))
333
- return NULL;
334
-
335
- return kfprog;
336
-}
337
-EXPORT_SYMBOL_GPL(get_compat_bpf_fprog);
338
-
339
-static int do_set_attach_filter(struct socket *sock, int level, int optname,
340
- char __user *optval, unsigned int optlen)
341
-{
342
- struct sock_fprog __user *kfprog;
343
-
344
- kfprog = get_compat_bpf_fprog(optval);
345
- if (!kfprog)
346
- return -EFAULT;
347
-
348
- return sock_setsockopt(sock, level, optname, (char __user *)kfprog,
349
- sizeof(struct sock_fprog));
350
-}
351
-
352
-static int do_set_sock_timeout(struct socket *sock, int level,
353
- int optname, char __user *optval, unsigned int optlen)
354
-{
355
- struct compat_timeval __user *up = (struct compat_timeval __user *)optval;
356
- struct timeval ktime;
357
- mm_segment_t old_fs;
358
- int err;
359
-
360
- if (optlen < sizeof(*up))
361
- return -EINVAL;
362
- if (!access_ok(VERIFY_READ, up, sizeof(*up)) ||
363
- __get_user(ktime.tv_sec, &up->tv_sec) ||
364
- __get_user(ktime.tv_usec, &up->tv_usec))
365
- return -EFAULT;
366
- old_fs = get_fs();
367
- set_fs(KERNEL_DS);
368
- err = sock_setsockopt(sock, level, optname, (char *)&ktime, sizeof(ktime));
369
- set_fs(old_fs);
370
-
371
- return err;
372
-}
373
-
374
-static int compat_sock_setsockopt(struct socket *sock, int level, int optname,
375
- char __user *optval, unsigned int optlen)
376
-{
377
- if (optname == SO_ATTACH_FILTER ||
378
- optname == SO_ATTACH_REUSEPORT_CBPF)
379
- return do_set_attach_filter(sock, level, optname,
380
- optval, optlen);
381
- if (!COMPAT_USE_64BIT_TIME &&
382
- (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO))
383
- return do_set_sock_timeout(sock, level, optname, optval, optlen);
384
-
385
- return sock_setsockopt(sock, level, optname, optval, optlen);
386
-}
387
-
388
-static int __compat_sys_setsockopt(int fd, int level, int optname,
389
- char __user *optval, unsigned int optlen)
390
-{
391
- int err;
392
- struct socket *sock = sockfd_lookup(fd, &err);
393
-
394
- if (sock) {
395
- err = security_socket_setsockopt(sock, level, optname);
396
- if (err) {
397
- sockfd_put(sock);
398
- return err;
399
- }
400
-
401
- if (level == SOL_SOCKET)
402
- err = compat_sock_setsockopt(sock, level,
403
- optname, optval, optlen);
404
- else if (sock->ops->compat_setsockopt)
405
- err = sock->ops->compat_setsockopt(sock, level,
406
- optname, optval, optlen);
407
- else
408
- err = sock->ops->setsockopt(sock, level,
409
- optname, optval, optlen);
410
- sockfd_put(sock);
411
- }
412
- return err;
413
-}
414
-
415
-COMPAT_SYSCALL_DEFINE5(setsockopt, int, fd, int, level, int, optname,
416
- char __user *, optval, unsigned int, optlen)
417
-{
418
- return __compat_sys_setsockopt(fd, level, optname, optval, optlen);
419
-}
420
-
421
-static int do_get_sock_timeout(struct socket *sock, int level, int optname,
422
- char __user *optval, int __user *optlen)
423
-{
424
- struct compat_timeval __user *up;
425
- struct timeval ktime;
426
- mm_segment_t old_fs;
427
- int len, err;
428
-
429
- up = (struct compat_timeval __user *) optval;
430
- if (get_user(len, optlen))
431
- return -EFAULT;
432
- if (len < sizeof(*up))
433
- return -EINVAL;
434
- len = sizeof(ktime);
435
- old_fs = get_fs();
436
- set_fs(KERNEL_DS);
437
- err = sock_getsockopt(sock, level, optname, (char *) &ktime, &len);
438
- set_fs(old_fs);
439
-
440
- if (!err) {
441
- if (put_user(sizeof(*up), optlen) ||
442
- !access_ok(VERIFY_WRITE, up, sizeof(*up)) ||
443
- __put_user(ktime.tv_sec, &up->tv_sec) ||
444
- __put_user(ktime.tv_usec, &up->tv_usec))
445
- err = -EFAULT;
446
- }
447
- return err;
448
-}
449
-
450
-static int compat_sock_getsockopt(struct socket *sock, int level, int optname,
451
- char __user *optval, int __user *optlen)
452
-{
453
- if (!COMPAT_USE_64BIT_TIME &&
454
- (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO))
455
- return do_get_sock_timeout(sock, level, optname, optval, optlen);
456
- return sock_getsockopt(sock, level, optname, optval, optlen);
457
-}
458
-
459
-int compat_sock_get_timestamp(struct sock *sk, struct timeval __user *userstamp)
460
-{
461
- struct compat_timeval __user *ctv;
462
- int err;
463
- struct timeval tv;
464
-
465
- if (COMPAT_USE_64BIT_TIME)
466
- return sock_get_timestamp(sk, userstamp);
467
-
468
- ctv = (struct compat_timeval __user *) userstamp;
469
- err = -ENOENT;
470
- sock_enable_timestamp(sk, SOCK_TIMESTAMP);
471
- tv = ktime_to_timeval(sock_read_timestamp(sk));
472
-
473
- if (tv.tv_sec == -1)
474
- return err;
475
- if (tv.tv_sec == 0) {
476
- ktime_t kt = ktime_get_real();
477
- sock_write_timestamp(sk, kt);
478
- tv = ktime_to_timeval(kt);
479
- }
480
- err = 0;
481
- if (put_user(tv.tv_sec, &ctv->tv_sec) ||
482
- put_user(tv.tv_usec, &ctv->tv_usec))
483
- err = -EFAULT;
484
- return err;
485
-}
486
-EXPORT_SYMBOL(compat_sock_get_timestamp);
487
-
488
-int compat_sock_get_timestampns(struct sock *sk, struct timespec __user *userstamp)
489
-{
490
- struct compat_timespec __user *ctv;
491
- int err;
492
- struct timespec ts;
493
-
494
- if (COMPAT_USE_64BIT_TIME)
495
- return sock_get_timestampns (sk, userstamp);
496
-
497
- ctv = (struct compat_timespec __user *) userstamp;
498
- err = -ENOENT;
499
- sock_enable_timestamp(sk, SOCK_TIMESTAMP);
500
- ts = ktime_to_timespec(sock_read_timestamp(sk));
501
- if (ts.tv_sec == -1)
502
- return err;
503
- if (ts.tv_sec == 0) {
504
- ktime_t kt = ktime_get_real();
505
- sock_write_timestamp(sk, kt);
506
- ts = ktime_to_timespec(kt);
507
- }
508
- err = 0;
509
- if (put_user(ts.tv_sec, &ctv->tv_sec) ||
510
- put_user(ts.tv_nsec, &ctv->tv_nsec))
511
- err = -EFAULT;
512
- return err;
513
-}
514
-EXPORT_SYMBOL(compat_sock_get_timestampns);
515
-
516
-static int __compat_sys_getsockopt(int fd, int level, int optname,
517
- char __user *optval,
518
- int __user *optlen)
519
-{
520
- int err;
521
- struct socket *sock = sockfd_lookup(fd, &err);
522
-
523
- if (sock) {
524
- err = security_socket_getsockopt(sock, level, optname);
525
- if (err) {
526
- sockfd_put(sock);
527
- return err;
528
- }
529
-
530
- if (level == SOL_SOCKET)
531
- err = compat_sock_getsockopt(sock, level,
532
- optname, optval, optlen);
533
- else if (sock->ops->compat_getsockopt)
534
- err = sock->ops->compat_getsockopt(sock, level,
535
- optname, optval, optlen);
536
- else
537
- err = sock->ops->getsockopt(sock, level,
538
- optname, optval, optlen);
539
- sockfd_put(sock);
540
- }
541
- return err;
542
-}
543
-
544
-COMPAT_SYSCALL_DEFINE5(getsockopt, int, fd, int, level, int, optname,
545
- char __user *, optval, int __user *, optlen)
546
-{
547
- return __compat_sys_getsockopt(fd, level, optname, optval, optlen);
548
-}
549
-
550
-struct compat_group_req {
551
- __u32 gr_interface;
552
- struct __kernel_sockaddr_storage gr_group
553
- __aligned(4);
554
-} __packed;
555
-
556
-struct compat_group_source_req {
557
- __u32 gsr_interface;
558
- struct __kernel_sockaddr_storage gsr_group
559
- __aligned(4);
560
- struct __kernel_sockaddr_storage gsr_source
561
- __aligned(4);
562
-} __packed;
563
-
564
-struct compat_group_filter {
565
- __u32 gf_interface;
566
- struct __kernel_sockaddr_storage gf_group
567
- __aligned(4);
568
- __u32 gf_fmode;
569
- __u32 gf_numsrc;
570
- struct __kernel_sockaddr_storage gf_slist[1]
571
- __aligned(4);
572
-} __packed;
573
-
574
-#define __COMPAT_GF0_SIZE (sizeof(struct compat_group_filter) - \
575
- sizeof(struct __kernel_sockaddr_storage))
576
-
577
-
578
-int compat_mc_setsockopt(struct sock *sock, int level, int optname,
579
- char __user *optval, unsigned int optlen,
580
- int (*setsockopt)(struct sock *, int, int, char __user *, unsigned int))
581
-{
582
- char __user *koptval = optval;
583
- int koptlen = optlen;
584
-
585
- switch (optname) {
586
- case MCAST_JOIN_GROUP:
587
- case MCAST_LEAVE_GROUP:
588
- {
589
- struct compat_group_req __user *gr32 = (void *)optval;
590
- struct group_req __user *kgr =
591
- compat_alloc_user_space(sizeof(struct group_req));
592
- u32 interface;
593
-
594
- if (!access_ok(VERIFY_READ, gr32, sizeof(*gr32)) ||
595
- !access_ok(VERIFY_WRITE, kgr, sizeof(struct group_req)) ||
596
- __get_user(interface, &gr32->gr_interface) ||
597
- __put_user(interface, &kgr->gr_interface) ||
598
- copy_in_user(&kgr->gr_group, &gr32->gr_group,
599
- sizeof(kgr->gr_group)))
600
- return -EFAULT;
601
- koptval = (char __user *)kgr;
602
- koptlen = sizeof(struct group_req);
603
- break;
604
- }
605
- case MCAST_JOIN_SOURCE_GROUP:
606
- case MCAST_LEAVE_SOURCE_GROUP:
607
- case MCAST_BLOCK_SOURCE:
608
- case MCAST_UNBLOCK_SOURCE:
609
- {
610
- struct compat_group_source_req __user *gsr32 = (void *)optval;
611
- struct group_source_req __user *kgsr = compat_alloc_user_space(
612
- sizeof(struct group_source_req));
613
- u32 interface;
614
-
615
- if (!access_ok(VERIFY_READ, gsr32, sizeof(*gsr32)) ||
616
- !access_ok(VERIFY_WRITE, kgsr,
617
- sizeof(struct group_source_req)) ||
618
- __get_user(interface, &gsr32->gsr_interface) ||
619
- __put_user(interface, &kgsr->gsr_interface) ||
620
- copy_in_user(&kgsr->gsr_group, &gsr32->gsr_group,
621
- sizeof(kgsr->gsr_group)) ||
622
- copy_in_user(&kgsr->gsr_source, &gsr32->gsr_source,
623
- sizeof(kgsr->gsr_source)))
624
- return -EFAULT;
625
- koptval = (char __user *)kgsr;
626
- koptlen = sizeof(struct group_source_req);
627
- break;
628
- }
629
- case MCAST_MSFILTER:
630
- {
631
- struct compat_group_filter __user *gf32 = (void *)optval;
632
- struct group_filter __user *kgf;
633
- u32 interface, fmode, numsrc;
634
-
635
- if (!access_ok(VERIFY_READ, gf32, __COMPAT_GF0_SIZE) ||
636
- __get_user(interface, &gf32->gf_interface) ||
637
- __get_user(fmode, &gf32->gf_fmode) ||
638
- __get_user(numsrc, &gf32->gf_numsrc))
639
- return -EFAULT;
640
- koptlen = optlen + sizeof(struct group_filter) -
641
- sizeof(struct compat_group_filter);
642
- if (koptlen < GROUP_FILTER_SIZE(numsrc))
643
- return -EINVAL;
644
- kgf = compat_alloc_user_space(koptlen);
645
- if (!access_ok(VERIFY_WRITE, kgf, koptlen) ||
646
- __put_user(interface, &kgf->gf_interface) ||
647
- __put_user(fmode, &kgf->gf_fmode) ||
648
- __put_user(numsrc, &kgf->gf_numsrc) ||
649
- copy_in_user(&kgf->gf_group, &gf32->gf_group,
650
- sizeof(kgf->gf_group)) ||
651
- (numsrc && copy_in_user(kgf->gf_slist, gf32->gf_slist,
652
- numsrc * sizeof(kgf->gf_slist[0]))))
653
- return -EFAULT;
654
- koptval = (char __user *)kgf;
655
- break;
656
- }
657
-
658
- default:
659
- break;
660
- }
661
- return setsockopt(sock, level, optname, koptval, koptlen);
662
-}
663
-EXPORT_SYMBOL(compat_mc_setsockopt);
664
-
665
-int compat_mc_getsockopt(struct sock *sock, int level, int optname,
666
- char __user *optval, int __user *optlen,
667
- int (*getsockopt)(struct sock *, int, int, char __user *, int __user *))
668
-{
669
- struct compat_group_filter __user *gf32 = (void *)optval;
670
- struct group_filter __user *kgf;
671
- int __user *koptlen;
672
- u32 interface, fmode, numsrc;
673
- int klen, ulen, err;
674
-
675
- if (optname != MCAST_MSFILTER)
676
- return getsockopt(sock, level, optname, optval, optlen);
677
-
678
- koptlen = compat_alloc_user_space(sizeof(*koptlen));
679
- if (!access_ok(VERIFY_READ, optlen, sizeof(*optlen)) ||
680
- __get_user(ulen, optlen))
681
- return -EFAULT;
682
-
683
- /* adjust len for pad */
684
- klen = ulen + sizeof(*kgf) - sizeof(*gf32);
685
-
686
- if (klen < GROUP_FILTER_SIZE(0))
687
- return -EINVAL;
688
-
689
- if (!access_ok(VERIFY_WRITE, koptlen, sizeof(*koptlen)) ||
690
- __put_user(klen, koptlen))
691
- return -EFAULT;
692
-
693
- /* have to allow space for previous compat_alloc_user_space, too */
694
- kgf = compat_alloc_user_space(klen+sizeof(*optlen));
695
-
696
- if (!access_ok(VERIFY_READ, gf32, __COMPAT_GF0_SIZE) ||
697
- __get_user(interface, &gf32->gf_interface) ||
698
- __get_user(fmode, &gf32->gf_fmode) ||
699
- __get_user(numsrc, &gf32->gf_numsrc) ||
700
- __put_user(interface, &kgf->gf_interface) ||
701
- __put_user(fmode, &kgf->gf_fmode) ||
702
- __put_user(numsrc, &kgf->gf_numsrc) ||
703
- copy_in_user(&kgf->gf_group, &gf32->gf_group, sizeof(kgf->gf_group)))
704
- return -EFAULT;
705
-
706
- err = getsockopt(sock, level, optname, (char __user *)kgf, koptlen);
707
- if (err)
708
- return err;
709
-
710
- if (!access_ok(VERIFY_READ, koptlen, sizeof(*koptlen)) ||
711
- __get_user(klen, koptlen))
712
- return -EFAULT;
713
-
714
- ulen = klen - (sizeof(*kgf)-sizeof(*gf32));
715
-
716
- if (!access_ok(VERIFY_WRITE, optlen, sizeof(*optlen)) ||
717
- __put_user(ulen, optlen))
718
- return -EFAULT;
719
-
720
- if (!access_ok(VERIFY_READ, kgf, klen) ||
721
- !access_ok(VERIFY_WRITE, gf32, ulen) ||
722
- __get_user(interface, &kgf->gf_interface) ||
723
- __get_user(fmode, &kgf->gf_fmode) ||
724
- __get_user(numsrc, &kgf->gf_numsrc) ||
725
- __put_user(interface, &gf32->gf_interface) ||
726
- __put_user(fmode, &gf32->gf_fmode) ||
727
- __put_user(numsrc, &gf32->gf_numsrc))
728
- return -EFAULT;
729
- if (numsrc) {
730
- int copylen;
731
-
732
- klen -= GROUP_FILTER_SIZE(0);
733
- copylen = numsrc * sizeof(gf32->gf_slist[0]);
734
- if (copylen > klen)
735
- copylen = klen;
736
- if (copy_in_user(gf32->gf_slist, kgf->gf_slist, copylen))
737
- return -EFAULT;
738
- }
739
- return err;
740
-}
741
-EXPORT_SYMBOL(compat_mc_getsockopt);
742
-
743332
744333 /* Argument list sizes for compat_sys_socketcall */
745334 #define AL(x) ((x) * sizeof(u32))
....@@ -814,34 +403,23 @@
814403 return __compat_sys_recvfrom(fd, buf, len, flags, addr, addrlen);
815404 }
816405
817
-static int __compat_sys_recvmmsg(int fd, struct compat_mmsghdr __user *mmsg,
818
- unsigned int vlen, unsigned int flags,
819
- struct compat_timespec __user *timeout)
820
-{
821
- int datagrams;
822
- struct timespec ktspec;
823
-
824
- if (timeout == NULL)
825
- return __sys_recvmmsg(fd, (struct mmsghdr __user *)mmsg, vlen,
826
- flags | MSG_CMSG_COMPAT, NULL);
827
-
828
- if (compat_get_timespec(&ktspec, timeout))
829
- return -EFAULT;
830
-
831
- datagrams = __sys_recvmmsg(fd, (struct mmsghdr __user *)mmsg, vlen,
832
- flags | MSG_CMSG_COMPAT, &ktspec);
833
- if (datagrams > 0 && compat_put_timespec(&ktspec, timeout))
834
- datagrams = -EFAULT;
835
-
836
- return datagrams;
837
-}
838
-
839
-COMPAT_SYSCALL_DEFINE5(recvmmsg, int, fd, struct compat_mmsghdr __user *, mmsg,
406
+COMPAT_SYSCALL_DEFINE5(recvmmsg_time64, int, fd, struct compat_mmsghdr __user *, mmsg,
840407 unsigned int, vlen, unsigned int, flags,
841
- struct compat_timespec __user *, timeout)
408
+ struct __kernel_timespec __user *, timeout)
842409 {
843
- return __compat_sys_recvmmsg(fd, mmsg, vlen, flags, timeout);
410
+ return __sys_recvmmsg(fd, (struct mmsghdr __user *)mmsg, vlen,
411
+ flags | MSG_CMSG_COMPAT, timeout, NULL);
844412 }
413
+
414
+#ifdef CONFIG_COMPAT_32BIT_TIME
415
+COMPAT_SYSCALL_DEFINE5(recvmmsg_time32, int, fd, struct compat_mmsghdr __user *, mmsg,
416
+ unsigned int, vlen, unsigned int, flags,
417
+ struct old_timespec32 __user *, timeout)
418
+{
419
+ return __sys_recvmmsg(fd, (struct mmsghdr __user *)mmsg, vlen,
420
+ flags | MSG_CMSG_COMPAT, NULL, timeout);
421
+}
422
+#endif
845423
846424 COMPAT_SYSCALL_DEFINE2(socketcall, int, call, u32 __user *, args)
847425 {
....@@ -911,13 +489,11 @@
911489 ret = __sys_shutdown(a0, a1);
912490 break;
913491 case SYS_SETSOCKOPT:
914
- ret = __compat_sys_setsockopt(a0, a1, a[2],
915
- compat_ptr(a[3]), a[4]);
492
+ ret = __sys_setsockopt(a0, a1, a[2], compat_ptr(a[3]), a[4]);
916493 break;
917494 case SYS_GETSOCKOPT:
918
- ret = __compat_sys_getsockopt(a0, a1, a[2],
919
- compat_ptr(a[3]),
920
- compat_ptr(a[4]));
495
+ ret = __sys_getsockopt(a0, a1, a[2], compat_ptr(a[3]),
496
+ compat_ptr(a[4]));
921497 break;
922498 case SYS_SENDMSG:
923499 ret = __compat_sys_sendmsg(a0, compat_ptr(a1), a[2]);
....@@ -929,8 +505,9 @@
929505 ret = __compat_sys_recvmsg(a0, compat_ptr(a1), a[2]);
930506 break;
931507 case SYS_RECVMMSG:
932
- ret = __compat_sys_recvmmsg(a0, compat_ptr(a1), a[2], a[3],
933
- compat_ptr(a[4]));
508
+ ret = __sys_recvmmsg(a0, compat_ptr(a1), a[2],
509
+ a[3] | MSG_CMSG_COMPAT, NULL,
510
+ compat_ptr(a[4]));
934511 break;
935512 case SYS_ACCEPT4:
936513 ret = __sys_accept4(a0, compat_ptr(a1), compat_ptr(a[2]), a[3]);