Skip to content

Commit

Permalink
net: pass a sockptr_t into ->setsockopt
Browse files Browse the repository at this point in the history
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: Christoph Hellwig <hch@lst.de>
Acked-by: Stefan Schmidt <stefan@datenfreihafen.org> [ieee802154]
Acked-by: Matthieu Baerts <matthieu.baerts@tessares.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Christoph Hellwig authored and davem330 committed Jul 24, 2020
1 parent d38d2b0 commit a7b75c5
Show file tree
Hide file tree
Showing 61 changed files with 246 additions and 258 deletions.
7 changes: 3 additions & 4 deletions crypto/af_alg.c
Original file line number Diff line number Diff line change
Expand Up @@ -197,8 +197,7 @@ static int alg_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
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;
Expand All @@ -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);
Expand All @@ -222,7 +221,7 @@ static int alg_setkey(struct sock *sk, char __user *ukey,
}

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);
Expand Down
18 changes: 10 additions & 8 deletions drivers/crypto/chelsio/chtls/chtls_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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));

Expand All @@ -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));

Expand All @@ -565,7 +567,7 @@ static int do_chtls_setsockopt(struct sock *sk, int optname,
}

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);

Expand Down
4 changes: 2 additions & 2 deletions drivers/isdn/mISDN/socket.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
}
Expand Down
4 changes: 3 additions & 1 deletion include/linux/net.h
Original file line number Diff line number Diff line change
Expand Up @@ -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>

