mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-12-29 09:16:33 +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
@ -197,8 +197,7 @@ static int alg_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
|
|||||||
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 @@ static int alg_setkey(struct sock *sk, char __user *ukey,
|
|||||||
}
|
}
|
||||||
|
|
||||||
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 @@ static int do_chtls_setsockopt(struct sock *sk, int optname,
|
|||||||
}
|
}
|
||||||
|
|
||||||
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 @@ static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg,
|
|||||||
}
|
}
|
||||||
|
|
||||||
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 @@ static int caif_stream_sendmsg(struct socket *sock, struct msghdr *msg,
|
|||||||
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 @@ int dccp_ioctl(struct sock *sk, int cmd, unsigned long arg)
|
|||||||
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 @@ static int dn_shutdown(struct socket *sock, int how)
|
|||||||
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 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
|
|||||||
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 @@ static int rawv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
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 @@ static int llcp_sock_listen(struct socket *sock, int backlog)
|
|||||||
}
|
}
|
||||||
|
|
||||||
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 @@ static int rds_cancel_sent_to(struct rds_sock *rs, char __user *optval,
|
|||||||
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 @@ static int __rds_rdma_map(struct rds_sock *rs, struct rds_get_mr_args *args,
|
|||||||
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 @@ static int sctp_setsockopt_pf_expose(struct sock *sk,
|
|||||||
* 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 @@ static int smc_shutdown(struct socket *sock, int how)
|
|||||||
}
|
}
|
||||||
|
|
||||||
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 @@ static int do_tls_setsockopt_conf(struct sock *sk, char __user *optval,
|
|||||||
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…
Reference in New Issue
Block a user