compat_ioctl: move PPPIOCSCOMPRESS to ppp_generic
authorAl Viro <viro@zeniv.linux.org.uk>
Thu, 18 Apr 2019 04:31:54 +0000 (00:31 -0400)
committerArnd Bergmann <arnd@arndb.de>
Wed, 23 Oct 2019 15:23:47 +0000 (17:23 +0200)
Rather than using a compat_alloc_user_space() buffer, moving
this next to the native handler allows sharing most of
the code, leaving only the user copy portion distinct.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Cc: netdev@vger.kernel.org
Cc: linux-ppp@vger.kernel.org
Cc: Paul Mackerras <paulus@samba.org>
Cc: "David S. Miller" <davem@davemloft.net>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
drivers/net/ppp/ppp_generic.c
fs/compat_ioctl.c

index 7f8430e..fb8e0ac 100644 (file)
@@ -270,7 +270,7 @@ static void ppp_mp_insert(struct ppp *ppp, struct sk_buff *skb);
 static struct sk_buff *ppp_mp_reconstruct(struct ppp *ppp);
 static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb);
 #endif /* CONFIG_PPP_MULTILINK */
-static int ppp_set_compress(struct ppp *ppp, unsigned long arg);
+static int ppp_set_compress(struct ppp *ppp, struct ppp_option_data *data);
 static void ppp_ccp_peek(struct ppp *ppp, struct sk_buff *skb, int inbound);
 static void ppp_ccp_closed(struct ppp *ppp);
 static struct compressor *find_compressor(int type);
@@ -708,9 +708,14 @@ static long ppp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                break;
 
        case PPPIOCSCOMPRESS:
-               err = ppp_set_compress(ppp, arg);
+       {
+               struct ppp_option_data data;
+               if (copy_from_user(&data, argp, sizeof(data)))
+                       err = -EFAULT;
+               else
+                       err = ppp_set_compress(ppp, &data);
                break;
-
+       }
        case PPPIOCGUNIT:
                if (put_user(ppp->file.index, p))
                        break;
@@ -827,6 +832,13 @@ out:
 }
 
 #ifdef CONFIG_COMPAT
+struct ppp_option_data32 {
+       compat_uptr_t           ptr;
+       u32                     length;
+       compat_int_t            transmit;
+};
+#define PPPIOCSCOMPRESS32      _IOW('t', 77, struct ppp_option_data32)
+
 static long ppp_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
        struct ppp_file *pf;
@@ -863,6 +875,21 @@ static long ppp_compat_ioctl(struct file *file, unsigned int cmd, unsigned long
                        break;
                }
 #endif /* CONFIG_PPP_FILTER */
+               case PPPIOCSCOMPRESS32:
+               {
+                       struct ppp_option_data32 data32;
+                       if (copy_from_user(&data32, argp, sizeof(data32))) {
+                               err = -EFAULT;
+                       } else {
+                               struct ppp_option_data data = {
+                                       .ptr = compat_ptr(data32.ptr),
+                                       .length = data32.length,
+                                       .transmit = data32.transmit
+                               };
+                               err = ppp_set_compress(ppp, &data);
+                       }
+                       break;
+               }
                }
        }
        mutex_unlock(&ppp_mutex);
@@ -2783,24 +2810,20 @@ ppp_output_wakeup(struct ppp_channel *chan)
 
 /* Process the PPPIOCSCOMPRESS ioctl. */
 static int
-ppp_set_compress(struct ppp *ppp, unsigned long arg)
+ppp_set_compress(struct ppp *ppp, struct ppp_option_data *data)
 {
-       int err;
+       int err = -EFAULT;
        struct compressor *cp, *ocomp;
-       struct ppp_option_data data;
        void *state, *ostate;
        unsigned char ccp_option[CCP_MAX_OPTION_LENGTH];
 
-       err = -EFAULT;
-       if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
-               goto out;
-       if (data.length > CCP_MAX_OPTION_LENGTH)
+       if (data->length > CCP_MAX_OPTION_LENGTH)
                goto out;
-       if (copy_from_user(ccp_option, (void __user *) data.ptr, data.length))
+       if (copy_from_user(ccp_option, data->ptr, data->length))
                goto out;
 
        err = -EINVAL;
-       if (data.length < 2 || ccp_option[1] < 2 || ccp_option[1] > data.length)
+       if (data->length < 2 || ccp_option[1] < 2 || ccp_option[1] > data->length)
                goto out;
 
        cp = try_then_request_module(
@@ -2810,8 +2833,8 @@ ppp_set_compress(struct ppp *ppp, unsigned long arg)
                goto out;
 
        err = -ENOBUFS;
-       if (data.transmit) {
-               state = cp->comp_alloc(ccp_option, data.length);
+       if (data->transmit) {
+               state = cp->comp_alloc(ccp_option, data->length);
                if (state) {
                        ppp_xmit_lock(ppp);
                        ppp->xstate &= ~SC_COMP_RUN;
@@ -2829,7 +2852,7 @@ ppp_set_compress(struct ppp *ppp, unsigned long arg)
                        module_put(cp->owner);
 
        } else {
-               state = cp->decomp_alloc(ccp_option, data.length);
+               state = cp->decomp_alloc(ccp_option, data->length);
                if (state) {
                        ppp_recv_lock(ppp);
                        ppp->rstate &= ~SC_DECOMP_RUN;
index eda41b2..0b5a732 100644 (file)
@@ -99,13 +99,6 @@ static int sg_grt_trans(struct file *file,
 }
 #endif /* CONFIG_BLOCK */
 
-struct ppp_option_data32 {
-       compat_caddr_t  ptr;
-       u32                     length;
-       compat_int_t            transmit;
-};
-#define PPPIOCSCOMPRESS32      _IOW('t', 77, struct ppp_option_data32)
-
 struct ppp_idle32 {
        compat_time_t xmit_idle;
        compat_time_t recv_idle;
@@ -133,29 +126,6 @@ static int ppp_gidle(struct file *file, unsigned int cmd,
        return err;
 }
 
-static int ppp_scompress(struct file *file, unsigned int cmd,
-       struct ppp_option_data32 __user *odata32)
-{
-       struct ppp_option_data __user *odata;
-       __u32 data;
-       void __user *datap;
-
-       odata = compat_alloc_user_space(sizeof(*odata));
-
-       if (get_user(data, &odata32->ptr))
-               return -EFAULT;
-
-       datap = compat_ptr(data);
-       if (put_user(datap, &odata->ptr))
-               return -EFAULT;
-
-       if (copy_in_user(&odata->length, &odata32->length,
-                        sizeof(__u32) + sizeof(int)))
-               return -EFAULT;
-
-       return do_ioctl(file, PPPIOCSCOMPRESS, (unsigned long) odata);
-}
-
 /*
  * simple reversible transform to make our table more evenly
  * distributed after sorting.
@@ -249,8 +219,6 @@ static long do_ioctl_trans(unsigned int cmd,
        switch (cmd) {
        case PPPIOCGIDLE32:
                return ppp_gidle(file, cmd, argp);
-       case PPPIOCSCOMPRESS32:
-               return ppp_scompress(file, cmd, argp);
 #ifdef CONFIG_BLOCK
        case SG_GET_REQUEST_TABLE:
                return sg_grt_trans(file, cmd, argp);