Expand Down Expand Up @@ -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);
Expand Down
3 changes: 2 additions & 1 deletion include/net/inet_connection_sock.h
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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 *);
Expand Down
2 changes: 1 addition & 1 deletion include/net/ip.h
Original file line number Diff line number Diff line change
Expand Up @@ -722,7 +722,7 @@ void ip_cmsg_recv_offset(struct msghdr *msg, struct sock *sk,
struct sk_buff *skb, int tlen, int offset);
int ip_cmsg_send(struct sock *sk, struct msghdr *msg,
struct ipcm_cookie *ipc, bool allow_ipv6);
int ip_setsockopt(struct sock *sk, int level, int optname, char __user *optval,
int ip_setsockopt(struct sock *sk, int level, int optname, sockptr_t optval,
unsigned int optlen);
int ip_getsockopt(struct sock *sk, int level, int optname, char __user *optval,
int __user *optlen);
Expand Down
4 changes: 2 additions & 2 deletions include/net/ipv6.h
Original file line number Diff line number Diff line change
Expand Up @@ -1084,8 +1084,8 @@ struct in6_addr *fl6_update_dst(struct flowi6 *fl6,
* socket options (ipv6_sockglue.c)
*/

int ipv6_setsockopt(struct sock *sk, int level, int optname,
char __user *optval, unsigned int optlen);
int ipv6_setsockopt(struct sock *sk, int level, int optname, sockptr_t optval,
unsigned int optlen);
int ipv6_getsockopt(struct sock *sk, int level, int optname,
char __user *optval, int __user *optlen);

Expand Down
2 changes: 1 addition & 1 deletion include/net/sctp/structs.h
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,7 @@ struct sctp_af {
int (*setsockopt) (struct sock *sk,
int level,
int optname,
char __user *optval,
sockptr_t optval,
unsigned int optlen);
int (*getsockopt) (struct sock *sk,
int level,
Expand Down
4 changes: 2 additions & 2 deletions include/net/sock.h
Original file line number Diff line number Diff line change
Expand Up @@ -1141,7 +1141,7 @@ struct proto {
void (*destroy)(struct sock *sk);
void (*shutdown)(struct sock *sk, int how);
int (*setsockopt)(struct sock *sk, int level,
int optname, char __user *optval,
int optname, sockptr_t optval,
unsigned int optlen);
int (*getsockopt)(struct sock *sk, int level,
int optname, char __user *optval,
Expand Down Expand Up @@ -1734,7 +1734,7 @@ int sock_common_getsockopt(struct socket *sock, int level, int optname,
int sock_common_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
int flags);
int sock_common_setsockopt(struct socket *sock, int level, int optname,
char __user *optval, unsigned int optlen);
sockptr_t optval, unsigned int optlen);

void sk_common_release(struct sock *sk);

Expand Down
4 changes: 2 additions & 2 deletions include/net/tcp.h
Original file line number Diff line number Diff line change
Expand Up @@ -399,8 +399,8 @@ __poll_t tcp_poll(struct file *file, struct socket *sock,
struct poll_table_struct *wait);
int tcp_getsockopt(struct sock *sk, int level, int optname,
char __user *optval, int __user *optlen);
int tcp_setsockopt(struct sock *sk, int level, int optname,
char __user *optval, unsigned int optlen);
int tcp_setsockopt(struct sock *sk, int level, int optname, sockptr_t optval,
unsigned int optlen);
void tcp_set_keepalive(struct sock *sk, int val);
void tcp_syn_ack_timeout(const struct request_sock *req);
int tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int nonblock,
Expand Down
6 changes: 3 additions & 3 deletions net/atm/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -745,7 +745,7 @@ static int check_qos(const struct atm_qos *qos)
}

int vcc_setsockopt(struct socket *sock, int level, int optname,
char __user *optval, unsigned int optlen)
sockptr_t optval, unsigned int optlen)
{
struct atm_vcc *vcc;
unsigned long value;
Expand All @@ -760,7 +760,7 @@ int vcc_setsockopt(struct socket *sock, int level, int optname,
{
struct atm_qos qos;

if (copy_from_user(&qos, optval, sizeof(qos)))
if (copy_from_sockptr(&qos, optval, sizeof(qos)))
return -EFAULT;
error = check_qos(&qos);
if (error)
Expand All @@ -774,7 +774,7 @@ int vcc_setsockopt(struct socket *sock, int level, int optname,
return 0;
}
case SO_SETCLP:
if (get_user(value, (unsigned long __user *)optval))
if (copy_from_sockptr(&value, optval, sizeof(value)))
return -EFAULT;
if (value)
vcc->atm_options |= ATM_ATMOPT_CLP;
Expand Down
2 changes: 1 addition & 1 deletion net/atm/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ __poll_t vcc_poll(struct file *file, struct socket *sock, poll_table *wait);
int vcc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);
int vcc_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);
int vcc_setsockopt(struct socket *sock, int level, int optname,
char __user *optval, unsigned int optlen);
sockptr_t optval, unsigned int optlen);
int vcc_getsockopt(struct socket *sock, int level, int optname,
char __user *optval, int __user *optlen);
void vcc_process_recv_queue(struct atm_vcc *vcc);
Expand Down
2 changes: 1 addition & 1 deletion net/atm/pvc.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ static int pvc_connect(struct socket *sock, struct sockaddr *sockaddr,
}

static int pvc_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;
int error;
Expand Down
6 changes: 3 additions & 3 deletions net/atm/svc.c
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,7 @@ int svc_change_qos(struct atm_vcc *vcc, struct atm_qos *qos)
}

static int svc_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 atm_vcc *vcc = ATM_SD(sock);
Expand All @@ -464,7 +464,7 @@ static int svc_setsockopt(struct socket *sock, int level, int optname,
error = -EINVAL;
goto out;
}
if (copy_from_user(&vcc->sap, optval, optlen)) {
if (copy_from_sockptr(&vcc->sap, optval, optlen)) {
error = -EFAULT;
goto out;
}
Expand All @@ -475,7 +475,7 @@ static int svc_setsockopt(struct socket *sock, int level, int optname,
error = -EINVAL;
goto out;
}
if (get_user(value, (int __user *)optval)) {
if (copy_from_sockptr(&value, optval, sizeof(int))) {
error = -EFAULT;
goto out;
}
Expand Down
6 changes: 3 additions & 3 deletions net/ax25/af_ax25.c
Original file line number Diff line number Diff line change
Expand Up @@ -528,7 +528,7 @@ ax25_cb *ax25_create_cb(void)
*/

static int ax25_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;
ax25_cb *ax25;
Expand All @@ -543,7 +543,7 @@ static int ax25_setsockopt(struct socket *sock, int level, int optname,
if (optlen < sizeof(unsigned int))
return -EINVAL;

if (get_user(opt, (unsigned int __user *)optval))
if (copy_from_sockptr(&opt, optval, sizeof(unsigned int)))
return -EFAULT;

lock_sock(sk);
Expand Down Expand Up @@ -640,7 +640,7 @@ static int ax25_setsockopt(struct socket *sock, int level, int optname,

memset(devname, 0, sizeof(devname));

if (copy_from_user(devname, optval, optlen)) {
if (copy_from_sockptr(devname, optval, optlen)) {
res = -EFAULT;
break;
}
Expand Down
8 changes: 4 additions & 4 deletions net/bluetooth/hci_sock.c
Original file line number Diff line number Diff line change
Expand Up @@ -1842,7 +1842,7 @@ static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg,
}

static int hci_sock_setsockopt(struct socket *sock, int level, int optname,
char __user *optval, unsigned int len)
sockptr_t optval, unsigned int len)
{
struct hci_ufilter uf = { .opcode = 0 };
struct sock *sk = sock->sk;
Expand All @@ -1862,7 +1862,7 @@ static int hci_sock_setsockopt(struct socket *sock, int level, int optname,

switch (optname) {
case HCI_DATA_DIR:
if (get_user(opt, (int __user *)optval)) {
if (copy_from_sockptr(&opt, optval, sizeof(opt))) {
err = -EFAULT;
break;
}
Expand All @@ -1874,7 +1874,7 @@ static int hci_sock_setsockopt(struct socket *sock, int level, int optname,
break;

case HCI_TIME_STAMP:
if (get_user(opt, (int __user *)optval)) {
if (copy_from_sockptr(&opt, optval, sizeof(opt))) {
err = -EFAULT;
break;
}
Expand All @@ -1896,7 +1896,7 @@ static int hci_sock_setsockopt(struct socket *sock, int level, int optname,
}

len = min_t(unsigned int, len, sizeof(uf));
if (copy_from_user(&uf, optval, len)) {
if (copy_from_sockptr(&uf, optval, len)) {
err = -EFAULT;
break;
}
Expand Down

0 comments on commit a7b75c5

Please sign in to comment.