Commit 5b6c02df authored by Al Viro's avatar Al Viro Committed by Arnd Bergmann

compat_ioctl: move PPPIOCSCOMPRESS to ppp_generic

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: default avatarAl 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: default avatarArnd Bergmann <arnd@arndb.de>
parent 3e859adf
...@@ -270,7 +270,7 @@ static void ppp_mp_insert(struct ppp *ppp, struct sk_buff *skb); ...@@ -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 struct sk_buff *ppp_mp_reconstruct(struct ppp *ppp);
static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb); static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb);
#endif /* CONFIG_PPP_MULTILINK */ #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_peek(struct ppp *ppp, struct sk_buff *skb, int inbound);
static void ppp_ccp_closed(struct ppp *ppp); static void ppp_ccp_closed(struct ppp *ppp);
static struct compressor *find_compressor(int type); static struct compressor *find_compressor(int type);
...@@ -708,9 +708,14 @@ static long ppp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) ...@@ -708,9 +708,14 @@ static long ppp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
break; break;
case PPPIOCSCOMPRESS: 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; break;
}
case PPPIOCGUNIT: case PPPIOCGUNIT:
if (put_user(ppp->file.index, p)) if (put_user(ppp->file.index, p))
break; break;
...@@ -827,6 +832,13 @@ static long ppp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) ...@@ -827,6 +832,13 @@ static long ppp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
} }
#ifdef CONFIG_COMPAT #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) static long ppp_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{ {
struct ppp_file *pf; struct ppp_file *pf;
...@@ -863,6 +875,21 @@ static long ppp_compat_ioctl(struct file *file, unsigned int cmd, unsigned long ...@@ -863,6 +875,21 @@ static long ppp_compat_ioctl(struct file *file, unsigned int cmd, unsigned long
break; break;
} }
#endif /* CONFIG_PPP_FILTER */ #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); mutex_unlock(&ppp_mutex);
...@@ -2783,24 +2810,20 @@ ppp_output_wakeup(struct ppp_channel *chan) ...@@ -2783,24 +2810,20 @@ ppp_output_wakeup(struct ppp_channel *chan)
/* Process the PPPIOCSCOMPRESS ioctl. */ /* Process the PPPIOCSCOMPRESS ioctl. */
static int 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 compressor *cp, *ocomp;
struct ppp_option_data data;
void *state, *ostate; void *state, *ostate;
unsigned char ccp_option[CCP_MAX_OPTION_LENGTH]; unsigned char ccp_option[CCP_MAX_OPTION_LENGTH];
err = -EFAULT; if (data->length > CCP_MAX_OPTION_LENGTH)
if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
goto out;
if (data.length > CCP_MAX_OPTION_LENGTH)
goto out; 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; goto out;
err = -EINVAL; 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; goto out;
cp = try_then_request_module( cp = try_then_request_module(
...@@ -2810,8 +2833,8 @@ ppp_set_compress(struct ppp *ppp, unsigned long arg) ...@@ -2810,8 +2833,8 @@ ppp_set_compress(struct ppp *ppp, unsigned long arg)
goto out; goto out;
err = -ENOBUFS; err = -ENOBUFS;
if (data.transmit) { if (data->transmit) {
state = cp->comp_alloc(ccp_option, data.length); state = cp->comp_alloc(ccp_option, data->length);
if (state) { if (state) {
ppp_xmit_lock(ppp); ppp_xmit_lock(ppp);
ppp->xstate &= ~SC_COMP_RUN; ppp->xstate &= ~SC_COMP_RUN;
...@@ -2829,7 +2852,7 @@ ppp_set_compress(struct ppp *ppp, unsigned long arg) ...@@ -2829,7 +2852,7 @@ ppp_set_compress(struct ppp *ppp, unsigned long arg)
module_put(cp->owner); module_put(cp->owner);
} else { } else {
state = cp->decomp_alloc(ccp_option, data.length); state = cp->decomp_alloc(ccp_option, data->length);
if (state) { if (state) {
ppp_recv_lock(ppp); ppp_recv_lock(ppp);
ppp->rstate &= ~SC_DECOMP_RUN; ppp->rstate &= ~SC_DECOMP_RUN;
......
...@@ -99,13 +99,6 @@ static int sg_grt_trans(struct file *file, ...@@ -99,13 +99,6 @@ static int sg_grt_trans(struct file *file,
} }
#endif /* CONFIG_BLOCK */ #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 { struct ppp_idle32 {
compat_time_t xmit_idle; compat_time_t xmit_idle;
compat_time_t recv_idle; compat_time_t recv_idle;
...@@ -133,29 +126,6 @@ static int ppp_gidle(struct file *file, unsigned int cmd, ...@@ -133,29 +126,6 @@ static int ppp_gidle(struct file *file, unsigned int cmd,
return err; 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 * simple reversible transform to make our table more evenly
* distributed after sorting. * distributed after sorting.
...@@ -249,8 +219,6 @@ static long do_ioctl_trans(unsigned int cmd, ...@@ -249,8 +219,6 @@ static long do_ioctl_trans(unsigned int cmd,
switch (cmd) { switch (cmd) {
case PPPIOCGIDLE32: case PPPIOCGIDLE32:
return ppp_gidle(file, cmd, argp); return ppp_gidle(file, cmd, argp);
case PPPIOCSCOMPRESS32:
return ppp_scompress(file, cmd, argp);
#ifdef CONFIG_BLOCK #ifdef CONFIG_BLOCK
case SG_GET_REQUEST_TABLE: case SG_GET_REQUEST_TABLE:
return sg_grt_trans(file, cmd, argp); return sg_grt_trans(file, cmd, argp);
......
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