Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'work.compat' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs

Pull compat_ioctl fixes from Al Viro:
"A bunch of compat_ioctl fixes, mostly in bluetooth.

Hopefully, most of fs/compat_ioctl.c will get killed off over the next
few cycles; between this, tty series already merged and Arnd's work
this cycle ought to take a good chunk out of the damn thing..."

* 'work.compat' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
hidp: fix compat_ioctl
hidp: constify hidp_connection_add()
cmtp: fix compat_ioctl
bnep: fix compat_ioctl
compat_ioctl: trim the pointless includes

+81 -117
+1 -68
fs/compat_ioctl.c
··· 22 22 #include <linux/smp.h> 23 23 #include <linux/ioctl.h> 24 24 #include <linux/if.h> 25 - #include <linux/if_bridge.h> 26 25 #include <linux/raid/md_u.h> 27 - #include <linux/kd.h> 28 - #include <linux/route.h> 29 - #include <linux/in6.h> 30 - #include <linux/ipv6_route.h> 31 - #include <linux/skbuff.h> 32 - #include <linux/netlink.h> 33 - #include <linux/vt.h> 34 26 #include <linux/falloc.h> 35 - #include <linux/fs.h> 36 27 #include <linux/file.h> 37 - #include <linux/ppp_defs.h> 38 28 #include <linux/ppp-ioctl.h> 39 29 #include <linux/if_pppox.h> 40 30 #include <linux/mtio.h> 41 31 #include <linux/tty.h> 42 32 #include <linux/vt_kern.h> 43 - #include <linux/fb.h> 44 - #include <linux/videodev2.h> 45 - #include <linux/netdevice.h> 46 33 #include <linux/raw.h> 47 34 #include <linux/blkdev.h> 48 - #include <linux/elevator.h> 49 35 #include <linux/rtc.h> 50 36 #include <linux/pci.h> 51 37 #include <linux/serial.h> 52 - #include <linux/if_tun.h> 53 38 #include <linux/ctype.h> 54 39 #include <linux/syscalls.h> 55 - #include <linux/atalk.h> 56 40 #include <linux/gfp.h> 57 41 #include <linux/cec.h> 58 42 ··· 58 74 #endif 59 75 60 76 #include <linux/uaccess.h> 61 - #include <linux/ethtool.h> 62 - #include <linux/mii.h> 63 - #include <linux/if_bonding.h> 64 77 #include <linux/watchdog.h> 65 78 66 79 #include <linux/soundcard.h> 67 - #include <linux/lp.h> 68 - #include <linux/ppdev.h> 69 - 70 - #include <linux/atm.h> 71 - #include <linux/atmarp.h> 72 - #include <linux/atmclip.h> 73 - #include <linux/atmdev.h> 74 - #include <linux/atmioc.h> 75 - #include <linux/atmlec.h> 76 - #include <linux/atmmpc.h> 77 - #include <linux/atmsvc.h> 78 - #include <linux/atm_tcp.h> 79 - #include <linux/sonet.h> 80 - #include <linux/atm_suni.h> 81 - 82 - #include <linux/usb.h> 83 - #include <linux/usbdevice_fs.h> 84 - #include <linux/nbd.h> 85 - #include <linux/random.h> 86 - #include <linux/filter.h> 87 80 88 81 #include <linux/hiddev.h> 89 82 ··· 73 112 #include <linux/sort.h> 74 113 75 114 #ifdef CONFIG_SPARC 115 + #include <linux/fb.h> 76 116 #include <asm/fbio.h> 77 117 #endif 78 118 ··· 506 544 #define HCIUARTSETFLAGS _IOW('U', 203, int) 507 545 #define HCIUARTGETFLAGS _IOR('U', 204, int) 508 546 509 - #define BNEPCONNADD _IOW('B', 200, int) 510 - #define BNEPCONNDEL _IOW('B', 201, int) 511 - #define BNEPGETCONNLIST _IOR('B', 210, int) 512 - #define BNEPGETCONNINFO _IOR('B', 211, int) 513 - #define BNEPGETSUPPFEAT _IOR('B', 212, int) 514 - 515 - #define CMTPCONNADD _IOW('C', 200, int) 516 - #define CMTPCONNDEL _IOW('C', 201, int) 517 - #define CMTPGETCONNLIST _IOR('C', 210, int) 518 - #define CMTPGETCONNINFO _IOR('C', 211, int) 519 - 520 - #define HIDPCONNADD _IOW('H', 200, int) 521 - #define HIDPCONNDEL _IOW('H', 201, int) 522 - #define HIDPGETCONNLIST _IOR('H', 210, int) 523 - #define HIDPGETCONNINFO _IOR('H', 211, int) 524 - 525 547 #define RTC_IRQP_READ32 _IOR('p', 0x0b, compat_ulong_t) 526 548 #define RTC_IRQP_SET32 _IOW('p', 0x0c, compat_ulong_t) 527 549 #define RTC_EPOCH_READ32 _IOR('p', 0x0d, compat_ulong_t) ··· 920 974 COMPATIBLE_IOCTL(RFCOMMGETDEVLIST) 921 975 COMPATIBLE_IOCTL(RFCOMMGETDEVINFO) 922 976 COMPATIBLE_IOCTL(RFCOMMSTEALDLC) 923 - COMPATIBLE_IOCTL(BNEPCONNADD) 924 - COMPATIBLE_IOCTL(BNEPCONNDEL) 925 - COMPATIBLE_IOCTL(BNEPGETCONNLIST) 926 - COMPATIBLE_IOCTL(BNEPGETCONNINFO) 927 - COMPATIBLE_IOCTL(BNEPGETSUPPFEAT) 928 - COMPATIBLE_IOCTL(CMTPCONNADD) 929 - COMPATIBLE_IOCTL(CMTPCONNDEL) 930 - COMPATIBLE_IOCTL(CMTPGETCONNLIST) 931 - COMPATIBLE_IOCTL(CMTPGETCONNINFO) 932 - COMPATIBLE_IOCTL(HIDPCONNADD) 933 - COMPATIBLE_IOCTL(HIDPCONNDEL) 934 - COMPATIBLE_IOCTL(HIDPGETCONNLIST) 935 - COMPATIBLE_IOCTL(HIDPGETCONNINFO) 936 977 /* CAPI */ 937 978 COMPATIBLE_IOCTL(CAPI_REGISTER) 938 979 COMPATIBLE_IOCTL(CAPI_GET_MANUFACTURER)
+12 -7
net/bluetooth/bnep/sock.c
··· 49 49 return 0; 50 50 } 51 51 52 - static int bnep_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) 52 + static int do_bnep_sock_ioctl(struct socket *sock, unsigned int cmd, void __user *argp) 53 53 { 54 54 struct bnep_connlist_req cl; 55 55 struct bnep_connadd_req ca; 56 56 struct bnep_conndel_req cd; 57 57 struct bnep_conninfo ci; 58 58 struct socket *nsock; 59 - void __user *argp = (void __user *)arg; 60 59 __u32 supp_feat = BIT(BNEP_SETUP_RESPONSE); 61 60 int err; 62 61 63 - BT_DBG("cmd %x arg %lx", cmd, arg); 62 + BT_DBG("cmd %x arg %p", cmd, argp); 64 63 65 64 switch (cmd) { 66 65 case BNEPCONNADD: ··· 133 134 return 0; 134 135 } 135 136 137 + static int bnep_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) 138 + { 139 + return do_bnep_sock_ioctl(sock, cmd, (void __user *)arg); 140 + } 141 + 136 142 #ifdef CONFIG_COMPAT 137 143 static int bnep_sock_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) 138 144 { 145 + void __user *argp = compat_ptr(arg); 139 146 if (cmd == BNEPGETCONNLIST) { 140 147 struct bnep_connlist_req cl; 148 + unsigned __user *p = argp; 141 149 u32 uci; 142 150 int err; 143 151 144 - if (get_user(cl.cnum, (u32 __user *) arg) || 145 - get_user(uci, (u32 __user *) (arg + 4))) 152 + if (get_user(cl.cnum, p) || get_user(uci, p + 1)) 146 153 return -EFAULT; 147 154 148 155 cl.ci = compat_ptr(uci); ··· 158 153 159 154 err = bnep_get_connlist(&cl); 160 155 161 - if (!err && put_user(cl.cnum, (u32 __user *) arg)) 156 + if (!err && put_user(cl.cnum, p)) 162 157 err = -EFAULT; 163 158 164 159 return err; 165 160 } 166 161 167 - return bnep_sock_ioctl(sock, cmd, arg); 162 + return do_bnep_sock_ioctl(sock, cmd, argp); 168 163 } 169 164 #endif 170 165
+12 -7
net/bluetooth/cmtp/sock.c
··· 63 63 return 0; 64 64 } 65 65 66 - static int cmtp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) 66 + static int do_cmtp_sock_ioctl(struct socket *sock, unsigned int cmd, void __user *argp) 67 67 { 68 68 struct cmtp_connadd_req ca; 69 69 struct cmtp_conndel_req cd; 70 70 struct cmtp_connlist_req cl; 71 71 struct cmtp_conninfo ci; 72 72 struct socket *nsock; 73 - void __user *argp = (void __user *)arg; 74 73 int err; 75 74 76 - BT_DBG("cmd %x arg %lx", cmd, arg); 75 + BT_DBG("cmd %x arg %p", cmd, argp); 77 76 78 77 switch (cmd) { 79 78 case CMTPCONNADD: ··· 136 137 return -EINVAL; 137 138 } 138 139 140 + static int cmtp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) 141 + { 142 + return do_cmtp_sock_ioctl(sock, cmd, (void __user *)arg); 143 + } 144 + 139 145 #ifdef CONFIG_COMPAT 140 146 static int cmtp_sock_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) 141 147 { 148 + void __user *argp = compat_ptr(arg); 142 149 if (cmd == CMTPGETCONNLIST) { 143 150 struct cmtp_connlist_req cl; 151 + u32 __user *p = argp; 144 152 u32 uci; 145 153 int err; 146 154 147 - if (get_user(cl.cnum, (u32 __user *) arg) || 148 - get_user(uci, (u32 __user *) (arg + 4))) 155 + if (get_user(cl.cnum, p) || get_user(uci, p + 1)) 149 156 return -EFAULT; 150 157 151 158 cl.ci = compat_ptr(uci); ··· 161 156 162 157 err = cmtp_get_connlist(&cl); 163 158 164 - if (!err && put_user(cl.cnum, (u32 __user *) arg)) 159 + if (!err && put_user(cl.cnum, p)) 165 160 err = -EFAULT; 166 161 167 162 return err; 168 163 } 169 164 170 - return cmtp_sock_ioctl(sock, cmd, arg); 165 + return do_cmtp_sock_ioctl(sock, cmd, argp); 171 166 } 172 167 #endif 173 168
+5 -5
net/bluetooth/hidp/core.c
··· 649 649 } 650 650 651 651 static int hidp_setup_input(struct hidp_session *session, 652 - struct hidp_connadd_req *req) 652 + const struct hidp_connadd_req *req) 653 653 { 654 654 struct input_dev *input; 655 655 int i; ··· 748 748 /* This function sets up the hid device. It does not add it 749 749 to the HID system. That is done in hidp_add_connection(). */ 750 750 static int hidp_setup_hid(struct hidp_session *session, 751 - struct hidp_connadd_req *req) 751 + const struct hidp_connadd_req *req) 752 752 { 753 753 struct hid_device *hid; 754 754 int err; ··· 807 807 808 808 /* initialize session devices */ 809 809 static int hidp_session_dev_init(struct hidp_session *session, 810 - struct hidp_connadd_req *req) 810 + const struct hidp_connadd_req *req) 811 811 { 812 812 int ret; 813 813 ··· 906 906 static int hidp_session_new(struct hidp_session **out, const bdaddr_t *bdaddr, 907 907 struct socket *ctrl_sock, 908 908 struct socket *intr_sock, 909 - struct hidp_connadd_req *req, 909 + const struct hidp_connadd_req *req, 910 910 struct l2cap_conn *conn) 911 911 { 912 912 struct hidp_session *session; ··· 1338 1338 return 0; 1339 1339 } 1340 1340 1341 - int hidp_connection_add(struct hidp_connadd_req *req, 1341 + int hidp_connection_add(const struct hidp_connadd_req *req, 1342 1342 struct socket *ctrl_sock, 1343 1343 struct socket *intr_sock) 1344 1344 {
+1 -1
net/bluetooth/hidp/hidp.h
··· 122 122 struct hidp_conninfo __user *ci; 123 123 }; 124 124 125 - int hidp_connection_add(struct hidp_connadd_req *req, struct socket *ctrl_sock, struct socket *intr_sock); 125 + int hidp_connection_add(const struct hidp_connadd_req *req, struct socket *ctrl_sock, struct socket *intr_sock); 126 126 int hidp_connection_del(struct hidp_conndel_req *req); 127 127 int hidp_get_connlist(struct hidp_connlist_req *req); 128 128 int hidp_get_conninfo(struct hidp_conninfo *ci);
+50 -29
net/bluetooth/hidp/sock.c
··· 46 46 return 0; 47 47 } 48 48 49 - static int hidp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) 49 + static int do_hidp_sock_ioctl(struct socket *sock, unsigned int cmd, void __user *argp) 50 50 { 51 - void __user *argp = (void __user *) arg; 52 51 struct hidp_connadd_req ca; 53 52 struct hidp_conndel_req cd; 54 53 struct hidp_connlist_req cl; ··· 56 57 struct socket *isock; 57 58 int err; 58 59 59 - BT_DBG("cmd %x arg %lx", cmd, arg); 60 + BT_DBG("cmd %x arg %p", cmd, argp); 60 61 61 62 switch (cmd) { 62 63 case HIDPCONNADD: ··· 121 122 return -EINVAL; 122 123 } 123 124 125 + static int hidp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) 126 + { 127 + return do_hidp_sock_ioctl(sock, cmd, (void __user *)arg); 128 + } 129 + 124 130 #ifdef CONFIG_COMPAT 125 131 struct compat_hidp_connadd_req { 126 132 int ctrl_sock; /* Connected control socket */ ··· 145 141 146 142 static int hidp_sock_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) 147 143 { 144 + void __user *argp = compat_ptr(arg); 145 + int err; 146 + 148 147 if (cmd == HIDPGETCONNLIST) { 149 148 struct hidp_connlist_req cl; 149 + u32 __user *p = argp; 150 150 u32 uci; 151 - int err; 152 151 153 - if (get_user(cl.cnum, (u32 __user *) arg) || 154 - get_user(uci, (u32 __user *) (arg + 4))) 152 + if (get_user(cl.cnum, p) || get_user(uci, p + 1)) 155 153 return -EFAULT; 156 154 157 155 cl.ci = compat_ptr(uci); ··· 163 157 164 158 err = hidp_get_connlist(&cl); 165 159 166 - if (!err && put_user(cl.cnum, (u32 __user *) arg)) 160 + if (!err && put_user(cl.cnum, p)) 167 161 err = -EFAULT; 168 162 169 163 return err; 170 164 } else if (cmd == HIDPCONNADD) { 171 - struct compat_hidp_connadd_req ca; 172 - struct hidp_connadd_req __user *uca; 165 + struct compat_hidp_connadd_req ca32; 166 + struct hidp_connadd_req ca; 167 + struct socket *csock; 168 + struct socket *isock; 173 169 174 - uca = compat_alloc_user_space(sizeof(*uca)); 170 + if (!capable(CAP_NET_ADMIN)) 171 + return -EPERM; 175 172 176 - if (copy_from_user(&ca, (void __user *) arg, sizeof(ca))) 173 + if (copy_from_user(&ca32, (void __user *) arg, sizeof(ca32))) 177 174 return -EFAULT; 178 175 179 - if (put_user(ca.ctrl_sock, &uca->ctrl_sock) || 180 - put_user(ca.intr_sock, &uca->intr_sock) || 181 - put_user(ca.parser, &uca->parser) || 182 - put_user(ca.rd_size, &uca->rd_size) || 183 - put_user(compat_ptr(ca.rd_data), &uca->rd_data) || 184 - put_user(ca.country, &uca->country) || 185 - put_user(ca.subclass, &uca->subclass) || 186 - put_user(ca.vendor, &uca->vendor) || 187 - put_user(ca.product, &uca->product) || 188 - put_user(ca.version, &uca->version) || 189 - put_user(ca.flags, &uca->flags) || 190 - put_user(ca.idle_to, &uca->idle_to) || 191 - copy_to_user(&uca->name[0], &ca.name[0], 128)) 192 - return -EFAULT; 176 + ca.ctrl_sock = ca32.ctrl_sock; 177 + ca.intr_sock = ca32.intr_sock; 178 + ca.parser = ca32.parser; 179 + ca.rd_size = ca32.rd_size; 180 + ca.rd_data = compat_ptr(ca32.rd_data); 181 + ca.country = ca32.country; 182 + ca.subclass = ca32.subclass; 183 + ca.vendor = ca32.vendor; 184 + ca.product = ca32.product; 185 + ca.version = ca32.version; 186 + ca.flags = ca32.flags; 187 + ca.idle_to = ca32.idle_to; 188 + memcpy(ca.name, ca32.name, 128); 193 189 194 - arg = (unsigned long) uca; 190 + csock = sockfd_lookup(ca.ctrl_sock, &err); 191 + if (!csock) 192 + return err; 195 193 196 - /* Fall through. We don't actually write back any _changes_ 197 - to the structure anyway, so there's no need to copy back 198 - into the original compat version */ 194 + isock = sockfd_lookup(ca.intr_sock, &err); 195 + if (!isock) { 196 + sockfd_put(csock); 197 + return err; 198 + } 199 + 200 + err = hidp_connection_add(&ca, csock, isock); 201 + if (!err && copy_to_user(argp, &ca32, sizeof(ca32))) 202 + err = -EFAULT; 203 + 204 + sockfd_put(csock); 205 + sockfd_put(isock); 206 + 207 + return err; 199 208 } 200 209 201 210 return hidp_sock_ioctl(sock, cmd, arg);