mirror of
https://github.com/Fishwaldo/linux-bl808.git
synced 2025-06-17 20:25:19 +00:00
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: 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>
This commit is contained in:
parent
d38d2b00ba
commit
a7b75c5a8c
61 changed files with 246 additions and 258 deletions
crypto
drivers
include
net
atm
ax25
bluetooth
caif
can
core
dccp
decnet
ieee802154
ipv4
ipv6
iucv
kcm
l2tp
llc
mptcp
netlink
netrom
nfc
packet
phonet
rds
rose
rxrpc
sctp
smc
socket.ctipc
tls
vmw_vsock
x25
xdp
|
@ -197,8 +197,7 @@ unlock:
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int alg_setkey(struct sock *sk, char __user *ukey,
|
static int alg_setkey(struct sock *sk, sockptr_t ukey, unsigned int keylen)
|
||||||
unsigned int keylen)
|
|
||||||
{
|
{
|
||||||
struct alg_sock *ask = alg_sk(sk);
|
struct alg_sock *ask = alg_sk(sk);
|
||||||
const struct af_alg_type *type = ask->type;
|
const struct af_alg_type *type = ask->type;
|
||||||
|
@ -210,7 +209,7 @@ static int alg_setkey(struct sock *sk, char __user *ukey,
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
err = -EFAULT;
|
err = -EFAULT;
|
||||||
if (copy_from_user(key, ukey, keylen))
|
if (copy_from_sockptr(key, ukey, keylen))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
err = type->setkey(ask->private, key, keylen);
|
err = type->setkey(ask->private, key, keylen);
|
||||||
|
@ -222,7 +221,7 @@ out:
|
||||||
}
|
}
|
||||||
|
|
||||||
static int alg_setsockopt(struct socket *sock, int level, int optname,
|
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 sock *sk = sock->sk;
|
||||||
struct alg_sock *ask = alg_sk(sk);
|
struct alg_sock *ask = alg_sk(sk);
|
||||||
|
|
|
@ -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,
|
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 tls_crypto_info *crypto_info, tmp_crypto_info;
|
||||||
struct chtls_sock *csk;
|
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);
|
csk = rcu_dereference_sk_user_data(sk);
|
||||||
|
|
||||||
if (!optval || optlen < sizeof(*crypto_info)) {
|
if (sockptr_is_null(optval) || optlen < sizeof(*crypto_info)) {
|
||||||
rc = -EINVAL;
|
rc = -EINVAL;
|
||||||
goto out;
|
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) {
|
if (rc) {
|
||||||
rc = -EFAULT;
|
rc = -EFAULT;
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -525,8 +525,9 @@ static int do_chtls_setsockopt(struct sock *sk, int optname,
|
||||||
/* Obtain version and type from previous copy */
|
/* Obtain version and type from previous copy */
|
||||||
crypto_info[0] = tmp_crypto_info;
|
crypto_info[0] = tmp_crypto_info;
|
||||||
/* Now copy the following data */
|
/* Now copy the following data */
|
||||||
rc = copy_from_user((char *)crypto_info + sizeof(*crypto_info),
|
sockptr_advance(optval, sizeof(*crypto_info));
|
||||||
optval + sizeof(*crypto_info),
|
rc = copy_from_sockptr((char *)crypto_info + sizeof(*crypto_info),
|
||||||
|
optval,
|
||||||
sizeof(struct tls12_crypto_info_aes_gcm_128)
|
sizeof(struct tls12_crypto_info_aes_gcm_128)
|
||||||
- sizeof(*crypto_info));
|
- sizeof(*crypto_info));
|
||||||
|
|
||||||
|
@ -541,8 +542,9 @@ static int do_chtls_setsockopt(struct sock *sk, int optname,
|
||||||
}
|
}
|
||||||
case TLS_CIPHER_AES_GCM_256: {
|
case TLS_CIPHER_AES_GCM_256: {
|
||||||
crypto_info[0] = tmp_crypto_info;
|
crypto_info[0] = tmp_crypto_info;
|
||||||
rc = copy_from_user((char *)crypto_info + sizeof(*crypto_info),
|
sockptr_advance(optval, sizeof(*crypto_info));
|
||||||
optval + sizeof(*crypto_info),
|
rc = copy_from_sockptr((char *)crypto_info + sizeof(*crypto_info),
|
||||||
|
optval,
|
||||||
sizeof(struct tls12_crypto_info_aes_gcm_256)
|
sizeof(struct tls12_crypto_info_aes_gcm_256)
|
||||||
- sizeof(*crypto_info));
|
- sizeof(*crypto_info));
|
||||||
|
|
||||||
|
@ -565,7 +567,7 @@ out:
|
||||||
}
|
}
|
||||||
|
|
||||||
static int chtls_setsockopt(struct sock *sk, int level, 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);
|
struct tls_context *ctx = tls_get_ctx(sk);
|
||||||
|
|
||||||
|
|
|
@ -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,
|
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;
|
struct sock *sk = sock->sk;
|
||||||
int err = 0, opt = 0;
|
int err = 0, opt = 0;
|
||||||
|
@ -414,7 +414,7 @@ static int data_sock_setsockopt(struct socket *sock, int level, int optname,
|
||||||
|
|
||||||
switch (optname) {
|
switch (optname) {
|
||||||
case MISDN_TIME_STAMP:
|
case MISDN_TIME_STAMP:
|
||||||
if (get_user(opt, (int __user *)optval)) {
|
if (copy_from_sockptr(&opt, optval, sizeof(int))) {
|
||||||
err = -EFAULT;
|
err = -EFAULT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include <linux/rcupdate.h>
|
#include <linux/rcupdate.h>
|
||||||
#include <linux/once.h>
|
#include <linux/once.h>
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
|
#include <linux/sockptr.h>
|
||||||
|
|
||||||
#include <uapi/linux/net.h>
|
#include <uapi/linux/net.h>
|
||||||
|
|
||||||
|
@ -162,7 +163,8 @@ struct proto_ops {
|
||||||
int (*listen) (struct socket *sock, int len);
|
int (*listen) (struct socket *sock, int len);
|
||||||
int (*shutdown) (struct socket *sock, int flags);
|
int (*shutdown) (struct socket *sock, int flags);
|
||||||
int (*setsockopt)(struct socket *sock, int level,
|
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 (*getsockopt)(struct socket *sock, int level,
|
||||||
int optname, char __user *optval, int __user *optlen);
|
int optname, char __user *optval, int __user *optlen);
|
||||||
void (*show_fdinfo)(struct seq_file *m, struct socket *sock);
|
void (*show_fdinfo)(struct seq_file *m, struct socket *sock);
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include <linux/timer.h>
|
#include <linux/timer.h>
|
||||||
#include <linux/poll.h>
|
#include <linux/poll.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/sockptr.h>
|
||||||
|
|
||||||
#include <net/inet_sock.h>
|
#include <net/inet_sock.h>
|
||||||
#include <net/request_sock.h>
|
#include <net/request_sock.h>
|
||||||
|
@ -45,7 +46,7 @@ struct inet_connection_sock_af_ops {
|
||||||
u16 net_frag_header_len;
|
u16 net_frag_header_len;
|
||||||
u16 sockaddr_len;
|
u16 sockaddr_len;
|
||||||
int (*setsockopt)(struct sock *sk, int level, int optname,
|
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,
|
int (*getsockopt)(struct sock *sk, int level, int optname,
|
||||||
char __user *optval, int __user *optlen);
|
char __user *optval, int __user *optlen);
|
||||||
void (*addr2sockaddr)(struct sock *sk, struct sockaddr *);
|
void (*addr2sockaddr)(struct sock *sk, struct sockaddr *);
|
||||||
|
|
|
@ -722,7 +722,7 @@ void ip_cmsg_recv_offset(struct msghdr *msg, struct sock *sk,
|
||||||
struct sk_buff *skb, int tlen, int offset);
|
struct sk_buff *skb, int tlen, int offset);
|
||||||
int ip_cmsg_send(struct sock *sk, struct msghdr *msg,
|
int ip_cmsg_send(struct sock *sk, struct msghdr *msg,
|
||||||
struct ipcm_cookie *ipc, bool allow_ipv6);
|
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);
|
unsigned int optlen);
|
||||||
int ip_getsockopt(struct sock *sk, int level, int optname, char __user *optval,
|
int ip_getsockopt(struct sock *sk, int level, int optname, char __user *optval,
|
||||||
int __user *optlen);
|
int __user *optlen);
|
||||||
|
|
|
@ -1084,8 +1084,8 @@ struct in6_addr *fl6_update_dst(struct flowi6 *fl6,
|
||||||
* socket options (ipv6_sockglue.c)
|
* socket options (ipv6_sockglue.c)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int ipv6_setsockopt(struct sock *sk, int level, int optname,
|
int ipv6_setsockopt(struct sock *sk, int level, int optname, sockptr_t optval,
|
||||||
char __user *optval, unsigned int optlen);
|
unsigned int optlen);
|
||||||
int ipv6_getsockopt(struct sock *sk, int level, int optname,
|
int ipv6_getsockopt(struct sock *sk, int level, int optname,
|
||||||
char __user *optval, int __user *optlen);
|
char __user *optval, int __user *optlen);
|
||||||
|
|
||||||
|
|
|
@ -431,7 +431,7 @@ struct sctp_af {
|
||||||
int (*setsockopt) (struct sock *sk,
|
int (*setsockopt) (struct sock *sk,
|
||||||
int level,
|
int level,
|
||||||
int optname,
|
int optname,
|
||||||
char __user *optval,
|
sockptr_t optval,
|
||||||
unsigned int optlen);
|
unsigned int optlen);
|
||||||
int (*getsockopt) (struct sock *sk,
|
int (*getsockopt) (struct sock *sk,
|
||||||
int level,
|
int level,
|
||||||
|
|
|
@ -1141,7 +1141,7 @@ struct proto {
|
||||||
void (*destroy)(struct sock *sk);
|
void (*destroy)(struct sock *sk);
|
||||||
void (*shutdown)(struct sock *sk, int how);
|
void (*shutdown)(struct sock *sk, int how);
|
||||||
int (*setsockopt)(struct sock *sk, int level,
|
int (*setsockopt)(struct sock *sk, int level,
|
||||||
int optname, char __user *optval,
|
int optname, sockptr_t optval,
|
||||||
unsigned int optlen);
|
unsigned int optlen);
|
||||||
int (*getsockopt)(struct sock *sk, int level,
|
int (*getsockopt)(struct sock *sk, int level,
|
||||||
int optname, char __user *optval,
|
int optname, char __user *optval,
|
||||||
|
@ -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 sock_common_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
|
||||||
int flags);
|
int flags);
|
||||||
int sock_common_setsockopt(struct socket *sock, int level, int optname,
|
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);
|
void sk_common_release(struct sock *sk);
|
||||||
|
|
||||||
|
|
|
@ -399,8 +399,8 @@ __poll_t tcp_poll(struct file *file, struct socket *sock,
|
||||||
struct poll_table_struct *wait);
|
struct poll_table_struct *wait);
|
||||||
int tcp_getsockopt(struct sock *sk, int level, int optname,
|
int tcp_getsockopt(struct sock *sk, int level, int optname,
|
||||||
char __user *optval, int __user *optlen);
|
char __user *optval, int __user *optlen);
|
||||||
int tcp_setsockopt(struct sock *sk, int level, int optname,
|
int tcp_setsockopt(struct sock *sk, int level, int optname, sockptr_t optval,
|
||||||
char __user *optval, unsigned int optlen);
|
unsigned int optlen);
|
||||||
void tcp_set_keepalive(struct sock *sk, int val);
|
void tcp_set_keepalive(struct sock *sk, int val);
|
||||||
void tcp_syn_ack_timeout(const struct request_sock *req);
|
void tcp_syn_ack_timeout(const struct request_sock *req);
|
||||||
int tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int nonblock,
|
int tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int nonblock,
|
||||||
|
|
|
@ -745,7 +745,7 @@ static int check_qos(const struct atm_qos *qos)
|
||||||
}
|
}
|
||||||
|
|
||||||
int vcc_setsockopt(struct socket *sock, int level, int optname,
|
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;
|
struct atm_vcc *vcc;
|
||||||
unsigned long value;
|
unsigned long value;
|
||||||
|
@ -760,7 +760,7 @@ int vcc_setsockopt(struct socket *sock, int level, int optname,
|
||||||
{
|
{
|
||||||
struct atm_qos qos;
|
struct atm_qos qos;
|
||||||
|
|
||||||
if (copy_from_user(&qos, optval, sizeof(qos)))
|
if (copy_from_sockptr(&qos, optval, sizeof(qos)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
error = check_qos(&qos);
|
error = check_qos(&qos);
|
||||||
if (error)
|
if (error)
|
||||||
|
@ -774,7 +774,7 @@ int vcc_setsockopt(struct socket *sock, int level, int optname,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
case SO_SETCLP:
|
case SO_SETCLP:
|
||||||
if (get_user(value, (unsigned long __user *)optval))
|
if (copy_from_sockptr(&value, optval, sizeof(value)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
if (value)
|
if (value)
|
||||||
vcc->atm_options |= ATM_ATMOPT_CLP;
|
vcc->atm_options |= ATM_ATMOPT_CLP;
|
||||||
|
|
|
@ -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_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_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);
|
||||||
int vcc_setsockopt(struct socket *sock, int level, int optname,
|
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,
|
int vcc_getsockopt(struct socket *sock, int level, int optname,
|
||||||
char __user *optval, int __user *optlen);
|
char __user *optval, int __user *optlen);
|
||||||
void vcc_process_recv_queue(struct atm_vcc *vcc);
|
void vcc_process_recv_queue(struct atm_vcc *vcc);
|
||||||
|
|
|
@ -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,
|
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;
|
struct sock *sk = sock->sk;
|
||||||
int error;
|
int error;
|
||||||
|
|
|
@ -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,
|
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 sock *sk = sock->sk;
|
||||||
struct atm_vcc *vcc = ATM_SD(sock);
|
struct atm_vcc *vcc = ATM_SD(sock);
|
||||||
|
@ -464,7 +464,7 @@ static int svc_setsockopt(struct socket *sock, int level, int optname,
|
||||||
error = -EINVAL;
|
error = -EINVAL;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (copy_from_user(&vcc->sap, optval, optlen)) {
|
if (copy_from_sockptr(&vcc->sap, optval, optlen)) {
|
||||||
error = -EFAULT;
|
error = -EFAULT;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -475,7 +475,7 @@ static int svc_setsockopt(struct socket *sock, int level, int optname,
|
||||||
error = -EINVAL;
|
error = -EINVAL;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (get_user(value, (int __user *)optval)) {
|
if (copy_from_sockptr(&value, optval, sizeof(int))) {
|
||||||
error = -EFAULT;
|
error = -EFAULT;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
|
@ -528,7 +528,7 @@ ax25_cb *ax25_create_cb(void)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int ax25_setsockopt(struct socket *sock, int level, int optname,
|
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;
|
struct sock *sk = sock->sk;
|
||||||
ax25_cb *ax25;
|
ax25_cb *ax25;
|
||||||
|
@ -543,7 +543,7 @@ static int ax25_setsockopt(struct socket *sock, int level, int optname,
|
||||||
if (optlen < sizeof(unsigned int))
|
if (optlen < sizeof(unsigned int))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (get_user(opt, (unsigned int __user *)optval))
|
if (copy_from_sockptr(&opt, optval, sizeof(unsigned int)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
lock_sock(sk);
|
lock_sock(sk);
|
||||||
|
@ -640,7 +640,7 @@ static int ax25_setsockopt(struct socket *sock, int level, int optname,
|
||||||
|
|
||||||
memset(devname, 0, sizeof(devname));
|
memset(devname, 0, sizeof(devname));
|
||||||
|
|
||||||
if (copy_from_user(devname, optval, optlen)) {
|
if (copy_from_sockptr(devname, optval, optlen)) {
|
||||||
res = -EFAULT;
|
res = -EFAULT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1842,7 +1842,7 @@ drop:
|
||||||
}
|
}
|
||||||
|
|
||||||
static int hci_sock_setsockopt(struct socket *sock, int level, int optname,
|
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 hci_ufilter uf = { .opcode = 0 };
|
||||||
struct sock *sk = sock->sk;
|
struct sock *sk = sock->sk;
|
||||||
|
@ -1862,7 +1862,7 @@ static int hci_sock_setsockopt(struct socket *sock, int level, int optname,
|
||||||
|
|
||||||
switch (optname) {
|
switch (optname) {
|
||||||
case HCI_DATA_DIR:
|
case HCI_DATA_DIR:
|
||||||
if (get_user(opt, (int __user *)optval)) {
|
if (copy_from_sockptr(&opt, optval, sizeof(opt))) {
|
||||||
err = -EFAULT;
|
err = -EFAULT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1874,7 +1874,7 @@ static int hci_sock_setsockopt(struct socket *sock, int level, int optname,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HCI_TIME_STAMP:
|
case HCI_TIME_STAMP:
|
||||||
if (get_user(opt, (int __user *)optval)) {
|
if (copy_from_sockptr(&opt, optval, sizeof(opt))) {
|
||||||
err = -EFAULT;
|
err = -EFAULT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1896,7 +1896,7 @@ static int hci_sock_setsockopt(struct socket *sock, int level, int optname,
|
||||||
}
|
}
|
||||||
|
|
||||||
len = min_t(unsigned int, len, sizeof(uf));
|
len = min_t(unsigned int, len, sizeof(uf));
|
||||||
if (copy_from_user(&uf, optval, len)) {
|
if (copy_from_sockptr(&uf, optval, len)) {
|
||||||
err = -EFAULT;
|
err = -EFAULT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -703,7 +703,7 @@ static bool l2cap_valid_mtu(struct l2cap_chan *chan, u16 mtu)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int l2cap_sock_setsockopt_old(struct socket *sock, int optname,
|
static int l2cap_sock_setsockopt_old(struct socket *sock, int optname,
|
||||||
char __user *optval, unsigned int optlen)
|
sockptr_t optval, unsigned int optlen)
|
||||||
{
|
{
|
||||||
struct sock *sk = sock->sk;
|
struct sock *sk = sock->sk;
|
||||||
struct l2cap_chan *chan = l2cap_pi(sk)->chan;
|
struct l2cap_chan *chan = l2cap_pi(sk)->chan;
|
||||||
|
@ -736,7 +736,7 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname,
|
||||||
opts.txwin_size = chan->tx_win;
|
opts.txwin_size = chan->tx_win;
|
||||||
|
|
||||||
len = min_t(unsigned int, sizeof(opts), optlen);
|
len = min_t(unsigned int, sizeof(opts), optlen);
|
||||||
if (copy_from_user((char *) &opts, optval, len)) {
|
if (copy_from_sockptr(&opts, optval, len)) {
|
||||||
err = -EFAULT;
|
err = -EFAULT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -782,7 +782,7 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case L2CAP_LM:
|
case L2CAP_LM:
|
||||||
if (get_user(opt, (u32 __user *) optval)) {
|
if (copy_from_sockptr(&opt, optval, sizeof(u32))) {
|
||||||
err = -EFAULT;
|
err = -EFAULT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -859,7 +859,7 @@ static int l2cap_set_mode(struct l2cap_chan *chan, u8 mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
|
static int l2cap_sock_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 sock *sk = sock->sk;
|
||||||
struct l2cap_chan *chan = l2cap_pi(sk)->chan;
|
struct l2cap_chan *chan = l2cap_pi(sk)->chan;
|
||||||
|
@ -891,7 +891,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
|
||||||
sec.level = BT_SECURITY_LOW;
|
sec.level = BT_SECURITY_LOW;
|
||||||
|
|
||||||
len = min_t(unsigned int, sizeof(sec), optlen);
|
len = min_t(unsigned int, sizeof(sec), optlen);
|
||||||
if (copy_from_user((char *) &sec, optval, len)) {
|
if (copy_from_sockptr(&sec, optval, len)) {
|
||||||
err = -EFAULT;
|
err = -EFAULT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -939,7 +939,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (get_user(opt, (u32 __user *) optval)) {
|
if (copy_from_sockptr(&opt, optval, sizeof(u32))) {
|
||||||
err = -EFAULT;
|
err = -EFAULT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -954,7 +954,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BT_FLUSHABLE:
|
case BT_FLUSHABLE:
|
||||||
if (get_user(opt, (u32 __user *) optval)) {
|
if (copy_from_sockptr(&opt, optval, sizeof(u32))) {
|
||||||
err = -EFAULT;
|
err = -EFAULT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -990,7 +990,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
|
||||||
pwr.force_active = BT_POWER_FORCE_ACTIVE_ON;
|
pwr.force_active = BT_POWER_FORCE_ACTIVE_ON;
|
||||||
|
|
||||||
len = min_t(unsigned int, sizeof(pwr), optlen);
|
len = min_t(unsigned int, sizeof(pwr), optlen);
|
||||||
if (copy_from_user((char *) &pwr, optval, len)) {
|
if (copy_from_sockptr(&pwr, optval, len)) {
|
||||||
err = -EFAULT;
|
err = -EFAULT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1002,7 +1002,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BT_CHANNEL_POLICY:
|
case BT_CHANNEL_POLICY:
|
||||||
if (get_user(opt, (u32 __user *) optval)) {
|
if (copy_from_sockptr(&opt, optval, sizeof(u32))) {
|
||||||
err = -EFAULT;
|
err = -EFAULT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1050,7 +1050,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (get_user(opt, (u16 __user *) optval)) {
|
if (copy_from_sockptr(&opt, optval, sizeof(u16))) {
|
||||||
err = -EFAULT;
|
err = -EFAULT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1081,7 +1081,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (get_user(opt, (u8 __user *) optval)) {
|
if (copy_from_sockptr(&opt, optval, sizeof(u8))) {
|
||||||
err = -EFAULT;
|
err = -EFAULT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -644,7 +644,8 @@ static int rfcomm_sock_recvmsg(struct socket *sock, struct msghdr *msg,
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rfcomm_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen)
|
static int rfcomm_sock_setsockopt_old(struct socket *sock, int optname,
|
||||||
|
sockptr_t optval, unsigned int optlen)
|
||||||
{
|
{
|
||||||
struct sock *sk = sock->sk;
|
struct sock *sk = sock->sk;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
@ -656,7 +657,7 @@ static int rfcomm_sock_setsockopt_old(struct socket *sock, int optname, char __u
|
||||||
|
|
||||||
switch (optname) {
|
switch (optname) {
|
||||||
case RFCOMM_LM:
|
case RFCOMM_LM:
|
||||||
if (get_user(opt, (u32 __user *) optval)) {
|
if (copy_from_sockptr(&opt, optval, sizeof(u32))) {
|
||||||
err = -EFAULT;
|
err = -EFAULT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -685,7 +686,8 @@ static int rfcomm_sock_setsockopt_old(struct socket *sock, int optname, char __u
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
|
static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname,
|
||||||
|
sockptr_t optval, unsigned int optlen)
|
||||||
{
|
{
|
||||||
struct sock *sk = sock->sk;
|
struct sock *sk = sock->sk;
|
||||||
struct bt_security sec;
|
struct bt_security sec;
|
||||||
|
@ -713,7 +715,7 @@ static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, c
|
||||||
sec.level = BT_SECURITY_LOW;
|
sec.level = BT_SECURITY_LOW;
|
||||||
|
|
||||||
len = min_t(unsigned int, sizeof(sec), optlen);
|
len = min_t(unsigned int, sizeof(sec), optlen);
|
||||||
if (copy_from_user((char *) &sec, optval, len)) {
|
if (copy_from_sockptr(&sec, optval, len)) {
|
||||||
err = -EFAULT;
|
err = -EFAULT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -732,7 +734,7 @@ static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, c
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (get_user(opt, (u32 __user *) optval)) {
|
if (copy_from_sockptr(&opt, optval, sizeof(u32))) {
|
||||||
err = -EFAULT;
|
err = -EFAULT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -791,7 +791,7 @@ static int sco_sock_recvmsg(struct socket *sock, struct msghdr *msg,
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sco_sock_setsockopt(struct socket *sock, int level, int optname,
|
static int sco_sock_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 sock *sk = sock->sk;
|
||||||
int len, err = 0;
|
int len, err = 0;
|
||||||
|
@ -810,7 +810,7 @@ static int sco_sock_setsockopt(struct socket *sock, int level, int optname,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (get_user(opt, (u32 __user *) optval)) {
|
if (copy_from_sockptr(&opt, optval, sizeof(u32))) {
|
||||||
err = -EFAULT;
|
err = -EFAULT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -831,7 +831,7 @@ static int sco_sock_setsockopt(struct socket *sock, int level, int optname,
|
||||||
voice.setting = sco_pi(sk)->setting;
|
voice.setting = sco_pi(sk)->setting;
|
||||||
|
|
||||||
len = min_t(unsigned int, sizeof(voice), optlen);
|
len = min_t(unsigned int, sizeof(voice), optlen);
|
||||||
if (copy_from_user((char *)&voice, optval, len)) {
|
if (copy_from_sockptr(&voice, optval, len)) {
|
||||||
err = -EFAULT;
|
err = -EFAULT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -669,8 +669,8 @@ out_err:
|
||||||
return sent ? : err;
|
return sent ? : err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int setsockopt(struct socket *sock,
|
static int setsockopt(struct socket *sock, int lvl, int opt, sockptr_t ov,
|
||||||
int lvl, int opt, char __user *ov, unsigned int ol)
|
unsigned int ol)
|
||||||
{
|
{
|
||||||
struct sock *sk = sock->sk;
|
struct sock *sk = sock->sk;
|
||||||
struct caifsock *cf_sk = container_of(sk, struct caifsock, sk);
|
struct caifsock *cf_sk = container_of(sk, struct caifsock, sk);
|
||||||
|
@ -685,7 +685,7 @@ static int setsockopt(struct socket *sock,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (lvl != SOL_CAIF)
|
if (lvl != SOL_CAIF)
|
||||||
goto bad_sol;
|
goto bad_sol;
|
||||||
if (copy_from_user(&linksel, ov, sizeof(int)))
|
if (copy_from_sockptr(&linksel, ov, sizeof(int)))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
lock_sock(&(cf_sk->sk));
|
lock_sock(&(cf_sk->sk));
|
||||||
cf_sk->conn_req.link_selector = linksel;
|
cf_sk->conn_req.link_selector = linksel;
|
||||||
|
@ -699,7 +699,7 @@ static int setsockopt(struct socket *sock,
|
||||||
return -ENOPROTOOPT;
|
return -ENOPROTOOPT;
|
||||||
lock_sock(&(cf_sk->sk));
|
lock_sock(&(cf_sk->sk));
|
||||||
if (ol > sizeof(cf_sk->conn_req.param.data) ||
|
if (ol > sizeof(cf_sk->conn_req.param.data) ||
|
||||||
copy_from_user(&cf_sk->conn_req.param.data, ov, ol)) {
|
copy_from_sockptr(&cf_sk->conn_req.param.data, ov, ol)) {
|
||||||
release_sock(&cf_sk->sk);
|
release_sock(&cf_sk->sk);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -627,14 +627,14 @@ static int j1939_sk_release(struct socket *sock)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int j1939_sk_setsockopt_flag(struct j1939_sock *jsk, char __user *optval,
|
static int j1939_sk_setsockopt_flag(struct j1939_sock *jsk, sockptr_t optval,
|
||||||
unsigned int optlen, int flag)
|
unsigned int optlen, int flag)
|
||||||
{
|
{
|
||||||
int tmp;
|
int tmp;
|
||||||
|
|
||||||
if (optlen != sizeof(tmp))
|
if (optlen != sizeof(tmp))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (copy_from_user(&tmp, optval, optlen))
|
if (copy_from_sockptr(&tmp, optval, optlen))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
lock_sock(&jsk->sk);
|
lock_sock(&jsk->sk);
|
||||||
if (tmp)
|
if (tmp)
|
||||||
|
@ -646,7 +646,7 @@ static int j1939_sk_setsockopt_flag(struct j1939_sock *jsk, char __user *optval,
|
||||||
}
|
}
|
||||||
|
|
||||||
static int j1939_sk_setsockopt(struct socket *sock, int level, int optname,
|
static int j1939_sk_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 sock *sk = sock->sk;
|
||||||
struct j1939_sock *jsk = j1939_sk(sk);
|
struct j1939_sock *jsk = j1939_sk(sk);
|
||||||
|
@ -658,7 +658,7 @@ static int j1939_sk_setsockopt(struct socket *sock, int level, int optname,
|
||||||
|
|
||||||
switch (optname) {
|
switch (optname) {
|
||||||
case SO_J1939_FILTER:
|
case SO_J1939_FILTER:
|
||||||
if (optval) {
|
if (!sockptr_is_null(optval)) {
|
||||||
struct j1939_filter *f;
|
struct j1939_filter *f;
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
|
@ -670,7 +670,7 @@ static int j1939_sk_setsockopt(struct socket *sock, int level, int optname,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
count = optlen / sizeof(*filters);
|
count = optlen / sizeof(*filters);
|
||||||
filters = memdup_user(optval, optlen);
|
filters = memdup_sockptr(optval, optlen);
|
||||||
if (IS_ERR(filters))
|
if (IS_ERR(filters))
|
||||||
return PTR_ERR(filters);
|
return PTR_ERR(filters);
|
||||||
|
|
||||||
|
@ -703,7 +703,7 @@ static int j1939_sk_setsockopt(struct socket *sock, int level, int optname,
|
||||||
case SO_J1939_SEND_PRIO:
|
case SO_J1939_SEND_PRIO:
|
||||||
if (optlen != sizeof(tmp))
|
if (optlen != sizeof(tmp))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (copy_from_user(&tmp, optval, optlen))
|
if (copy_from_sockptr(&tmp, optval, optlen))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
if (tmp < 0 || tmp > 7)
|
if (tmp < 0 || tmp > 7)
|
||||||
return -EDOM;
|
return -EDOM;
|
||||||
|
|
|
@ -485,7 +485,7 @@ static int raw_getname(struct socket *sock, struct sockaddr *uaddr,
|
||||||
}
|
}
|
||||||
|
|
||||||
static int raw_setsockopt(struct socket *sock, int level, int optname,
|
static int raw_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 sock *sk = sock->sk;
|
||||||
struct raw_sock *ro = raw_sk(sk);
|
struct raw_sock *ro = raw_sk(sk);
|
||||||
|
@ -511,11 +511,11 @@ static int raw_setsockopt(struct socket *sock, int level, int optname,
|
||||||
|
|
||||||
if (count > 1) {
|
if (count > 1) {
|
||||||
/* filter does not fit into dfilter => alloc space */
|
/* filter does not fit into dfilter => alloc space */
|
||||||
filter = memdup_user(optval, optlen);
|
filter = memdup_sockptr(optval, optlen);
|
||||||
if (IS_ERR(filter))
|
if (IS_ERR(filter))
|
||||||
return PTR_ERR(filter);
|
return PTR_ERR(filter);
|
||||||
} else if (count == 1) {
|
} else if (count == 1) {
|
||||||
if (copy_from_user(&sfilter, optval, sizeof(sfilter)))
|
if (copy_from_sockptr(&sfilter, optval, sizeof(sfilter)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -568,7 +568,7 @@ static int raw_setsockopt(struct socket *sock, int level, int optname,
|
||||||
if (optlen != sizeof(err_mask))
|
if (optlen != sizeof(err_mask))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (copy_from_user(&err_mask, optval, optlen))
|
if (copy_from_sockptr(&err_mask, optval, optlen))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
err_mask &= CAN_ERR_MASK;
|
err_mask &= CAN_ERR_MASK;
|
||||||
|
@ -607,7 +607,7 @@ static int raw_setsockopt(struct socket *sock, int level, int optname,
|
||||||
if (optlen != sizeof(ro->loopback))
|
if (optlen != sizeof(ro->loopback))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (copy_from_user(&ro->loopback, optval, optlen))
|
if (copy_from_sockptr(&ro->loopback, optval, optlen))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -616,7 +616,7 @@ static int raw_setsockopt(struct socket *sock, int level, int optname,
|
||||||
if (optlen != sizeof(ro->recv_own_msgs))
|
if (optlen != sizeof(ro->recv_own_msgs))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (copy_from_user(&ro->recv_own_msgs, optval, optlen))
|
if (copy_from_sockptr(&ro->recv_own_msgs, optval, optlen))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -625,7 +625,7 @@ static int raw_setsockopt(struct socket *sock, int level, int optname,
|
||||||
if (optlen != sizeof(ro->fd_frames))
|
if (optlen != sizeof(ro->fd_frames))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (copy_from_user(&ro->fd_frames, optval, optlen))
|
if (copy_from_sockptr(&ro->fd_frames, optval, optlen))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -634,7 +634,7 @@ static int raw_setsockopt(struct socket *sock, int level, int optname,
|
||||||
if (optlen != sizeof(ro->join_filters))
|
if (optlen != sizeof(ro->join_filters))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (copy_from_user(&ro->join_filters, optval, optlen))
|
if (copy_from_sockptr(&ro->join_filters, optval, optlen))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -3211,7 +3211,7 @@ EXPORT_SYMBOL(sock_common_recvmsg);
|
||||||
* Set socket options on an inet socket.
|
* Set socket options on an inet socket.
|
||||||
*/
|
*/
|
||||||
int sock_common_setsockopt(struct socket *sock, int level, int optname,
|
int sock_common_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 sock *sk = sock->sk;
|
||||||
|
|
||||||
|
|
|
@ -295,7 +295,7 @@ int dccp_disconnect(struct sock *sk, int flags);
|
||||||
int dccp_getsockopt(struct sock *sk, int level, int optname,
|
int dccp_getsockopt(struct sock *sk, int level, int optname,
|
||||||
char __user *optval, int __user *optlen);
|
char __user *optval, int __user *optlen);
|
||||||
int dccp_setsockopt(struct sock *sk, int level, int optname,
|
int dccp_setsockopt(struct sock *sk, int level, int optname,
|
||||||
char __user *optval, unsigned int optlen);
|
sockptr_t optval, unsigned int optlen);
|
||||||
int dccp_ioctl(struct sock *sk, int cmd, unsigned long arg);
|
int dccp_ioctl(struct sock *sk, int cmd, unsigned long arg);
|
||||||
int dccp_sendmsg(struct sock *sk, struct msghdr *msg, size_t size);
|
int dccp_sendmsg(struct sock *sk, struct msghdr *msg, size_t size);
|
||||||
int dccp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int nonblock,
|
int dccp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int nonblock,
|
||||||
|
|
|
@ -411,7 +411,7 @@ out:
|
||||||
EXPORT_SYMBOL_GPL(dccp_ioctl);
|
EXPORT_SYMBOL_GPL(dccp_ioctl);
|
||||||
|
|
||||||
static int dccp_setsockopt_service(struct sock *sk, const __be32 service,
|
static int dccp_setsockopt_service(struct sock *sk, const __be32 service,
|
||||||
char __user *optval, unsigned int optlen)
|
sockptr_t optval, unsigned int optlen)
|
||||||
{
|
{
|
||||||
struct dccp_sock *dp = dccp_sk(sk);
|
struct dccp_sock *dp = dccp_sk(sk);
|
||||||
struct dccp_service_list *sl = NULL;
|
struct dccp_service_list *sl = NULL;
|
||||||
|
@ -426,9 +426,9 @@ static int dccp_setsockopt_service(struct sock *sk, const __be32 service,
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
sl->dccpsl_nr = optlen / sizeof(u32) - 1;
|
sl->dccpsl_nr = optlen / sizeof(u32) - 1;
|
||||||
if (copy_from_user(sl->dccpsl_list,
|
sockptr_advance(optval, sizeof(service));
|
||||||
optval + sizeof(service),
|
if (copy_from_sockptr(sl->dccpsl_list, optval,
|
||||||
optlen - sizeof(service)) ||
|
optlen - sizeof(service)) ||
|
||||||
dccp_list_has_service(sl, DCCP_SERVICE_INVALID_VALUE)) {
|
dccp_list_has_service(sl, DCCP_SERVICE_INVALID_VALUE)) {
|
||||||
kfree(sl);
|
kfree(sl);
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
@ -482,7 +482,7 @@ static int dccp_setsockopt_cscov(struct sock *sk, int cscov, bool rx)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dccp_setsockopt_ccid(struct sock *sk, int type,
|
static int dccp_setsockopt_ccid(struct sock *sk, int type,
|
||||||
char __user *optval, unsigned int optlen)
|
sockptr_t optval, unsigned int optlen)
|
||||||
{
|
{
|
||||||
u8 *val;
|
u8 *val;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
@ -490,7 +490,7 @@ static int dccp_setsockopt_ccid(struct sock *sk, int type,
|
||||||
if (optlen < 1 || optlen > DCCP_FEAT_MAX_SP_VALS)
|
if (optlen < 1 || optlen > DCCP_FEAT_MAX_SP_VALS)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
val = memdup_user(optval, optlen);
|
val = memdup_sockptr(optval, optlen);
|
||||||
if (IS_ERR(val))
|
if (IS_ERR(val))
|
||||||
return PTR_ERR(val);
|
return PTR_ERR(val);
|
||||||
|
|
||||||
|
@ -507,7 +507,7 @@ static int dccp_setsockopt_ccid(struct sock *sk, int type,
|
||||||
}
|
}
|
||||||
|
|
||||||
static int do_dccp_setsockopt(struct sock *sk, int level, int optname,
|
static int do_dccp_setsockopt(struct sock *sk, int level, int optname,
|
||||||
char __user *optval, unsigned int optlen)
|
sockptr_t optval, unsigned int optlen)
|
||||||
{
|
{
|
||||||
struct dccp_sock *dp = dccp_sk(sk);
|
struct dccp_sock *dp = dccp_sk(sk);
|
||||||
int val, err = 0;
|
int val, err = 0;
|
||||||
|
@ -529,7 +529,7 @@ static int do_dccp_setsockopt(struct sock *sk, int level, int optname,
|
||||||
if (optlen < (int)sizeof(int))
|
if (optlen < (int)sizeof(int))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (get_user(val, (int __user *)optval))
|
if (copy_from_sockptr(&val, optval, sizeof(int)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
if (optname == DCCP_SOCKOPT_SERVICE)
|
if (optname == DCCP_SOCKOPT_SERVICE)
|
||||||
|
@ -572,8 +572,8 @@ static int do_dccp_setsockopt(struct sock *sk, int level, int optname,
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dccp_setsockopt(struct sock *sk, int level, int optname,
|
int dccp_setsockopt(struct sock *sk, int level, int optname, sockptr_t optval,
|
||||||
char __user *optval, unsigned int optlen)
|
unsigned int optlen)
|
||||||
{
|
{
|
||||||
if (level != SOL_DCCP)
|
if (level != SOL_DCCP)
|
||||||
return inet_csk(sk)->icsk_af_ops->setsockopt(sk, level,
|
return inet_csk(sk)->icsk_af_ops->setsockopt(sk, level,
|
||||||
|
|
|
@ -150,7 +150,8 @@ static struct hlist_head dn_sk_hash[DN_SK_HASH_SIZE];
|
||||||
static struct hlist_head dn_wild_sk;
|
static struct hlist_head dn_wild_sk;
|
||||||
static atomic_long_t decnet_memory_allocated;
|
static atomic_long_t decnet_memory_allocated;
|
||||||
|
|
||||||
static int __dn_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen, int flags);
|
static int __dn_setsockopt(struct socket *sock, int level, int optname,
|
||||||
|
sockptr_t optval, unsigned int optlen, int flags);
|
||||||
static int __dn_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen, int flags);
|
static int __dn_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen, int flags);
|
||||||
|
|
||||||
static struct hlist_head *dn_find_list(struct sock *sk)
|
static struct hlist_head *dn_find_list(struct sock *sk)
|
||||||
|
@ -1320,7 +1321,8 @@ out:
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dn_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
|
static int dn_setsockopt(struct socket *sock, int level, int optname,
|
||||||
|
sockptr_t optval, unsigned int optlen)
|
||||||
{
|
{
|
||||||
struct sock *sk = sock->sk;
|
struct sock *sk = sock->sk;
|
||||||
int err;
|
int err;
|
||||||
|
@ -1332,14 +1334,14 @@ static int dn_setsockopt(struct socket *sock, int level, int optname, char __use
|
||||||
/* we need to exclude all possible ENOPROTOOPTs except default case */
|
/* we need to exclude all possible ENOPROTOOPTs except default case */
|
||||||
if (err == -ENOPROTOOPT && optname != DSO_LINKINFO &&
|
if (err == -ENOPROTOOPT && optname != DSO_LINKINFO &&
|
||||||
optname != DSO_STREAM && optname != DSO_SEQPACKET)
|
optname != DSO_STREAM && optname != DSO_SEQPACKET)
|
||||||
err = nf_setsockopt(sk, PF_DECnet, optname,
|
err = nf_setsockopt(sk, PF_DECnet, optname, optval, optlen);
|
||||||
USER_SOCKPTR(optval), optlen);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __dn_setsockopt(struct socket *sock, int level,int optname, char __user *optval, unsigned int optlen, int flags)
|
static int __dn_setsockopt(struct socket *sock, int level, int optname,
|
||||||
|
sockptr_t optval, unsigned int optlen, int flags)
|
||||||
{
|
{
|
||||||
struct sock *sk = sock->sk;
|
struct sock *sk = sock->sk;
|
||||||
struct dn_scp *scp = DN_SK(sk);
|
struct dn_scp *scp = DN_SK(sk);
|
||||||
|
@ -1355,13 +1357,13 @@ static int __dn_setsockopt(struct socket *sock, int level,int optname, char __us
|
||||||
} u;
|
} u;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (optlen && !optval)
|
if (optlen && sockptr_is_null(optval))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (optlen > sizeof(u))
|
if (optlen > sizeof(u))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (copy_from_user(&u, optval, optlen))
|
if (copy_from_sockptr(&u, optval, optlen))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
switch (optname) {
|
switch (optname) {
|
||||||
|
|
|
@ -382,7 +382,7 @@ static int raw_getsockopt(struct sock *sk, int level, int optname,
|
||||||
}
|
}
|
||||||
|
|
||||||
static int raw_setsockopt(struct sock *sk, int level, int optname,
|
static int raw_setsockopt(struct sock *sk, int level, int optname,
|
||||||
char __user *optval, unsigned int optlen)
|
sockptr_t optval, unsigned int optlen)
|
||||||
{
|
{
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
|
@ -872,7 +872,7 @@ static int dgram_getsockopt(struct sock *sk, int level, int optname,
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dgram_setsockopt(struct sock *sk, int level, int optname,
|
static int dgram_setsockopt(struct sock *sk, int level, int optname,
|
||||||
char __user *optval, unsigned int optlen)
|
sockptr_t optval, unsigned int optlen)
|
||||||
{
|
{
|
||||||
struct dgram_sock *ro = dgram_sk(sk);
|
struct dgram_sock *ro = dgram_sk(sk);
|
||||||
struct net *net = sock_net(sk);
|
struct net *net = sock_net(sk);
|
||||||
|
@ -882,7 +882,7 @@ static int dgram_setsockopt(struct sock *sk, int level, int optname,
|
||||||
if (optlen < sizeof(int))
|
if (optlen < sizeof(int))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (get_user(val, (int __user *)optval))
|
if (copy_from_sockptr(&val, optval, sizeof(int)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
lock_sock(sk);
|
lock_sock(sk);
|
||||||
|
|
|
@ -1401,21 +1401,19 @@ void ipv4_pktinfo_prepare(const struct sock *sk, struct sk_buff *skb)
|
||||||
skb_dst_drop(skb);
|
skb_dst_drop(skb);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ip_setsockopt(struct sock *sk, int level,
|
int ip_setsockopt(struct sock *sk, int level, int optname, sockptr_t optval,
|
||||||
int optname, char __user *optval, unsigned int optlen)
|
unsigned int optlen)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (level != SOL_IP)
|
if (level != SOL_IP)
|
||||||
return -ENOPROTOOPT;
|
return -ENOPROTOOPT;
|
||||||
|
|
||||||
err = do_ip_setsockopt(sk, level, optname, USER_SOCKPTR(optval),
|
err = do_ip_setsockopt(sk, level, optname, optval, optlen);
|
||||||
optlen);
|
|
||||||
#if IS_ENABLED(CONFIG_BPFILTER_UMH)
|
#if IS_ENABLED(CONFIG_BPFILTER_UMH)
|
||||||
if (optname >= BPFILTER_IPT_SO_SET_REPLACE &&
|
if (optname >= BPFILTER_IPT_SO_SET_REPLACE &&
|
||||||
optname < BPFILTER_IPT_SET_MAX)
|
optname < BPFILTER_IPT_SET_MAX)
|
||||||
err = bpfilter_ip_set_sockopt(sk, optname, USER_SOCKPTR(optval),
|
err = bpfilter_ip_set_sockopt(sk, optname, optval, optlen);
|
||||||
optlen);
|
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_NETFILTER
|
#ifdef CONFIG_NETFILTER
|
||||||
/* we need to exclude all possible ENOPROTOOPTs except default case */
|
/* we need to exclude all possible ENOPROTOOPTs except default case */
|
||||||
|
@ -1423,8 +1421,7 @@ int ip_setsockopt(struct sock *sk, int level,
|
||||||
optname != IP_IPSEC_POLICY &&
|
optname != IP_IPSEC_POLICY &&
|
||||||
optname != IP_XFRM_POLICY &&
|
optname != IP_XFRM_POLICY &&
|
||||||
!ip_mroute_opt(optname))
|
!ip_mroute_opt(optname))
|
||||||
err = nf_setsockopt(sk, PF_INET, optname, USER_SOCKPTR(optval),
|
err = nf_setsockopt(sk, PF_INET, optname, optval, optlen);
|
||||||
optlen);
|
|
||||||
#endif
|
#endif
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
|
@ -809,11 +809,11 @@ static int raw_sk_init(struct sock *sk)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int raw_seticmpfilter(struct sock *sk, char __user *optval, int optlen)
|
static int raw_seticmpfilter(struct sock *sk, sockptr_t optval, int optlen)
|
||||||
{
|
{
|
||||||
if (optlen > sizeof(struct icmp_filter))
|
if (optlen > sizeof(struct icmp_filter))
|
||||||
optlen = sizeof(struct icmp_filter);
|
optlen = sizeof(struct icmp_filter);
|
||||||
if (copy_from_user(&raw_sk(sk)->filter, optval, optlen))
|
if (copy_from_sockptr(&raw_sk(sk)->filter, optval, optlen))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -838,7 +838,7 @@ out: return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int do_raw_setsockopt(struct sock *sk, int level, int optname,
|
static int do_raw_setsockopt(struct sock *sk, int level, int optname,
|
||||||
char __user *optval, unsigned int optlen)
|
sockptr_t optval, unsigned int optlen)
|
||||||
{
|
{
|
||||||
if (optname == ICMP_FILTER) {
|
if (optname == ICMP_FILTER) {
|
||||||
if (inet_sk(sk)->inet_num != IPPROTO_ICMP)
|
if (inet_sk(sk)->inet_num != IPPROTO_ICMP)
|
||||||
|
@ -850,7 +850,7 @@ static int do_raw_setsockopt(struct sock *sk, int level, int optname,
|
||||||
}
|
}
|
||||||
|
|
||||||
static int raw_setsockopt(struct sock *sk, int level, int optname,
|
static int raw_setsockopt(struct sock *sk, int level, int optname,
|
||||||
char __user *optval, unsigned int optlen)
|
sockptr_t optval, unsigned int optlen)
|
||||||
{
|
{
|
||||||
if (level != SOL_RAW)
|
if (level != SOL_RAW)
|
||||||
return ip_setsockopt(sk, level, optname, optval, optlen);
|
return ip_setsockopt(sk, level, optname, optval, optlen);
|
||||||
|
|
|
@ -3323,7 +3323,7 @@ static int do_tcp_setsockopt(struct sock *sk, int level, int optname,
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
int tcp_setsockopt(struct sock *sk, int level, int optname, char __user *optval,
|
int tcp_setsockopt(struct sock *sk, int level, int optname, sockptr_t optval,
|
||||||
unsigned int optlen)
|
unsigned int optlen)
|
||||||
{
|
{
|
||||||
const struct inet_connection_sock *icsk = inet_csk(sk);
|
const struct inet_connection_sock *icsk = inet_csk(sk);
|
||||||
|
@ -3331,8 +3331,7 @@ int tcp_setsockopt(struct sock *sk, int level, int optname, char __user *optval,
|
||||||
if (level != SOL_TCP)
|
if (level != SOL_TCP)
|
||||||
return icsk->icsk_af_ops->setsockopt(sk, level, optname,
|
return icsk->icsk_af_ops->setsockopt(sk, level, optname,
|
||||||
optval, optlen);
|
optval, optlen);
|
||||||
return do_tcp_setsockopt(sk, level, optname, USER_SOCKPTR(optval),
|
return do_tcp_setsockopt(sk, level, optname, optval, optlen);
|
||||||
optlen);
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(tcp_setsockopt);
|
EXPORT_SYMBOL(tcp_setsockopt);
|
||||||
|
|
||||||
|
|
|
@ -2703,12 +2703,12 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(udp_lib_setsockopt);
|
EXPORT_SYMBOL(udp_lib_setsockopt);
|
||||||
|
|
||||||
int udp_setsockopt(struct sock *sk, int level, int optname,
|
int udp_setsockopt(struct sock *sk, int level, int optname, sockptr_t optval,
|
||||||
char __user *optval, unsigned int optlen)
|
unsigned int optlen)
|
||||||
{
|
{
|
||||||
if (level == SOL_UDP || level == SOL_UDPLITE)
|
if (level == SOL_UDP || level == SOL_UDPLITE)
|
||||||
return udp_lib_setsockopt(sk, level, optname,
|
return udp_lib_setsockopt(sk, level, optname,
|
||||||
USER_SOCKPTR(optval), optlen,
|
optval, optlen,
|
||||||
udp_push_pending_frames);
|
udp_push_pending_frames);
|
||||||
return ip_setsockopt(sk, level, optname, optval, optlen);
|
return ip_setsockopt(sk, level, optname, optval, optlen);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,8 +12,8 @@ int __udp4_lib_err(struct sk_buff *, u32, struct udp_table *);
|
||||||
int udp_v4_get_port(struct sock *sk, unsigned short snum);
|
int udp_v4_get_port(struct sock *sk, unsigned short snum);
|
||||||
void udp_v4_rehash(struct sock *sk);
|
void udp_v4_rehash(struct sock *sk);
|
||||||
|
|
||||||
int udp_setsockopt(struct sock *sk, int level, int optname,
|
int udp_setsockopt(struct sock *sk, int level, int optname, sockptr_t optval,
|
||||||
char __user *optval, unsigned int optlen);
|
unsigned int optlen);
|
||||||
int udp_getsockopt(struct sock *sk, int level, int optname,
|
int udp_getsockopt(struct sock *sk, int level, int optname,
|
||||||
char __user *optval, int __user *optlen);
|
char __user *optval, int __user *optlen);
|
||||||
|
|
||||||
|
|
|
@ -980,8 +980,8 @@ e_inval:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ipv6_setsockopt(struct sock *sk, int level, int optname,
|
int ipv6_setsockopt(struct sock *sk, int level, int optname, sockptr_t optval,
|
||||||
char __user *optval, unsigned int optlen)
|
unsigned int optlen)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
@ -991,14 +991,12 @@ int ipv6_setsockopt(struct sock *sk, int level, int optname,
|
||||||
if (level != SOL_IPV6)
|
if (level != SOL_IPV6)
|
||||||
return -ENOPROTOOPT;
|
return -ENOPROTOOPT;
|
||||||
|
|
||||||
err = do_ipv6_setsockopt(sk, level, optname, USER_SOCKPTR(optval),
|
err = do_ipv6_setsockopt(sk, level, optname, optval, optlen);
|
||||||
optlen);
|
|
||||||
#ifdef CONFIG_NETFILTER
|
#ifdef CONFIG_NETFILTER
|
||||||
/* we need to exclude all possible ENOPROTOOPTs except default case */
|
/* we need to exclude all possible ENOPROTOOPTs except default case */
|
||||||
if (err == -ENOPROTOOPT && optname != IPV6_IPSEC_POLICY &&
|
if (err == -ENOPROTOOPT && optname != IPV6_IPSEC_POLICY &&
|
||||||
optname != IPV6_XFRM_POLICY)
|
optname != IPV6_XFRM_POLICY)
|
||||||
err = nf_setsockopt(sk, PF_INET6, optname, USER_SOCKPTR(optval),
|
err = nf_setsockopt(sk, PF_INET6, optname, optval, optlen);
|
||||||
optlen);
|
|
||||||
#endif
|
#endif
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
|
@ -972,13 +972,13 @@ do_confirm:
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rawv6_seticmpfilter(struct sock *sk, int level, int optname,
|
static int rawv6_seticmpfilter(struct sock *sk, int level, int optname,
|
||||||
char __user *optval, int optlen)
|
sockptr_t optval, int optlen)
|
||||||
{
|
{
|
||||||
switch (optname) {
|
switch (optname) {
|
||||||
case ICMPV6_FILTER:
|
case ICMPV6_FILTER:
|
||||||
if (optlen > sizeof(struct icmp6_filter))
|
if (optlen > sizeof(struct icmp6_filter))
|
||||||
optlen = sizeof(struct icmp6_filter);
|
optlen = sizeof(struct icmp6_filter);
|
||||||
if (copy_from_user(&raw6_sk(sk)->filter, optval, optlen))
|
if (copy_from_sockptr(&raw6_sk(sk)->filter, optval, optlen))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
return 0;
|
return 0;
|
||||||
default:
|
default:
|
||||||
|
@ -1015,12 +1015,12 @@ static int rawv6_geticmpfilter(struct sock *sk, int level, int optname,
|
||||||
|
|
||||||
|
|
||||||
static int do_rawv6_setsockopt(struct sock *sk, int level, int optname,
|
static int do_rawv6_setsockopt(struct sock *sk, int level, int optname,
|
||||||
char __user *optval, unsigned int optlen)
|
sockptr_t optval, unsigned int optlen)
|
||||||
{
|
{
|
||||||
struct raw6_sock *rp = raw6_sk(sk);
|
struct raw6_sock *rp = raw6_sk(sk);
|
||||||
int val;
|
int val;
|
||||||
|
|
||||||
if (get_user(val, (int __user *)optval))
|
if (copy_from_sockptr(&val, optval, sizeof(val)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
switch (optname) {
|
switch (optname) {
|
||||||
|
@ -1062,7 +1062,7 @@ static int do_rawv6_setsockopt(struct sock *sk, int level, int optname,
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rawv6_setsockopt(struct sock *sk, int level, int optname,
|
static int rawv6_setsockopt(struct sock *sk, int level, int optname,
|
||||||
char __user *optval, unsigned int optlen)
|
sockptr_t optval, unsigned int optlen)
|
||||||
{
|
{
|
||||||
switch (level) {
|
switch (level) {
|
||||||
case SOL_RAW:
|
case SOL_RAW:
|
||||||
|
|
|
@ -1618,12 +1618,12 @@ void udpv6_destroy_sock(struct sock *sk)
|
||||||
/*
|
/*
|
||||||
* Socket option code for UDP
|
* Socket option code for UDP
|
||||||
*/
|
*/
|
||||||
int udpv6_setsockopt(struct sock *sk, int level, int optname,
|
int udpv6_setsockopt(struct sock *sk, int level, int optname, sockptr_t optval,
|
||||||
char __user *optval, unsigned int optlen)
|
unsigned int optlen)
|
||||||
{
|
{
|
||||||
if (level == SOL_UDP || level == SOL_UDPLITE)
|
if (level == SOL_UDP || level == SOL_UDPLITE)
|
||||||
return udp_lib_setsockopt(sk, level, optname,
|
return udp_lib_setsockopt(sk, level, optname,
|
||||||
USER_SOCKPTR(optval), optlen,
|
optval, optlen,
|
||||||
udp_v6_push_pending_frames);
|
udp_v6_push_pending_frames);
|
||||||
return ipv6_setsockopt(sk, level, optname, optval, optlen);
|
return ipv6_setsockopt(sk, level, optname, optval, optlen);
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,8 +17,8 @@ void udp_v6_rehash(struct sock *sk);
|
||||||
|
|
||||||
int udpv6_getsockopt(struct sock *sk, int level, int optname,
|
int udpv6_getsockopt(struct sock *sk, int level, int optname,
|
||||||
char __user *optval, int __user *optlen);
|
char __user *optval, int __user *optlen);
|
||||||
int udpv6_setsockopt(struct sock *sk, int level, int optname,
|
int udpv6_setsockopt(struct sock *sk, int level, int optname, sockptr_t optval,
|
||||||
char __user *optval, unsigned int optlen);
|
unsigned int optlen);
|
||||||
int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len);
|
int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len);
|
||||||
int udpv6_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int noblock,
|
int udpv6_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int noblock,
|
||||||
int flags, int *addr_len);
|
int flags, int *addr_len);
|
||||||
|
|
|
@ -1494,7 +1494,7 @@ static int iucv_sock_release(struct socket *sock)
|
||||||
|
|
||||||
/* getsockopt and setsockopt */
|
/* getsockopt and setsockopt */
|
||||||
static int iucv_sock_setsockopt(struct socket *sock, int level, int optname,
|
static int iucv_sock_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 sock *sk = sock->sk;
|
||||||
struct iucv_sock *iucv = iucv_sk(sk);
|
struct iucv_sock *iucv = iucv_sk(sk);
|
||||||
|
@ -1507,7 +1507,7 @@ static int iucv_sock_setsockopt(struct socket *sock, int level, int optname,
|
||||||
if (optlen < sizeof(int))
|
if (optlen < sizeof(int))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (get_user(val, (int __user *) optval))
|
if (copy_from_sockptr(&val, optval, sizeof(int)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
rc = 0;
|
rc = 0;
|
||||||
|
|
|
@ -1265,7 +1265,7 @@ static void kcm_recv_enable(struct kcm_sock *kcm)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int kcm_setsockopt(struct socket *sock, int level, int optname,
|
static int kcm_setsockopt(struct socket *sock, int level, int optname,
|
||||||
char __user *optval, unsigned int optlen)
|
sockptr_t optval, unsigned int optlen)
|
||||||
{
|
{
|
||||||
struct kcm_sock *kcm = kcm_sk(sock->sk);
|
struct kcm_sock *kcm = kcm_sk(sock->sk);
|
||||||
int val, valbool;
|
int val, valbool;
|
||||||
|
@ -1277,8 +1277,8 @@ static int kcm_setsockopt(struct socket *sock, int level, int optname,
|
||||||
if (optlen < sizeof(int))
|
if (optlen < sizeof(int))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (get_user(val, (int __user *)optval))
|
if (copy_from_sockptr(&val, optval, sizeof(int)))
|
||||||
return -EINVAL;
|
return -EFAULT;
|
||||||
|
|
||||||
valbool = val ? 1 : 0;
|
valbool = val ? 1 : 0;
|
||||||
|
|
||||||
|
|
|
@ -1242,7 +1242,7 @@ static int pppol2tp_session_setsockopt(struct sock *sk,
|
||||||
* session or the special tunnel type.
|
* session or the special tunnel type.
|
||||||
*/
|
*/
|
||||||
static int pppol2tp_setsockopt(struct socket *sock, int level, int optname,
|
static int pppol2tp_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 sock *sk = sock->sk;
|
||||||
struct l2tp_session *session;
|
struct l2tp_session *session;
|
||||||
|
@ -1256,7 +1256,7 @@ static int pppol2tp_setsockopt(struct socket *sock, int level, int optname,
|
||||||
if (optlen < sizeof(int))
|
if (optlen < sizeof(int))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (get_user(val, (int __user *)optval))
|
if (copy_from_sockptr(&val, optval, sizeof(int)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
err = -ENOTCONN;
|
err = -ENOTCONN;
|
||||||
|
|
|
@ -1053,7 +1053,7 @@ static int llc_ui_ioctl(struct socket *sock, unsigned int cmd,
|
||||||
* Set various connection specific parameters.
|
* Set various connection specific parameters.
|
||||||
*/
|
*/
|
||||||
static int llc_ui_setsockopt(struct socket *sock, int level, int optname,
|
static int llc_ui_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 sock *sk = sock->sk;
|
||||||
struct llc_sock *llc = llc_sk(sk);
|
struct llc_sock *llc = llc_sk(sk);
|
||||||
|
@ -1063,7 +1063,7 @@ static int llc_ui_setsockopt(struct socket *sock, int level, int optname,
|
||||||
lock_sock(sk);
|
lock_sock(sk);
|
||||||
if (unlikely(level != SOL_LLC || optlen != sizeof(int)))
|
if (unlikely(level != SOL_LLC || optlen != sizeof(int)))
|
||||||
goto out;
|
goto out;
|
||||||
rc = get_user(opt, (int __user *)optval);
|
rc = copy_from_sockptr(&opt, optval, sizeof(opt));
|
||||||
if (rc)
|
if (rc)
|
||||||
goto out;
|
goto out;
|
||||||
rc = -EINVAL;
|
rc = -EINVAL;
|
||||||
|
|
|
@ -1632,7 +1632,7 @@ static void mptcp_destroy(struct sock *sk)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mptcp_setsockopt_sol_socket(struct mptcp_sock *msk, int optname,
|
static int mptcp_setsockopt_sol_socket(struct mptcp_sock *msk, int optname,
|
||||||
char __user *optval, unsigned int optlen)
|
sockptr_t optval, unsigned int optlen)
|
||||||
{
|
{
|
||||||
struct sock *sk = (struct sock *)msk;
|
struct sock *sk = (struct sock *)msk;
|
||||||
struct socket *ssock;
|
struct socket *ssock;
|
||||||
|
@ -1648,8 +1648,7 @@ static int mptcp_setsockopt_sol_socket(struct mptcp_sock *msk, int optname,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = sock_setsockopt(ssock, SOL_SOCKET, optname,
|
ret = sock_setsockopt(ssock, SOL_SOCKET, optname, optval, optlen);
|
||||||
USER_SOCKPTR(optval), optlen);
|
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
if (optname == SO_REUSEPORT)
|
if (optname == SO_REUSEPORT)
|
||||||
sk->sk_reuseport = ssock->sk->sk_reuseport;
|
sk->sk_reuseport = ssock->sk->sk_reuseport;
|
||||||
|
@ -1660,12 +1659,11 @@ static int mptcp_setsockopt_sol_socket(struct mptcp_sock *msk, int optname,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
return sock_setsockopt(sk->sk_socket, SOL_SOCKET, optname,
|
return sock_setsockopt(sk->sk_socket, SOL_SOCKET, optname, optval, optlen);
|
||||||
USER_SOCKPTR(optval), optlen);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mptcp_setsockopt_v6(struct mptcp_sock *msk, int optname,
|
static int mptcp_setsockopt_v6(struct mptcp_sock *msk, int optname,
|
||||||
char __user *optval, unsigned int optlen)
|
sockptr_t optval, unsigned int optlen)
|
||||||
{
|
{
|
||||||
struct sock *sk = (struct sock *)msk;
|
struct sock *sk = (struct sock *)msk;
|
||||||
int ret = -EOPNOTSUPP;
|
int ret = -EOPNOTSUPP;
|
||||||
|
@ -1692,7 +1690,7 @@ static int mptcp_setsockopt_v6(struct mptcp_sock *msk, int optname,
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mptcp_setsockopt(struct sock *sk, int level, int optname,
|
static int mptcp_setsockopt(struct sock *sk, int level, int optname,
|
||||||
char __user *optval, unsigned int optlen)
|
sockptr_t optval, unsigned int optlen)
|
||||||
{
|
{
|
||||||
struct mptcp_sock *msk = mptcp_sk(sk);
|
struct mptcp_sock *msk = mptcp_sk(sk);
|
||||||
struct sock *ssk;
|
struct sock *ssk;
|
||||||
|
|
|
@ -1621,7 +1621,7 @@ static void netlink_update_socket_mc(struct netlink_sock *nlk,
|
||||||
}
|
}
|
||||||
|
|
||||||
static int netlink_setsockopt(struct socket *sock, int level, int optname,
|
static int netlink_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 sock *sk = sock->sk;
|
||||||
struct netlink_sock *nlk = nlk_sk(sk);
|
struct netlink_sock *nlk = nlk_sk(sk);
|
||||||
|
@ -1632,7 +1632,7 @@ static int netlink_setsockopt(struct socket *sock, int level, int optname,
|
||||||
return -ENOPROTOOPT;
|
return -ENOPROTOOPT;
|
||||||
|
|
||||||
if (optlen >= sizeof(int) &&
|
if (optlen >= sizeof(int) &&
|
||||||
get_user(val, (unsigned int __user *)optval))
|
copy_from_sockptr(&val, optval, sizeof(val)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
switch (optname) {
|
switch (optname) {
|
||||||
|
|
|
@ -294,7 +294,7 @@ void nr_destroy_socket(struct sock *sk)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int nr_setsockopt(struct socket *sock, int level, int optname,
|
static int nr_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 sock *sk = sock->sk;
|
||||||
struct nr_sock *nr = nr_sk(sk);
|
struct nr_sock *nr = nr_sk(sk);
|
||||||
|
@ -306,7 +306,7 @@ static int nr_setsockopt(struct socket *sock, int level, int optname,
|
||||||
if (optlen < sizeof(unsigned int))
|
if (optlen < sizeof(unsigned int))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (get_user(opt, (unsigned int __user *)optval))
|
if (copy_from_sockptr(&opt, optval, sizeof(unsigned int)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
switch (optname) {
|
switch (optname) {
|
||||||
|
|
|
@ -218,7 +218,7 @@ error:
|
||||||
}
|
}
|
||||||
|
|
||||||
static int nfc_llcp_setsockopt(struct socket *sock, int level, int optname,
|
static int nfc_llcp_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 sock *sk = sock->sk;
|
||||||
struct nfc_llcp_sock *llcp_sock = nfc_llcp_sock(sk);
|
struct nfc_llcp_sock *llcp_sock = nfc_llcp_sock(sk);
|
||||||
|
@ -241,7 +241,7 @@ static int nfc_llcp_setsockopt(struct socket *sock, int level, int optname,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (get_user(opt, (u32 __user *) optval)) {
|
if (copy_from_sockptr(&opt, optval, sizeof(u32))) {
|
||||||
err = -EFAULT;
|
err = -EFAULT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -263,7 +263,7 @@ static int nfc_llcp_setsockopt(struct socket *sock, int level, int optname,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (get_user(opt, (u32 __user *) optval)) {
|
if (copy_from_sockptr(&opt, optval, sizeof(u32))) {
|
||||||
err = -EFAULT;
|
err = -EFAULT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1558,7 +1558,7 @@ static int fanout_set_data_cbpf(struct packet_sock *po, sockptr_t data,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int fanout_set_data_ebpf(struct packet_sock *po, char __user *data,
|
static int fanout_set_data_ebpf(struct packet_sock *po, sockptr_t data,
|
||||||
unsigned int len)
|
unsigned int len)
|
||||||
{
|
{
|
||||||
struct bpf_prog *new;
|
struct bpf_prog *new;
|
||||||
|
@ -1568,7 +1568,7 @@ static int fanout_set_data_ebpf(struct packet_sock *po, char __user *data,
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
if (len != sizeof(fd))
|
if (len != sizeof(fd))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (copy_from_user(&fd, data, len))
|
if (copy_from_sockptr(&fd, data, len))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
new = bpf_prog_get_type(fd, BPF_PROG_TYPE_SOCKET_FILTER);
|
new = bpf_prog_get_type(fd, BPF_PROG_TYPE_SOCKET_FILTER);
|
||||||
|
@ -1579,12 +1579,12 @@ static int fanout_set_data_ebpf(struct packet_sock *po, char __user *data,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int fanout_set_data(struct packet_sock *po, char __user *data,
|
static int fanout_set_data(struct packet_sock *po, sockptr_t data,
|
||||||
unsigned int len)
|
unsigned int len)
|
||||||
{
|
{
|
||||||
switch (po->fanout->type) {
|
switch (po->fanout->type) {
|
||||||
case PACKET_FANOUT_CBPF:
|
case PACKET_FANOUT_CBPF:
|
||||||
return fanout_set_data_cbpf(po, USER_SOCKPTR(data), len);
|
return fanout_set_data_cbpf(po, data, len);
|
||||||
case PACKET_FANOUT_EBPF:
|
case PACKET_FANOUT_EBPF:
|
||||||
return fanout_set_data_ebpf(po, data, len);
|
return fanout_set_data_ebpf(po, data, len);
|
||||||
default:
|
default:
|
||||||
|
@ -3652,7 +3652,8 @@ static void packet_flush_mclist(struct sock *sk)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
packet_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
|
packet_setsockopt(struct socket *sock, int level, int optname, sockptr_t optval,
|
||||||
|
unsigned int optlen)
|
||||||
{
|
{
|
||||||
struct sock *sk = sock->sk;
|
struct sock *sk = sock->sk;
|
||||||
struct packet_sock *po = pkt_sk(sk);
|
struct packet_sock *po = pkt_sk(sk);
|
||||||
|
@ -3672,7 +3673,7 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (len > sizeof(mreq))
|
if (len > sizeof(mreq))
|
||||||
len = sizeof(mreq);
|
len = sizeof(mreq);
|
||||||
if (copy_from_user(&mreq, optval, len))
|
if (copy_from_sockptr(&mreq, optval, len))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
if (len < (mreq.mr_alen + offsetof(struct packet_mreq, mr_address)))
|
if (len < (mreq.mr_alen + offsetof(struct packet_mreq, mr_address)))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -3703,7 +3704,7 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv
|
||||||
if (optlen < len) {
|
if (optlen < len) {
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
} else {
|
} else {
|
||||||
if (copy_from_user(&req_u.req, optval, len))
|
if (copy_from_sockptr(&req_u.req, optval, len))
|
||||||
ret = -EFAULT;
|
ret = -EFAULT;
|
||||||
else
|
else
|
||||||
ret = packet_set_ring(sk, &req_u, 0,
|
ret = packet_set_ring(sk, &req_u, 0,
|
||||||
|
@ -3718,7 +3719,7 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv
|
||||||
|
|
||||||
if (optlen != sizeof(val))
|
if (optlen != sizeof(val))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (copy_from_user(&val, optval, sizeof(val)))
|
if (copy_from_sockptr(&val, optval, sizeof(val)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
pkt_sk(sk)->copy_thresh = val;
|
pkt_sk(sk)->copy_thresh = val;
|
||||||
|
@ -3730,7 +3731,7 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv
|
||||||
|
|
||||||
if (optlen != sizeof(val))
|
if (optlen != sizeof(val))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (copy_from_user(&val, optval, sizeof(val)))
|
if (copy_from_sockptr(&val, optval, sizeof(val)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
switch (val) {
|
switch (val) {
|
||||||
case TPACKET_V1:
|
case TPACKET_V1:
|
||||||
|
@ -3756,7 +3757,7 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv
|
||||||
|
|
||||||
if (optlen != sizeof(val))
|
if (optlen != sizeof(val))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (copy_from_user(&val, optval, sizeof(val)))
|
if (copy_from_sockptr(&val, optval, sizeof(val)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
if (val > INT_MAX)
|
if (val > INT_MAX)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -3776,7 +3777,7 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv
|
||||||
|
|
||||||
if (optlen != sizeof(val))
|
if (optlen != sizeof(val))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (copy_from_user(&val, optval, sizeof(val)))
|
if (copy_from_sockptr(&val, optval, sizeof(val)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
lock_sock(sk);
|
lock_sock(sk);
|
||||||
|
@ -3795,7 +3796,7 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv
|
||||||
|
|
||||||
if (optlen < sizeof(val))
|
if (optlen < sizeof(val))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (copy_from_user(&val, optval, sizeof(val)))
|
if (copy_from_sockptr(&val, optval, sizeof(val)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
lock_sock(sk);
|
lock_sock(sk);
|
||||||
|
@ -3809,7 +3810,7 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv
|
||||||
|
|
||||||
if (optlen < sizeof(val))
|
if (optlen < sizeof(val))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (copy_from_user(&val, optval, sizeof(val)))
|
if (copy_from_sockptr(&val, optval, sizeof(val)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
lock_sock(sk);
|
lock_sock(sk);
|
||||||
|
@ -3825,7 +3826,7 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (optlen < sizeof(val))
|
if (optlen < sizeof(val))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (copy_from_user(&val, optval, sizeof(val)))
|
if (copy_from_sockptr(&val, optval, sizeof(val)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
lock_sock(sk);
|
lock_sock(sk);
|
||||||
|
@ -3844,7 +3845,7 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv
|
||||||
|
|
||||||
if (optlen != sizeof(val))
|
if (optlen != sizeof(val))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (copy_from_user(&val, optval, sizeof(val)))
|
if (copy_from_sockptr(&val, optval, sizeof(val)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
po->tp_tstamp = val;
|
po->tp_tstamp = val;
|
||||||
|
@ -3856,7 +3857,7 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv
|
||||||
|
|
||||||
if (optlen != sizeof(val))
|
if (optlen != sizeof(val))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (copy_from_user(&val, optval, sizeof(val)))
|
if (copy_from_sockptr(&val, optval, sizeof(val)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
return fanout_add(sk, val & 0xffff, val >> 16);
|
return fanout_add(sk, val & 0xffff, val >> 16);
|
||||||
|
@ -3874,7 +3875,7 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv
|
||||||
|
|
||||||
if (optlen != sizeof(val))
|
if (optlen != sizeof(val))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (copy_from_user(&val, optval, sizeof(val)))
|
if (copy_from_sockptr(&val, optval, sizeof(val)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
if (val < 0 || val > 1)
|
if (val < 0 || val > 1)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -3888,7 +3889,7 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv
|
||||||
|
|
||||||
if (optlen != sizeof(val))
|
if (optlen != sizeof(val))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (copy_from_user(&val, optval, sizeof(val)))
|
if (copy_from_sockptr(&val, optval, sizeof(val)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
lock_sock(sk);
|
lock_sock(sk);
|
||||||
|
@ -3907,7 +3908,7 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv
|
||||||
|
|
||||||
if (optlen != sizeof(val))
|
if (optlen != sizeof(val))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (copy_from_user(&val, optval, sizeof(val)))
|
if (copy_from_sockptr(&val, optval, sizeof(val)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
po->xmit = val ? packet_direct_xmit : dev_queue_xmit;
|
po->xmit = val ? packet_direct_xmit : dev_queue_xmit;
|
||||||
|
|
|
@ -975,7 +975,7 @@ static int pep_init(struct sock *sk)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pep_setsockopt(struct sock *sk, int level, int optname,
|
static int pep_setsockopt(struct sock *sk, int level, int optname,
|
||||||
char __user *optval, unsigned int optlen)
|
sockptr_t optval, unsigned int optlen)
|
||||||
{
|
{
|
||||||
struct pep_sock *pn = pep_sk(sk);
|
struct pep_sock *pn = pep_sk(sk);
|
||||||
int val = 0, err = 0;
|
int val = 0, err = 0;
|
||||||
|
@ -983,7 +983,7 @@ static int pep_setsockopt(struct sock *sk, int level, int optname,
|
||||||
if (level != SOL_PNPIPE)
|
if (level != SOL_PNPIPE)
|
||||||
return -ENOPROTOOPT;
|
return -ENOPROTOOPT;
|
||||||
if (optlen >= sizeof(int)) {
|
if (optlen >= sizeof(int)) {
|
||||||
if (get_user(val, (int __user *) optval))
|
if (copy_from_sockptr(&val, optval, sizeof(int)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -290,8 +290,7 @@ static int rds_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rds_cancel_sent_to(struct rds_sock *rs, char __user *optval,
|
static int rds_cancel_sent_to(struct rds_sock *rs, sockptr_t optval, int len)
|
||||||
int len)
|
|
||||||
{
|
{
|
||||||
struct sockaddr_in6 sin6;
|
struct sockaddr_in6 sin6;
|
||||||
struct sockaddr_in sin;
|
struct sockaddr_in sin;
|
||||||
|
@ -308,14 +307,15 @@ static int rds_cancel_sent_to(struct rds_sock *rs, char __user *optval,
|
||||||
goto out;
|
goto out;
|
||||||
} else if (len < sizeof(struct sockaddr_in6)) {
|
} else if (len < sizeof(struct sockaddr_in6)) {
|
||||||
/* Assume IPv4 */
|
/* Assume IPv4 */
|
||||||
if (copy_from_user(&sin, optval, sizeof(struct sockaddr_in))) {
|
if (copy_from_sockptr(&sin, optval,
|
||||||
|
sizeof(struct sockaddr_in))) {
|
||||||
ret = -EFAULT;
|
ret = -EFAULT;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
ipv6_addr_set_v4mapped(sin.sin_addr.s_addr, &sin6.sin6_addr);
|
ipv6_addr_set_v4mapped(sin.sin_addr.s_addr, &sin6.sin6_addr);
|
||||||
sin6.sin6_port = sin.sin_port;
|
sin6.sin6_port = sin.sin_port;
|
||||||
} else {
|
} else {
|
||||||
if (copy_from_user(&sin6, optval,
|
if (copy_from_sockptr(&sin6, optval,
|
||||||
sizeof(struct sockaddr_in6))) {
|
sizeof(struct sockaddr_in6))) {
|
||||||
ret = -EFAULT;
|
ret = -EFAULT;
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -327,21 +327,20 @@ out:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rds_set_bool_option(unsigned char *optvar, char __user *optval,
|
static int rds_set_bool_option(unsigned char *optvar, sockptr_t optval,
|
||||||
int optlen)
|
int optlen)
|
||||||
{
|
{
|
||||||
int value;
|
int value;
|
||||||
|
|
||||||
if (optlen < sizeof(int))
|
if (optlen < sizeof(int))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (get_user(value, (int __user *) optval))
|
if (copy_from_sockptr(&value, optval, sizeof(int)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
*optvar = !!value;
|
*optvar = !!value;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rds_cong_monitor(struct rds_sock *rs, char __user *optval,
|
static int rds_cong_monitor(struct rds_sock *rs, sockptr_t optval, int optlen)
|
||||||
int optlen)
|
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
@ -358,8 +357,7 @@ static int rds_cong_monitor(struct rds_sock *rs, char __user *optval,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rds_set_transport(struct rds_sock *rs, char __user *optval,
|
static int rds_set_transport(struct rds_sock *rs, sockptr_t optval, int optlen)
|
||||||
int optlen)
|
|
||||||
{
|
{
|
||||||
int t_type;
|
int t_type;
|
||||||
|
|
||||||
|
@ -369,7 +367,7 @@ static int rds_set_transport(struct rds_sock *rs, char __user *optval,
|
||||||
if (optlen != sizeof(int))
|
if (optlen != sizeof(int))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (copy_from_user(&t_type, (int __user *)optval, sizeof(t_type)))
|
if (copy_from_sockptr(&t_type, optval, sizeof(t_type)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
if (t_type < 0 || t_type >= RDS_TRANS_COUNT)
|
if (t_type < 0 || t_type >= RDS_TRANS_COUNT)
|
||||||
|
@ -380,7 +378,7 @@ static int rds_set_transport(struct rds_sock *rs, char __user *optval,
|
||||||
return rs->rs_transport ? 0 : -ENOPROTOOPT;
|
return rs->rs_transport ? 0 : -ENOPROTOOPT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rds_enable_recvtstamp(struct sock *sk, char __user *optval,
|
static int rds_enable_recvtstamp(struct sock *sk, sockptr_t optval,
|
||||||
int optlen, int optname)
|
int optlen, int optname)
|
||||||
{
|
{
|
||||||
int val, valbool;
|
int val, valbool;
|
||||||
|
@ -388,7 +386,7 @@ static int rds_enable_recvtstamp(struct sock *sk, char __user *optval,
|
||||||
if (optlen != sizeof(int))
|
if (optlen != sizeof(int))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
if (get_user(val, (int __user *)optval))
|
if (copy_from_sockptr(&val, optval, sizeof(int)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
valbool = val ? 1 : 0;
|
valbool = val ? 1 : 0;
|
||||||
|
@ -404,7 +402,7 @@ static int rds_enable_recvtstamp(struct sock *sk, char __user *optval,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rds_recv_track_latency(struct rds_sock *rs, char __user *optval,
|
static int rds_recv_track_latency(struct rds_sock *rs, sockptr_t optval,
|
||||||
int optlen)
|
int optlen)
|
||||||
{
|
{
|
||||||
struct rds_rx_trace_so trace;
|
struct rds_rx_trace_so trace;
|
||||||
|
@ -413,7 +411,7 @@ static int rds_recv_track_latency(struct rds_sock *rs, char __user *optval,
|
||||||
if (optlen != sizeof(struct rds_rx_trace_so))
|
if (optlen != sizeof(struct rds_rx_trace_so))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
if (copy_from_user(&trace, optval, sizeof(trace)))
|
if (copy_from_sockptr(&trace, optval, sizeof(trace)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
if (trace.rx_traces > RDS_MSG_RX_DGRAM_TRACE_MAX)
|
if (trace.rx_traces > RDS_MSG_RX_DGRAM_TRACE_MAX)
|
||||||
|
@ -432,7 +430,7 @@ static int rds_recv_track_latency(struct rds_sock *rs, char __user *optval,
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rds_setsockopt(struct socket *sock, int level, int optname,
|
static int rds_setsockopt(struct socket *sock, int level, int optname,
|
||||||
char __user *optval, unsigned int optlen)
|
sockptr_t optval, unsigned int optlen)
|
||||||
{
|
{
|
||||||
struct rds_sock *rs = rds_sk_to_rs(sock->sk);
|
struct rds_sock *rs = rds_sk_to_rs(sock->sk);
|
||||||
int ret;
|
int ret;
|
||||||
|
|
|
@ -353,21 +353,20 @@ out:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int rds_get_mr(struct rds_sock *rs, char __user *optval, int optlen)
|
int rds_get_mr(struct rds_sock *rs, sockptr_t optval, int optlen)
|
||||||
{
|
{
|
||||||
struct rds_get_mr_args args;
|
struct rds_get_mr_args args;
|
||||||
|
|
||||||
if (optlen != sizeof(struct rds_get_mr_args))
|
if (optlen != sizeof(struct rds_get_mr_args))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (copy_from_user(&args, (struct rds_get_mr_args __user *)optval,
|
if (copy_from_sockptr(&args, optval, sizeof(struct rds_get_mr_args)))
|
||||||
sizeof(struct rds_get_mr_args)))
|
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
return __rds_rdma_map(rs, &args, NULL, NULL, NULL);
|
return __rds_rdma_map(rs, &args, NULL, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
int rds_get_mr_for_dest(struct rds_sock *rs, char __user *optval, int optlen)
|
int rds_get_mr_for_dest(struct rds_sock *rs, sockptr_t optval, int optlen)
|
||||||
{
|
{
|
||||||
struct rds_get_mr_for_dest_args args;
|
struct rds_get_mr_for_dest_args args;
|
||||||
struct rds_get_mr_args new_args;
|
struct rds_get_mr_args new_args;
|
||||||
|
@ -375,7 +374,7 @@ int rds_get_mr_for_dest(struct rds_sock *rs, char __user *optval, int optlen)
|
||||||
if (optlen != sizeof(struct rds_get_mr_for_dest_args))
|
if (optlen != sizeof(struct rds_get_mr_for_dest_args))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (copy_from_user(&args, (struct rds_get_mr_for_dest_args __user *)optval,
|
if (copy_from_sockptr(&args, optval,
|
||||||
sizeof(struct rds_get_mr_for_dest_args)))
|
sizeof(struct rds_get_mr_for_dest_args)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
|
@ -394,7 +393,7 @@ int rds_get_mr_for_dest(struct rds_sock *rs, char __user *optval, int optlen)
|
||||||
/*
|
/*
|
||||||
* Free the MR indicated by the given R_Key
|
* Free the MR indicated by the given R_Key
|
||||||
*/
|
*/
|
||||||
int rds_free_mr(struct rds_sock *rs, char __user *optval, int optlen)
|
int rds_free_mr(struct rds_sock *rs, sockptr_t optval, int optlen)
|
||||||
{
|
{
|
||||||
struct rds_free_mr_args args;
|
struct rds_free_mr_args args;
|
||||||
struct rds_mr *mr;
|
struct rds_mr *mr;
|
||||||
|
@ -403,8 +402,7 @@ int rds_free_mr(struct rds_sock *rs, char __user *optval, int optlen)
|
||||||
if (optlen != sizeof(struct rds_free_mr_args))
|
if (optlen != sizeof(struct rds_free_mr_args))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (copy_from_user(&args, (struct rds_free_mr_args __user *)optval,
|
if (copy_from_sockptr(&args, optval, sizeof(struct rds_free_mr_args)))
|
||||||
sizeof(struct rds_free_mr_args)))
|
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
/* Special case - a null cookie means flush all unused MRs */
|
/* Special case - a null cookie means flush all unused MRs */
|
||||||
|
|
|
@ -924,9 +924,9 @@ int rds_send_pong(struct rds_conn_path *cp, __be16 dport);
|
||||||
|
|
||||||
/* rdma.c */
|
/* rdma.c */
|
||||||
void rds_rdma_unuse(struct rds_sock *rs, u32 r_key, int force);
|
void rds_rdma_unuse(struct rds_sock *rs, u32 r_key, int force);
|
||||||
int rds_get_mr(struct rds_sock *rs, char __user *optval, int optlen);
|
int rds_get_mr(struct rds_sock *rs, sockptr_t optval, int optlen);
|
||||||
int rds_get_mr_for_dest(struct rds_sock *rs, char __user *optval, int optlen);
|
int rds_get_mr_for_dest(struct rds_sock *rs, sockptr_t optval, int optlen);
|
||||||
int rds_free_mr(struct rds_sock *rs, char __user *optval, int optlen);
|
int rds_free_mr(struct rds_sock *rs, sockptr_t optval, int optlen);
|
||||||
void rds_rdma_drop_keys(struct rds_sock *rs);
|
void rds_rdma_drop_keys(struct rds_sock *rs);
|
||||||
int rds_rdma_extra_size(struct rds_rdma_args *args,
|
int rds_rdma_extra_size(struct rds_rdma_args *args,
|
||||||
struct rds_iov_vector *iov);
|
struct rds_iov_vector *iov);
|
||||||
|
|
|
@ -365,7 +365,7 @@ void rose_destroy_socket(struct sock *sk)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int rose_setsockopt(struct socket *sock, int level, int optname,
|
static int rose_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 sock *sk = sock->sk;
|
||||||
struct rose_sock *rose = rose_sk(sk);
|
struct rose_sock *rose = rose_sk(sk);
|
||||||
|
@ -377,7 +377,7 @@ static int rose_setsockopt(struct socket *sock, int level, int optname,
|
||||||
if (optlen < sizeof(int))
|
if (optlen < sizeof(int))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (get_user(opt, (int __user *)optval))
|
if (copy_from_sockptr(&opt, optval, sizeof(int)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
switch (optname) {
|
switch (optname) {
|
||||||
|
|
|
@ -588,7 +588,7 @@ EXPORT_SYMBOL(rxrpc_sock_set_min_security_level);
|
||||||
* set RxRPC socket options
|
* set RxRPC socket options
|
||||||
*/
|
*/
|
||||||
static int rxrpc_setsockopt(struct socket *sock, int level, int optname,
|
static int rxrpc_setsockopt(struct socket *sock, int level, int optname,
|
||||||
char __user *optval, unsigned int optlen)
|
sockptr_t optval, unsigned int optlen)
|
||||||
{
|
{
|
||||||
struct rxrpc_sock *rx = rxrpc_sk(sock->sk);
|
struct rxrpc_sock *rx = rxrpc_sk(sock->sk);
|
||||||
unsigned int min_sec_level;
|
unsigned int min_sec_level;
|
||||||
|
@ -639,8 +639,8 @@ static int rxrpc_setsockopt(struct socket *sock, int level, int optname,
|
||||||
ret = -EISCONN;
|
ret = -EISCONN;
|
||||||
if (rx->sk.sk_state != RXRPC_UNBOUND)
|
if (rx->sk.sk_state != RXRPC_UNBOUND)
|
||||||
goto error;
|
goto error;
|
||||||
ret = get_user(min_sec_level,
|
ret = copy_from_sockptr(&min_sec_level, optval,
|
||||||
(unsigned int __user *) optval);
|
sizeof(unsigned int));
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto error;
|
goto error;
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
|
@ -658,7 +658,7 @@ static int rxrpc_setsockopt(struct socket *sock, int level, int optname,
|
||||||
if (rx->sk.sk_state != RXRPC_SERVER_BOUND2)
|
if (rx->sk.sk_state != RXRPC_SERVER_BOUND2)
|
||||||
goto error;
|
goto error;
|
||||||
ret = -EFAULT;
|
ret = -EFAULT;
|
||||||
if (copy_from_user(service_upgrade, optval,
|
if (copy_from_sockptr(service_upgrade, optval,
|
||||||
sizeof(service_upgrade)) != 0)
|
sizeof(service_upgrade)) != 0)
|
||||||
goto error;
|
goto error;
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
|
|
|
@ -909,8 +909,8 @@ extern const struct rxrpc_security rxrpc_no_security;
|
||||||
extern struct key_type key_type_rxrpc;
|
extern struct key_type key_type_rxrpc;
|
||||||
extern struct key_type key_type_rxrpc_s;
|
extern struct key_type key_type_rxrpc_s;
|
||||||
|
|
||||||
int rxrpc_request_key(struct rxrpc_sock *, char __user *, int);
|
int rxrpc_request_key(struct rxrpc_sock *, sockptr_t , int);
|
||||||
int rxrpc_server_keyring(struct rxrpc_sock *, char __user *, int);
|
int rxrpc_server_keyring(struct rxrpc_sock *, sockptr_t, int);
|
||||||
int rxrpc_get_server_data_key(struct rxrpc_connection *, const void *, time64_t,
|
int rxrpc_get_server_data_key(struct rxrpc_connection *, const void *, time64_t,
|
||||||
u32);
|
u32);
|
||||||
|
|
||||||
|
|
|
@ -896,7 +896,7 @@ static void rxrpc_describe(const struct key *key, struct seq_file *m)
|
||||||
/*
|
/*
|
||||||
* grab the security key for a socket
|
* grab the security key for a socket
|
||||||
*/
|
*/
|
||||||
int rxrpc_request_key(struct rxrpc_sock *rx, char __user *optval, int optlen)
|
int rxrpc_request_key(struct rxrpc_sock *rx, sockptr_t optval, int optlen)
|
||||||
{
|
{
|
||||||
struct key *key;
|
struct key *key;
|
||||||
char *description;
|
char *description;
|
||||||
|
@ -906,7 +906,7 @@ int rxrpc_request_key(struct rxrpc_sock *rx, char __user *optval, int optlen)
|
||||||
if (optlen <= 0 || optlen > PAGE_SIZE - 1)
|
if (optlen <= 0 || optlen > PAGE_SIZE - 1)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
description = memdup_user_nul(optval, optlen);
|
description = memdup_sockptr_nul(optval, optlen);
|
||||||
if (IS_ERR(description))
|
if (IS_ERR(description))
|
||||||
return PTR_ERR(description);
|
return PTR_ERR(description);
|
||||||
|
|
||||||
|
@ -926,8 +926,7 @@ int rxrpc_request_key(struct rxrpc_sock *rx, char __user *optval, int optlen)
|
||||||
/*
|
/*
|
||||||
* grab the security keyring for a server socket
|
* grab the security keyring for a server socket
|
||||||
*/
|
*/
|
||||||
int rxrpc_server_keyring(struct rxrpc_sock *rx, char __user *optval,
|
int rxrpc_server_keyring(struct rxrpc_sock *rx, sockptr_t optval, int optlen)
|
||||||
int optlen)
|
|
||||||
{
|
{
|
||||||
struct key *key;
|
struct key *key;
|
||||||
char *description;
|
char *description;
|
||||||
|
@ -937,7 +936,7 @@ int rxrpc_server_keyring(struct rxrpc_sock *rx, char __user *optval,
|
||||||
if (optlen <= 0 || optlen > PAGE_SIZE - 1)
|
if (optlen <= 0 || optlen > PAGE_SIZE - 1)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
description = memdup_user_nul(optval, optlen);
|
description = memdup_sockptr_nul(optval, optlen);
|
||||||
if (IS_ERR(description))
|
if (IS_ERR(description))
|
||||||
return PTR_ERR(description);
|
return PTR_ERR(description);
|
||||||
|
|
||||||
|
|
|
@ -4429,7 +4429,7 @@ out:
|
||||||
* optlen - the size of the buffer.
|
* optlen - the size of the buffer.
|
||||||
*/
|
*/
|
||||||
static int sctp_setsockopt(struct sock *sk, int level, int optname,
|
static int sctp_setsockopt(struct sock *sk, int level, int optname,
|
||||||
char __user *optval, unsigned int optlen)
|
sockptr_t optval, unsigned int optlen)
|
||||||
{
|
{
|
||||||
void *kopt = NULL;
|
void *kopt = NULL;
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
|
@ -4449,7 +4449,7 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (optlen > 0) {
|
if (optlen > 0) {
|
||||||
kopt = memdup_user(optval, optlen);
|
kopt = memdup_sockptr(optval, optlen);
|
||||||
if (IS_ERR(kopt))
|
if (IS_ERR(kopt))
|
||||||
return PTR_ERR(kopt);
|
return PTR_ERR(kopt);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1731,7 +1731,7 @@ out:
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smc_setsockopt(struct socket *sock, int level, int optname,
|
static int smc_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 sock *sk = sock->sk;
|
||||||
struct smc_sock *smc;
|
struct smc_sock *smc;
|
||||||
|
@ -1754,7 +1754,7 @@ static int smc_setsockopt(struct socket *sock, int level, int optname,
|
||||||
|
|
||||||
if (optlen < sizeof(int))
|
if (optlen < sizeof(int))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (get_user(val, (int __user *)optval))
|
if (copy_from_sockptr(&val, optval, sizeof(int)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
lock_sock(sk);
|
lock_sock(sk);
|
||||||
|
|
23
net/socket.c
23
net/socket.c
|
@ -2094,10 +2094,10 @@ static bool sock_use_custom_sol_socket(const struct socket *sock)
|
||||||
* Set a socket option. Because we don't know the option lengths we have
|
* Set a socket option. Because we don't know the option lengths we have
|
||||||
* to pass the user mode parameter for the protocols to sort out.
|
* to pass the user mode parameter for the protocols to sort out.
|
||||||
*/
|
*/
|
||||||
int __sys_setsockopt(int fd, int level, int optname, char __user *optval,
|
int __sys_setsockopt(int fd, int level, int optname, char __user *user_optval,
|
||||||
int optlen)
|
int optlen)
|
||||||
{
|
{
|
||||||
mm_segment_t oldfs = get_fs();
|
sockptr_t optval = USER_SOCKPTR(user_optval);
|
||||||
char *kernel_optval = NULL;
|
char *kernel_optval = NULL;
|
||||||
int err, fput_needed;
|
int err, fput_needed;
|
||||||
struct socket *sock;
|
struct socket *sock;
|
||||||
|
@ -2115,7 +2115,7 @@ int __sys_setsockopt(int fd, int level, int optname, char __user *optval,
|
||||||
|
|
||||||
if (!in_compat_syscall())
|
if (!in_compat_syscall())
|
||||||
err = BPF_CGROUP_RUN_PROG_SETSOCKOPT(sock->sk, &level, &optname,
|
err = BPF_CGROUP_RUN_PROG_SETSOCKOPT(sock->sk, &level, &optname,
|
||||||
optval, &optlen,
|
user_optval, &optlen,
|
||||||
&kernel_optval);
|
&kernel_optval);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto out_put;
|
goto out_put;
|
||||||
|
@ -2124,25 +2124,16 @@ int __sys_setsockopt(int fd, int level, int optname, char __user *optval,
|
||||||
goto out_put;
|
goto out_put;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kernel_optval) {
|
if (kernel_optval)
|
||||||
set_fs(KERNEL_DS);
|
optval = KERNEL_SOCKPTR(kernel_optval);
|
||||||
optval = (char __user __force *)kernel_optval;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (level == SOL_SOCKET && !sock_use_custom_sol_socket(sock))
|
if (level == SOL_SOCKET && !sock_use_custom_sol_socket(sock))
|
||||||
err = sock_setsockopt(sock, level, optname,
|
err = sock_setsockopt(sock, level, optname, optval, optlen);
|
||||||
USER_SOCKPTR(optval), optlen);
|
|
||||||
else if (unlikely(!sock->ops->setsockopt))
|
else if (unlikely(!sock->ops->setsockopt))
|
||||||
err = -EOPNOTSUPP;
|
err = -EOPNOTSUPP;
|
||||||
else
|
else
|
||||||
err = sock->ops->setsockopt(sock, level, optname, optval,
|
err = sock->ops->setsockopt(sock, level, optname, optval,
|
||||||
optlen);
|
optlen);
|
||||||
|
kfree(kernel_optval);
|
||||||
if (kernel_optval) {
|
|
||||||
set_fs(oldfs);
|
|
||||||
kfree(kernel_optval);
|
|
||||||
}
|
|
||||||
|
|
||||||
out_put:
|
out_put:
|
||||||
fput_light(sock->file, fput_needed);
|
fput_light(sock->file, fput_needed);
|
||||||
return err;
|
return err;
|
||||||
|
|
|
@ -3103,7 +3103,7 @@ static int tipc_sk_leave(struct tipc_sock *tsk)
|
||||||
* Returns 0 on success, errno otherwise
|
* Returns 0 on success, errno otherwise
|
||||||
*/
|
*/
|
||||||
static int tipc_setsockopt(struct socket *sock, int lvl, int opt,
|
static int tipc_setsockopt(struct socket *sock, int lvl, int opt,
|
||||||
char __user *ov, unsigned int ol)
|
sockptr_t ov, unsigned int ol)
|
||||||
{
|
{
|
||||||
struct sock *sk = sock->sk;
|
struct sock *sk = sock->sk;
|
||||||
struct tipc_sock *tsk = tipc_sk(sk);
|
struct tipc_sock *tsk = tipc_sk(sk);
|
||||||
|
@ -3124,17 +3124,17 @@ static int tipc_setsockopt(struct socket *sock, int lvl, int opt,
|
||||||
case TIPC_NODELAY:
|
case TIPC_NODELAY:
|
||||||
if (ol < sizeof(value))
|
if (ol < sizeof(value))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (get_user(value, (u32 __user *)ov))
|
if (copy_from_sockptr(&value, ov, sizeof(u32)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
break;
|
break;
|
||||||
case TIPC_GROUP_JOIN:
|
case TIPC_GROUP_JOIN:
|
||||||
if (ol < sizeof(mreq))
|
if (ol < sizeof(mreq))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (copy_from_user(&mreq, ov, sizeof(mreq)))
|
if (copy_from_sockptr(&mreq, ov, sizeof(mreq)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (ov || ol)
|
if (!sockptr_is_null(ov) || ol)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -450,7 +450,7 @@ static int tls_getsockopt(struct sock *sk, int level, int optname,
|
||||||
return do_tls_getsockopt(sk, optname, optval, optlen);
|
return do_tls_getsockopt(sk, optname, optval, optlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int do_tls_setsockopt_conf(struct sock *sk, char __user *optval,
|
static int do_tls_setsockopt_conf(struct sock *sk, sockptr_t optval,
|
||||||
unsigned int optlen, int tx)
|
unsigned int optlen, int tx)
|
||||||
{
|
{
|
||||||
struct tls_crypto_info *crypto_info;
|
struct tls_crypto_info *crypto_info;
|
||||||
|
@ -460,7 +460,7 @@ static int do_tls_setsockopt_conf(struct sock *sk, char __user *optval,
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
int conf;
|
int conf;
|
||||||
|
|
||||||
if (!optval || (optlen < sizeof(*crypto_info))) {
|
if (sockptr_is_null(optval) || (optlen < sizeof(*crypto_info))) {
|
||||||
rc = -EINVAL;
|
rc = -EINVAL;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -479,7 +479,7 @@ static int do_tls_setsockopt_conf(struct sock *sk, char __user *optval,
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = copy_from_user(crypto_info, optval, sizeof(*crypto_info));
|
rc = copy_from_sockptr(crypto_info, optval, sizeof(*crypto_info));
|
||||||
if (rc) {
|
if (rc) {
|
||||||
rc = -EFAULT;
|
rc = -EFAULT;
|
||||||
goto err_crypto_info;
|
goto err_crypto_info;
|
||||||
|
@ -522,8 +522,9 @@ static int do_tls_setsockopt_conf(struct sock *sk, char __user *optval,
|
||||||
goto err_crypto_info;
|
goto err_crypto_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = copy_from_user(crypto_info + 1, optval + sizeof(*crypto_info),
|
sockptr_advance(optval, sizeof(*crypto_info));
|
||||||
optlen - sizeof(*crypto_info));
|
rc = copy_from_sockptr(crypto_info + 1, optval,
|
||||||
|
optlen - sizeof(*crypto_info));
|
||||||
if (rc) {
|
if (rc) {
|
||||||
rc = -EFAULT;
|
rc = -EFAULT;
|
||||||
goto err_crypto_info;
|
goto err_crypto_info;
|
||||||
|
@ -579,8 +580,8 @@ out:
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int do_tls_setsockopt(struct sock *sk, int optname,
|
static int do_tls_setsockopt(struct sock *sk, int optname, sockptr_t optval,
|
||||||
char __user *optval, unsigned int optlen)
|
unsigned int optlen)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
|
@ -600,7 +601,7 @@ static int do_tls_setsockopt(struct sock *sk, int optname,
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tls_setsockopt(struct sock *sk, int level, int optname,
|
static int tls_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);
|
struct tls_context *ctx = tls_get_ctx(sk);
|
||||||
|
|
||||||
|
|
|
@ -1517,7 +1517,7 @@ static void vsock_update_buffer_size(struct vsock_sock *vsk,
|
||||||
static int vsock_stream_setsockopt(struct socket *sock,
|
static int vsock_stream_setsockopt(struct socket *sock,
|
||||||
int level,
|
int level,
|
||||||
int optname,
|
int optname,
|
||||||
char __user *optval,
|
sockptr_t optval,
|
||||||
unsigned int optlen)
|
unsigned int optlen)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
@ -1535,7 +1535,7 @@ static int vsock_stream_setsockopt(struct socket *sock,
|
||||||
err = -EINVAL; \
|
err = -EINVAL; \
|
||||||
goto exit; \
|
goto exit; \
|
||||||
} \
|
} \
|
||||||
if (copy_from_user(&_v, optval, sizeof(_v)) != 0) { \
|
if (copy_from_sockptr(&_v, optval, sizeof(_v)) != 0) { \
|
||||||
err = -EFAULT; \
|
err = -EFAULT; \
|
||||||
goto exit; \
|
goto exit; \
|
||||||
} \
|
} \
|
||||||
|
|
|
@ -431,7 +431,7 @@ void x25_destroy_socket_from_timer(struct sock *sk)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int x25_setsockopt(struct socket *sock, int level, int optname,
|
static int x25_setsockopt(struct socket *sock, int level, int optname,
|
||||||
char __user *optval, unsigned int optlen)
|
sockptr_t optval, unsigned int optlen)
|
||||||
{
|
{
|
||||||
int opt;
|
int opt;
|
||||||
struct sock *sk = sock->sk;
|
struct sock *sk = sock->sk;
|
||||||
|
@ -445,7 +445,7 @@ static int x25_setsockopt(struct socket *sock, int level, int optname,
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
rc = -EFAULT;
|
rc = -EFAULT;
|
||||||
if (get_user(opt, (int __user *)optval))
|
if (copy_from_sockptr(&opt, optval, sizeof(int)))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (opt)
|
if (opt)
|
||||||
|
|
|
@ -702,7 +702,7 @@ struct xdp_umem_reg_v1 {
|
||||||
};
|
};
|
||||||
|
|
||||||
static int xsk_setsockopt(struct socket *sock, int level, int optname,
|
static int xsk_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 sock *sk = sock->sk;
|
||||||
struct xdp_sock *xs = xdp_sk(sk);
|
struct xdp_sock *xs = xdp_sk(sk);
|
||||||
|
@ -720,7 +720,7 @@ static int xsk_setsockopt(struct socket *sock, int level, int optname,
|
||||||
|
|
||||||
if (optlen < sizeof(entries))
|
if (optlen < sizeof(entries))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (copy_from_user(&entries, optval, sizeof(entries)))
|
if (copy_from_sockptr(&entries, optval, sizeof(entries)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
mutex_lock(&xs->mutex);
|
mutex_lock(&xs->mutex);
|
||||||
|
@ -747,7 +747,7 @@ static int xsk_setsockopt(struct socket *sock, int level, int optname,
|
||||||
else if (optlen < sizeof(mr))
|
else if (optlen < sizeof(mr))
|
||||||
mr_size = sizeof(struct xdp_umem_reg_v1);
|
mr_size = sizeof(struct xdp_umem_reg_v1);
|
||||||
|
|
||||||
if (copy_from_user(&mr, optval, mr_size))
|
if (copy_from_sockptr(&mr, optval, mr_size))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
mutex_lock(&xs->mutex);
|
mutex_lock(&xs->mutex);
|
||||||
|
@ -774,7 +774,7 @@ static int xsk_setsockopt(struct socket *sock, int level, int optname,
|
||||||
struct xsk_queue **q;
|
struct xsk_queue **q;
|
||||||
int entries;
|
int entries;
|
||||||
|
|
||||||
if (copy_from_user(&entries, optval, sizeof(entries)))
|
if (copy_from_sockptr(&entries, optval, sizeof(entries)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
mutex_lock(&xs->mutex);
|
mutex_lock(&xs->mutex);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue