summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/linux/sockptr.h26
-rw-r--r--net/ipv4/bpfilter/sockopt.c14
-rw-r--r--net/socket.c6
3 files changed, 9 insertions, 37 deletions
diff --git a/include/linux/sockptr.h b/include/linux/sockptr.h
index 96840def9d69..ea193414298b 100644
--- a/include/linux/sockptr.h
+++ b/include/linux/sockptr.h
@@ -8,26 +8,9 @@
#ifndef _LINUX_SOCKPTR_H
#define _LINUX_SOCKPTR_H
-#include <linux/compiler.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
-#ifdef CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE
-typedef union {
- void *kernel;
- void __user *user;
-} sockptr_t;
-
-static inline bool sockptr_is_kernel(sockptr_t sockptr)
-{
- return (unsigned long)sockptr.kernel >= TASK_SIZE;
-}
-
-static inline sockptr_t KERNEL_SOCKPTR(void *p)
-{
- return (sockptr_t) { .kernel = p };
-}
-#else /* CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE */
typedef struct {
union {
void *kernel;
@@ -45,15 +28,10 @@ static inline sockptr_t KERNEL_SOCKPTR(void *p)
{
return (sockptr_t) { .kernel = p, .is_kernel = true };
}
-#endif /* CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE */
-static inline int __must_check init_user_sockptr(sockptr_t *sp, void __user *p,
- size_t size)
+static inline sockptr_t USER_SOCKPTR(void __user *p)
{
- if (!access_ok(p, size))
- return -EFAULT;
- *sp = (sockptr_t) { .user = p };
- return 0;
+ return (sockptr_t) { .user = p };
}
static inline bool sockptr_is_null(sockptr_t sockptr)
diff --git a/net/ipv4/bpfilter/sockopt.c b/net/ipv4/bpfilter/sockopt.c
index 545b2640f019..1b34cb9a7708 100644
--- a/net/ipv4/bpfilter/sockopt.c
+++ b/net/ipv4/bpfilter/sockopt.c
@@ -57,18 +57,16 @@ int bpfilter_ip_set_sockopt(struct sock *sk, int optname, sockptr_t optval,
return bpfilter_mbox_request(sk, optname, optval, optlen, true);
}
-int bpfilter_ip_get_sockopt(struct sock *sk, int optname,
- char __user *user_optval, int __user *optlen)
+int bpfilter_ip_get_sockopt(struct sock *sk, int optname, char __user *optval,
+ int __user *optlen)
{
- sockptr_t optval;
- int err, len;
+ int len;
if (get_user(len, optlen))
return -EFAULT;
- err = init_user_sockptr(&optval, user_optval, len);
- if (err)
- return err;
- return bpfilter_mbox_request(sk, optname, optval, len, false);
+
+ return bpfilter_mbox_request(sk, optname, USER_SOCKPTR(optval), len,
+ false);
}
static int __init bpfilter_sockopt_init(void)
diff --git a/net/socket.c b/net/socket.c
index f4d5998bdcba..dbbe8ea7d395 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -2095,7 +2095,7 @@ static bool sock_use_custom_sol_socket(const struct socket *sock)
int __sys_setsockopt(int fd, int level, int optname, char __user *user_optval,
int optlen)
{
- sockptr_t optval;
+ sockptr_t optval = USER_SOCKPTR(user_optval);
char *kernel_optval = NULL;
int err, fput_needed;
struct socket *sock;
@@ -2103,10 +2103,6 @@ int __sys_setsockopt(int fd, int level, int optname, char __user *user_optval,
if (optlen < 0)
return -EINVAL;
- err = init_user_sockptr(&optval, user_optval, optlen);
- if (err)
- return err;
-
sock = sockfd_lookup_light(fd, &err, &fput_needed);
if (!sock)
return err;