diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2020-05-10 17:53:35 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2020-05-20 20:31:35 -0400 |
commit | 8cacb4165985444c275a6f813f91f08479bdbfad (patch) | |
tree | 00cd065ec52d8e90081edbef1fa7380557eea0e3 | |
parent | 36085049bc0acb6f2e784f430c2cc66944a2ef07 (diff) |
atm: lift copyin from atm_dev_ioctl()
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r-- | net/atm/ioctl.c | 25 | ||||
-rw-r--r-- | net/atm/resources.c | 35 | ||||
-rw-r--r-- | net/atm/resources.h | 4 |
3 files changed, 31 insertions, 33 deletions
diff --git a/net/atm/ioctl.c b/net/atm/ioctl.c index fdd0e3434523..52f2c77e656f 100644 --- a/net/atm/ioctl.c +++ b/net/atm/ioctl.c @@ -182,7 +182,30 @@ static int do_vcc_ioctl(struct socket *sock, unsigned int cmd, } error = atm_getnames(buf, len); } else { - error = atm_dev_ioctl(cmd, argp, compat); + int number; + + if (IS_ENABLED(CONFIG_COMPAT) && compat) { +#ifdef CONFIG_COMPAT + struct compat_atmif_sioc __user *csioc = argp; + compat_uptr_t carg; + + len = &csioc->length; + if (get_user(carg, &csioc->arg)) + return -EFAULT; + buf = compat_ptr(carg); + if (get_user(number, &csioc->number)) + return -EFAULT; +#endif + } else { + struct atmif_sioc __user *sioc = argp; + + len = &sioc->length; + if (get_user(buf, &sioc->arg)) + return -EFAULT; + if (get_user(number, &sioc->number)) + return -EFAULT; + } + error = atm_dev_ioctl(cmd, buf, len, number, compat); } done: diff --git a/net/atm/resources.c b/net/atm/resources.c index 5507cc608969..94bdc6527ee8 100644 --- a/net/atm/resources.c +++ b/net/atm/resources.c @@ -227,39 +227,14 @@ int atm_getnames(void __user *buf, int __user *iobuf_len) return error; } -int atm_dev_ioctl(unsigned int cmd, void __user *arg, int compat) +int atm_dev_ioctl(unsigned int cmd, void __user *buf, int __user *sioc_len, + int number, int compat) { - void __user *buf; - int error, len, number, size = 0; + int error, len, size = 0; struct atm_dev *dev; - int __user *sioc_len; - if (IS_ENABLED(CONFIG_COMPAT) && compat) { -#ifdef CONFIG_COMPAT - struct compat_atmif_sioc __user *csioc = arg; - compat_uptr_t carg; - - sioc_len = &csioc->length; - if (get_user(carg, &csioc->arg)) - return -EFAULT; - buf = compat_ptr(carg); - - if (get_user(len, &csioc->length)) - return -EFAULT; - if (get_user(number, &csioc->number)) - return -EFAULT; -#endif - } else { - struct atmif_sioc __user *sioc = arg; - - sioc_len = &sioc->length; - if (get_user(buf, &sioc->arg)) - return -EFAULT; - if (get_user(len, &sioc->length)) - return -EFAULT; - if (get_user(number, &sioc->number)) - return -EFAULT; - } + if (get_user(len, sioc_len)) + return -EFAULT; dev = try_then_request_module(atm_dev_lookup(number), "atm-device-%d", number); diff --git a/net/atm/resources.h b/net/atm/resources.h index 5e2c68d37d63..4a0839e92ff3 100644 --- a/net/atm/resources.h +++ b/net/atm/resources.h @@ -15,8 +15,8 @@ extern struct list_head atm_devs; extern struct mutex atm_dev_mutex; int atm_getnames(void __user *buf, int __user *iobuf_len); -int atm_dev_ioctl(unsigned int cmd, void __user *arg, int compat); - +int atm_dev_ioctl(unsigned int cmd, void __user *buf, int __user *sioc_len, + int number, int compat); #ifdef CONFIG_PROC_FS |