Commit ba7d4f36 authored by Linus Torvalds's avatar Linus Torvalds

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
parents 5947a64a 702ec307
...@@ -22,37 +22,21 @@ ...@@ -22,37 +22,21 @@
#include <linux/smp.h> #include <linux/smp.h>
#include <linux/ioctl.h> #include <linux/ioctl.h>
#include <linux/if.h> #include <linux/if.h>
#include <linux/if_bridge.h>
#include <linux/raid/md_u.h> #include <linux/raid/md_u.h>
#include <linux/kd.h>
#include <linux/route.h>
#include <linux/in6.h>
#include <linux/ipv6_route.h>
#include <linux/skbuff.h>
#include <linux/netlink.h>
#include <linux/vt.h>
#include <linux/falloc.h> #include <linux/falloc.h>
#include <linux/fs.h>
#include <linux/file.h> #include <linux/file.h>
#include <linux/ppp_defs.h>
#include <linux/ppp-ioctl.h> #include <linux/ppp-ioctl.h>
#include <linux/if_pppox.h> #include <linux/if_pppox.h>
#include <linux/mtio.h> #include <linux/mtio.h>
#include <linux/tty.h> #include <linux/tty.h>
#include <linux/vt_kern.h> #include <linux/vt_kern.h>
#include <linux/fb.h>
#include <linux/videodev2.h>
#include <linux/netdevice.h>
#include <linux/raw.h> #include <linux/raw.h>
#include <linux/blkdev.h> #include <linux/blkdev.h>
#include <linux/elevator.h>
#include <linux/rtc.h> #include <linux/rtc.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/serial.h> #include <linux/serial.h>
#include <linux/if_tun.h>
#include <linux/ctype.h> #include <linux/ctype.h>
#include <linux/syscalls.h> #include <linux/syscalls.h>
#include <linux/atalk.h>
#include <linux/gfp.h> #include <linux/gfp.h>
#include <linux/cec.h> #include <linux/cec.h>
...@@ -74,32 +58,9 @@ ...@@ -74,32 +58,9 @@
#endif #endif
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <linux/ethtool.h>
#include <linux/mii.h>
#include <linux/if_bonding.h>
#include <linux/watchdog.h> #include <linux/watchdog.h>
#include <linux/soundcard.h> #include <linux/soundcard.h>
#include <linux/lp.h>
#include <linux/ppdev.h>
#include <linux/atm.h>
#include <linux/atmarp.h>
#include <linux/atmclip.h>
#include <linux/atmdev.h>
#include <linux/atmioc.h>
#include <linux/atmlec.h>
#include <linux/atmmpc.h>
#include <linux/atmsvc.h>
#include <linux/atm_tcp.h>
#include <linux/sonet.h>
#include <linux/atm_suni.h>
#include <linux/usb.h>
#include <linux/usbdevice_fs.h>
#include <linux/nbd.h>
#include <linux/random.h>
#include <linux/filter.h>
#include <linux/hiddev.h> #include <linux/hiddev.h>
...@@ -112,6 +73,7 @@ ...@@ -112,6 +73,7 @@
#include <linux/sort.h> #include <linux/sort.h>
#ifdef CONFIG_SPARC #ifdef CONFIG_SPARC
#include <linux/fb.h>
#include <asm/fbio.h> #include <asm/fbio.h>
#endif #endif
...@@ -544,22 +506,6 @@ static int mt_ioctl_trans(struct file *file, ...@@ -544,22 +506,6 @@ static int mt_ioctl_trans(struct file *file,
#define HCIUARTSETFLAGS _IOW('U', 203, int) #define HCIUARTSETFLAGS _IOW('U', 203, int)
#define HCIUARTGETFLAGS _IOR('U', 204, int) #define HCIUARTGETFLAGS _IOR('U', 204, int)
#define BNEPCONNADD _IOW('B', 200, int)
#define BNEPCONNDEL _IOW('B', 201, int)
#define BNEPGETCONNLIST _IOR('B', 210, int)
#define BNEPGETCONNINFO _IOR('B', 211, int)
#define BNEPGETSUPPFEAT _IOR('B', 212, int)
#define CMTPCONNADD _IOW('C', 200, int)
#define CMTPCONNDEL _IOW('C', 201, int)
#define CMTPGETCONNLIST _IOR('C', 210, int)
#define CMTPGETCONNINFO _IOR('C', 211, int)
#define HIDPCONNADD _IOW('H', 200, int)
#define HIDPCONNDEL _IOW('H', 201, int)
#define HIDPGETCONNLIST _IOR('H', 210, int)
#define HIDPGETCONNINFO _IOR('H', 211, int)
#define RTC_IRQP_READ32 _IOR('p', 0x0b, compat_ulong_t) #define RTC_IRQP_READ32 _IOR('p', 0x0b, compat_ulong_t)
#define RTC_IRQP_SET32 _IOW('p', 0x0c, compat_ulong_t) #define RTC_IRQP_SET32 _IOW('p', 0x0c, compat_ulong_t)
#define RTC_EPOCH_READ32 _IOR('p', 0x0d, compat_ulong_t) #define RTC_EPOCH_READ32 _IOR('p', 0x0d, compat_ulong_t)
...@@ -974,19 +920,6 @@ COMPATIBLE_IOCTL(RFCOMMRELEASEDEV) ...@@ -974,19 +920,6 @@ COMPATIBLE_IOCTL(RFCOMMRELEASEDEV)
COMPATIBLE_IOCTL(RFCOMMGETDEVLIST) COMPATIBLE_IOCTL(RFCOMMGETDEVLIST)
COMPATIBLE_IOCTL(RFCOMMGETDEVINFO) COMPATIBLE_IOCTL(RFCOMMGETDEVINFO)
COMPATIBLE_IOCTL(RFCOMMSTEALDLC) COMPATIBLE_IOCTL(RFCOMMSTEALDLC)
COMPATIBLE_IOCTL(BNEPCONNADD)
COMPATIBLE_IOCTL(BNEPCONNDEL)
COMPATIBLE_IOCTL(BNEPGETCONNLIST)
COMPATIBLE_IOCTL(BNEPGETCONNINFO)
COMPATIBLE_IOCTL(BNEPGETSUPPFEAT)
COMPATIBLE_IOCTL(CMTPCONNADD)
COMPATIBLE_IOCTL(CMTPCONNDEL)
COMPATIBLE_IOCTL(CMTPGETCONNLIST)
COMPATIBLE_IOCTL(CMTPGETCONNINFO)
COMPATIBLE_IOCTL(HIDPCONNADD)
COMPATIBLE_IOCTL(HIDPCONNDEL)
COMPATIBLE_IOCTL(HIDPGETCONNLIST)
COMPATIBLE_IOCTL(HIDPGETCONNINFO)
/* CAPI */ /* CAPI */
COMPATIBLE_IOCTL(CAPI_REGISTER) COMPATIBLE_IOCTL(CAPI_REGISTER)
COMPATIBLE_IOCTL(CAPI_GET_MANUFACTURER) COMPATIBLE_IOCTL(CAPI_GET_MANUFACTURER)
......
...@@ -49,18 +49,17 @@ static int bnep_sock_release(struct socket *sock) ...@@ -49,18 +49,17 @@ static int bnep_sock_release(struct socket *sock)
return 0; return 0;
} }
static int bnep_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) static int do_bnep_sock_ioctl(struct socket *sock, unsigned int cmd, void __user *argp)
{ {
struct bnep_connlist_req cl; struct bnep_connlist_req cl;
struct bnep_connadd_req ca; struct bnep_connadd_req ca;
struct bnep_conndel_req cd; struct bnep_conndel_req cd;
struct bnep_conninfo ci; struct bnep_conninfo ci;
struct socket *nsock; struct socket *nsock;
void __user *argp = (void __user *)arg;
__u32 supp_feat = BIT(BNEP_SETUP_RESPONSE); __u32 supp_feat = BIT(BNEP_SETUP_RESPONSE);
int err; int err;
BT_DBG("cmd %x arg %lx", cmd, arg); BT_DBG("cmd %x arg %p", cmd, argp);
switch (cmd) { switch (cmd) {
case BNEPCONNADD: case BNEPCONNADD:
...@@ -134,16 +133,22 @@ static int bnep_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long ...@@ -134,16 +133,22 @@ static int bnep_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long
return 0; return 0;
} }
static int bnep_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
{
return do_bnep_sock_ioctl(sock, cmd, (void __user *)arg);
}
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
static int bnep_sock_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) static int bnep_sock_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
{ {
void __user *argp = compat_ptr(arg);
if (cmd == BNEPGETCONNLIST) { if (cmd == BNEPGETCONNLIST) {
struct bnep_connlist_req cl; struct bnep_connlist_req cl;
unsigned __user *p = argp;
u32 uci; u32 uci;
int err; int err;
if (get_user(cl.cnum, (u32 __user *) arg) || if (get_user(cl.cnum, p) || get_user(uci, p + 1))
get_user(uci, (u32 __user *) (arg + 4)))
return -EFAULT; return -EFAULT;
cl.ci = compat_ptr(uci); cl.ci = compat_ptr(uci);
...@@ -153,13 +158,13 @@ static int bnep_sock_compat_ioctl(struct socket *sock, unsigned int cmd, unsigne ...@@ -153,13 +158,13 @@ static int bnep_sock_compat_ioctl(struct socket *sock, unsigned int cmd, unsigne
err = bnep_get_connlist(&cl); err = bnep_get_connlist(&cl);
if (!err && put_user(cl.cnum, (u32 __user *) arg)) if (!err && put_user(cl.cnum, p))
err = -EFAULT; err = -EFAULT;
return err; return err;
} }
return bnep_sock_ioctl(sock, cmd, arg); return do_bnep_sock_ioctl(sock, cmd, argp);
} }
#endif #endif
......
...@@ -63,17 +63,16 @@ static int cmtp_sock_release(struct socket *sock) ...@@ -63,17 +63,16 @@ static int cmtp_sock_release(struct socket *sock)
return 0; return 0;
} }
static int cmtp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) static int do_cmtp_sock_ioctl(struct socket *sock, unsigned int cmd, void __user *argp)
{ {
struct cmtp_connadd_req ca; struct cmtp_connadd_req ca;
struct cmtp_conndel_req cd; struct cmtp_conndel_req cd;
struct cmtp_connlist_req cl; struct cmtp_connlist_req cl;
struct cmtp_conninfo ci; struct cmtp_conninfo ci;
struct socket *nsock; struct socket *nsock;
void __user *argp = (void __user *)arg;
int err; int err;
BT_DBG("cmd %x arg %lx", cmd, arg); BT_DBG("cmd %x arg %p", cmd, argp);
switch (cmd) { switch (cmd) {
case CMTPCONNADD: case CMTPCONNADD:
...@@ -137,16 +136,22 @@ static int cmtp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long ...@@ -137,16 +136,22 @@ static int cmtp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long
return -EINVAL; return -EINVAL;
} }
static int cmtp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
{
return do_cmtp_sock_ioctl(sock, cmd, (void __user *)arg);
}
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
static int cmtp_sock_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) static int cmtp_sock_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
{ {
void __user *argp = compat_ptr(arg);
if (cmd == CMTPGETCONNLIST) { if (cmd == CMTPGETCONNLIST) {
struct cmtp_connlist_req cl; struct cmtp_connlist_req cl;
u32 __user *p = argp;
u32 uci; u32 uci;
int err; int err;
if (get_user(cl.cnum, (u32 __user *) arg) || if (get_user(cl.cnum, p) || get_user(uci, p + 1))
get_user(uci, (u32 __user *) (arg + 4)))
return -EFAULT; return -EFAULT;
cl.ci = compat_ptr(uci); cl.ci = compat_ptr(uci);
...@@ -156,13 +161,13 @@ static int cmtp_sock_compat_ioctl(struct socket *sock, unsigned int cmd, unsigne ...@@ -156,13 +161,13 @@ static int cmtp_sock_compat_ioctl(struct socket *sock, unsigned int cmd, unsigne
err = cmtp_get_connlist(&cl); err = cmtp_get_connlist(&cl);
if (!err && put_user(cl.cnum, (u32 __user *) arg)) if (!err && put_user(cl.cnum, p))
err = -EFAULT; err = -EFAULT;
return err; return err;
} }
return cmtp_sock_ioctl(sock, cmd, arg); return do_cmtp_sock_ioctl(sock, cmd, argp);
} }
#endif #endif
......
...@@ -649,7 +649,7 @@ static void hidp_process_transmit(struct hidp_session *session, ...@@ -649,7 +649,7 @@ static void hidp_process_transmit(struct hidp_session *session,
} }
static int hidp_setup_input(struct hidp_session *session, static int hidp_setup_input(struct hidp_session *session,
struct hidp_connadd_req *req) const struct hidp_connadd_req *req)
{ {
struct input_dev *input; struct input_dev *input;
int i; int i;
...@@ -748,7 +748,7 @@ EXPORT_SYMBOL_GPL(hidp_hid_driver); ...@@ -748,7 +748,7 @@ EXPORT_SYMBOL_GPL(hidp_hid_driver);
/* This function sets up the hid device. It does not add it /* This function sets up the hid device. It does not add it
to the HID system. That is done in hidp_add_connection(). */ to the HID system. That is done in hidp_add_connection(). */
static int hidp_setup_hid(struct hidp_session *session, static int hidp_setup_hid(struct hidp_session *session,
struct hidp_connadd_req *req) const struct hidp_connadd_req *req)
{ {
struct hid_device *hid; struct hid_device *hid;
int err; int err;
...@@ -807,7 +807,7 @@ static int hidp_setup_hid(struct hidp_session *session, ...@@ -807,7 +807,7 @@ static int hidp_setup_hid(struct hidp_session *session,
/* initialize session devices */ /* initialize session devices */
static int hidp_session_dev_init(struct hidp_session *session, static int hidp_session_dev_init(struct hidp_session *session,
struct hidp_connadd_req *req) const struct hidp_connadd_req *req)
{ {
int ret; int ret;
...@@ -906,7 +906,7 @@ static void hidp_session_dev_work(struct work_struct *work) ...@@ -906,7 +906,7 @@ static void hidp_session_dev_work(struct work_struct *work)
static int hidp_session_new(struct hidp_session **out, const bdaddr_t *bdaddr, static int hidp_session_new(struct hidp_session **out, const bdaddr_t *bdaddr,
struct socket *ctrl_sock, struct socket *ctrl_sock,
struct socket *intr_sock, struct socket *intr_sock,
struct hidp_connadd_req *req, const struct hidp_connadd_req *req,
struct l2cap_conn *conn) struct l2cap_conn *conn)
{ {
struct hidp_session *session; struct hidp_session *session;
...@@ -1338,7 +1338,7 @@ static int hidp_verify_sockets(struct socket *ctrl_sock, ...@@ -1338,7 +1338,7 @@ static int hidp_verify_sockets(struct socket *ctrl_sock,
return 0; return 0;
} }
int hidp_connection_add(struct hidp_connadd_req *req, int hidp_connection_add(const struct hidp_connadd_req *req,
struct socket *ctrl_sock, struct socket *ctrl_sock,
struct socket *intr_sock) struct socket *intr_sock)
{ {
......
...@@ -122,7 +122,7 @@ struct hidp_connlist_req { ...@@ -122,7 +122,7 @@ struct hidp_connlist_req {
struct hidp_conninfo __user *ci; struct hidp_conninfo __user *ci;
}; };
int hidp_connection_add(struct hidp_connadd_req *req, struct socket *ctrl_sock, struct socket *intr_sock); int hidp_connection_add(const struct hidp_connadd_req *req, struct socket *ctrl_sock, struct socket *intr_sock);
int hidp_connection_del(struct hidp_conndel_req *req); int hidp_connection_del(struct hidp_conndel_req *req);
int hidp_get_connlist(struct hidp_connlist_req *req); int hidp_get_connlist(struct hidp_connlist_req *req);
int hidp_get_conninfo(struct hidp_conninfo *ci); int hidp_get_conninfo(struct hidp_conninfo *ci);
......
...@@ -46,9 +46,8 @@ static int hidp_sock_release(struct socket *sock) ...@@ -46,9 +46,8 @@ static int hidp_sock_release(struct socket *sock)
return 0; return 0;
} }
static int hidp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) static int do_hidp_sock_ioctl(struct socket *sock, unsigned int cmd, void __user *argp)
{ {
void __user *argp = (void __user *) arg;
struct hidp_connadd_req ca; struct hidp_connadd_req ca;
struct hidp_conndel_req cd; struct hidp_conndel_req cd;
struct hidp_connlist_req cl; struct hidp_connlist_req cl;
...@@ -57,7 +56,7 @@ static int hidp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long ...@@ -57,7 +56,7 @@ static int hidp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long
struct socket *isock; struct socket *isock;
int err; int err;
BT_DBG("cmd %x arg %lx", cmd, arg); BT_DBG("cmd %x arg %p", cmd, argp);
switch (cmd) { switch (cmd) {
case HIDPCONNADD: case HIDPCONNADD:
...@@ -122,6 +121,11 @@ static int hidp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long ...@@ -122,6 +121,11 @@ static int hidp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long
return -EINVAL; return -EINVAL;
} }
static int hidp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
{
return do_hidp_sock_ioctl(sock, cmd, (void __user *)arg);
}
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
struct compat_hidp_connadd_req { struct compat_hidp_connadd_req {
int ctrl_sock; /* Connected control socket */ int ctrl_sock; /* Connected control socket */
...@@ -141,13 +145,15 @@ struct compat_hidp_connadd_req { ...@@ -141,13 +145,15 @@ struct compat_hidp_connadd_req {
static int hidp_sock_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) static int hidp_sock_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
{ {
void __user *argp = compat_ptr(arg);
int err;
if (cmd == HIDPGETCONNLIST) { if (cmd == HIDPGETCONNLIST) {
struct hidp_connlist_req cl; struct hidp_connlist_req cl;
u32 __user *p = argp;
u32 uci; u32 uci;
int err;
if (get_user(cl.cnum, (u32 __user *) arg) || if (get_user(cl.cnum, p) || get_user(uci, p + 1))
get_user(uci, (u32 __user *) (arg + 4)))
return -EFAULT; return -EFAULT;
cl.ci = compat_ptr(uci); cl.ci = compat_ptr(uci);
...@@ -157,39 +163,54 @@ static int hidp_sock_compat_ioctl(struct socket *sock, unsigned int cmd, unsigne ...@@ -157,39 +163,54 @@ static int hidp_sock_compat_ioctl(struct socket *sock, unsigned int cmd, unsigne
err = hidp_get_connlist(&cl); err = hidp_get_connlist(&cl);
if (!err && put_user(cl.cnum, (u32 __user *) arg)) if (!err && put_user(cl.cnum, p))
err = -EFAULT; err = -EFAULT;
return err; return err;
} else if (cmd == HIDPCONNADD) { } else if (cmd == HIDPCONNADD) {
struct compat_hidp_connadd_req ca; struct compat_hidp_connadd_req ca32;
struct hidp_connadd_req __user *uca; struct hidp_connadd_req ca;
struct socket *csock;
struct socket *isock;
uca = compat_alloc_user_space(sizeof(*uca)); if (!capable(CAP_NET_ADMIN))
return -EPERM;
if (copy_from_user(&ca, (void __user *) arg, sizeof(ca))) if (copy_from_user(&ca32, (void __user *) arg, sizeof(ca32)))
return -EFAULT; return -EFAULT;
if (put_user(ca.ctrl_sock, &uca->ctrl_sock) || ca.ctrl_sock = ca32.ctrl_sock;
put_user(ca.intr_sock, &uca->intr_sock) || ca.intr_sock = ca32.intr_sock;
put_user(ca.parser, &uca->parser) || ca.parser = ca32.parser;
put_user(ca.rd_size, &uca->rd_size) || ca.rd_size = ca32.rd_size;
put_user(compat_ptr(ca.rd_data), &uca->rd_data) || ca.rd_data = compat_ptr(ca32.rd_data);
put_user(ca.country, &uca->country) || ca.country = ca32.country;
put_user(ca.subclass, &uca->subclass) || ca.subclass = ca32.subclass;
put_user(ca.vendor, &uca->vendor) || ca.vendor = ca32.vendor;
put_user(ca.product, &uca->product) || ca.product = ca32.product;
put_user(ca.version, &uca->version) || ca.version = ca32.version;
put_user(ca.flags, &uca->flags) || ca.flags = ca32.flags;
put_user(ca.idle_to, &uca->idle_to) || ca.idle_to = ca32.idle_to;
copy_to_user(&uca->name[0], &ca.name[0], 128)) memcpy(ca.name, ca32.name, 128);
return -EFAULT;
csock = sockfd_lookup(ca.ctrl_sock, &err);
if (!csock)
return err;
arg = (unsigned long) uca; isock = sockfd_lookup(ca.intr_sock, &err);
if (!isock) {
sockfd_put(csock);
return err;
}
/* Fall through. We don't actually write back any _changes_ err = hidp_connection_add(&ca, csock, isock);
to the structure anyway, so there's no need to copy back if (!err && copy_to_user(argp, &ca32, sizeof(ca32)))
into the original compat version */ err = -EFAULT;
sockfd_put(csock);
sockfd_put(isock);
return err;
} }
return hidp_sock_ioctl(sock, cmd, arg); return hidp_sock_ioctl(sock, cmd, arg);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment