Commit a7b75c5a authored by Christoph Hellwig's avatar Christoph Hellwig Committed by David S. Miller
Browse files

net: pass a sockptr_t into ->setsockopt



Rework the remaining setsockopt code to pass a sockptr_t instead of a
plain user pointer.  This removes the last remaining set_fs(KERNEL_DS)
outside of architecture specific code.

Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Acked-by: Stefan Schmidt <stefan@datenfreihafen.org> [ieee802154]
Acked-by: default avatarMatthieu Baerts <matthieu.baerts@tessares.net>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent d38d2b00
Loading
Loading
Loading
Loading
+3 −4
Original line number Diff line number Diff line
@@ -197,8 +197,7 @@ unlock:
	return err;
}

static int alg_setkey(struct sock *sk, char __user *ukey,
		      unsigned int keylen)
static int alg_setkey(struct sock *sk, sockptr_t ukey, unsigned int keylen)
{
	struct alg_sock *ask = alg_sk(sk);
	const struct af_alg_type *type = ask->type;
@@ -210,7 +209,7 @@ static int alg_setkey(struct sock *sk, char __user *ukey,
		return -ENOMEM;

	err = -EFAULT;
	if (copy_from_user(key, ukey, keylen))
	if (copy_from_sockptr(key, ukey, keylen))
		goto out;

	err = type->setkey(ask->private, key, keylen);
@@ -222,7 +221,7 @@ out:
}

static int alg_setsockopt(struct socket *sock, int level, int optname,
			  char __user *optval, unsigned int optlen)
			  sockptr_t optval, unsigned int optlen)
{
	struct sock *sk = sock->sk;
	struct alg_sock *ask = alg_sk(sk);
+10 −8
Original line number Diff line number Diff line
@@ -488,7 +488,7 @@ static int chtls_getsockopt(struct sock *sk, int level, int optname,
}

static int do_chtls_setsockopt(struct sock *sk, int optname,
			       char __user *optval, unsigned int optlen)
			       sockptr_t optval, unsigned int optlen)
{
	struct tls_crypto_info *crypto_info, tmp_crypto_info;
	struct chtls_sock *csk;
@@ -498,12 +498,12 @@ static int do_chtls_setsockopt(struct sock *sk, int optname,

	csk = rcu_dereference_sk_user_data(sk);

	if (!optval || optlen < sizeof(*crypto_info)) {
	if (sockptr_is_null(optval) || optlen < sizeof(*crypto_info)) {
		rc = -EINVAL;
		goto out;
	}

	rc = copy_from_user(&tmp_crypto_info, optval, sizeof(*crypto_info));
	rc = copy_from_sockptr(&tmp_crypto_info, optval, sizeof(*crypto_info));
	if (rc) {
		rc = -EFAULT;
		goto out;
@@ -525,8 +525,9 @@ static int do_chtls_setsockopt(struct sock *sk, int optname,
		/* Obtain version and type from previous copy */
		crypto_info[0] = tmp_crypto_info;
		/* Now copy the following data */
		rc = copy_from_user((char *)crypto_info + sizeof(*crypto_info),
				optval + sizeof(*crypto_info),
		sockptr_advance(optval, sizeof(*crypto_info));
		rc = copy_from_sockptr((char *)crypto_info + sizeof(*crypto_info),
				optval,
				sizeof(struct tls12_crypto_info_aes_gcm_128)
				- sizeof(*crypto_info));

@@ -541,8 +542,9 @@ static int do_chtls_setsockopt(struct sock *sk, int optname,
	}
	case TLS_CIPHER_AES_GCM_256: {
		crypto_info[0] = tmp_crypto_info;
		rc = copy_from_user((char *)crypto_info + sizeof(*crypto_info),
				    optval + sizeof(*crypto_info),
		sockptr_advance(optval, sizeof(*crypto_info));
		rc = copy_from_sockptr((char *)crypto_info + sizeof(*crypto_info),
				    optval,
				sizeof(struct tls12_crypto_info_aes_gcm_256)
				- sizeof(*crypto_info));

@@ -565,7 +567,7 @@ out:
}

static int chtls_setsockopt(struct sock *sk, int level, int optname,
			    char __user *optval, unsigned int optlen)
			    sockptr_t optval, unsigned int optlen)
{
	struct tls_context *ctx = tls_get_ctx(sk);

+2 −2
Original line number Diff line number Diff line
@@ -401,7 +401,7 @@ data_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
}

static int data_sock_setsockopt(struct socket *sock, int level, int optname,
				char __user *optval, unsigned int len)
				sockptr_t optval, unsigned int len)
{
	struct sock *sk = sock->sk;
	int err = 0, opt = 0;
@@ -414,7 +414,7 @@ static int data_sock_setsockopt(struct socket *sock, int level, int optname,

	switch (optname) {
	case MISDN_TIME_STAMP:
		if (get_user(opt, (int __user *)optval)) {
		if (copy_from_sockptr(&opt, optval, sizeof(int))) {
			err = -EFAULT;
			break;
		}
+3 −1
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@
#include <linux/rcupdate.h>
#include <linux/once.h>
#include <linux/fs.h>
#include <linux/sockptr.h>

#include <uapi/linux/net.h>

@@ -162,7 +163,8 @@ struct proto_ops {
	int		(*listen)    (struct socket *sock, int len);
	int		(*shutdown)  (struct socket *sock, int flags);
	int		(*setsockopt)(struct socket *sock, int level,
				      int optname, char __user *optval, unsigned int optlen);
				      int optname, sockptr_t optval,
				      unsigned int optlen);
	int		(*getsockopt)(struct socket *sock, int level,
				      int optname, char __user *optval, int __user *optlen);
	void		(*show_fdinfo)(struct seq_file *m, struct socket *sock);
+2 −1
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
#include <linux/timer.h>
#include <linux/poll.h>
#include <linux/kernel.h>
#include <linux/sockptr.h>

#include <net/inet_sock.h>
#include <net/request_sock.h>
@@ -45,7 +46,7 @@ struct inet_connection_sock_af_ops {
	u16	    net_frag_header_len;
	u16	    sockaddr_len;
	int	    (*setsockopt)(struct sock *sk, int level, int optname,
				  char __user *optval, unsigned int optlen);
				  sockptr_t optval, unsigned int optlen);
	int	    (*getsockopt)(struct sock *sk, int level, int optname,
				  char __user *optval, int __user *optlen);
	void	    (*addr2sockaddr)(struct sock *sk, struct sockaddr *);
Loading