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

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
Loading
Loading
Loading
Loading
+38 −15
Original line number Diff line number Diff line
@@ -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;
+0 −32
Original line number Diff line number Diff line
@@ -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);