* [PATCH 01/22] net/atm: remove the atmdev_ops {get,set}sockopt methods
2020-07-17 6:23 sockopt cleanups Christoph Hellwig
@ 2020-07-17 6:23 ` Christoph Hellwig
2020-07-17 6:23 ` [PATCH 02/22] net: streamline __sys_setsockopt Christoph Hellwig
` (21 subsequent siblings)
22 siblings, 0 replies; 27+ messages in thread
From: Christoph Hellwig @ 2020-07-17 6:23 UTC (permalink / raw)
To: David S. Miller
Cc: Alexei Starovoitov, Daniel Borkmann, Chas Williams,
Pablo Neira Ayuso, Jozsef Kadlecsik, Florian Westphal,
Alexey Kuznetsov, Hideaki YOSHIFUJI, linux-kernel, netdev, bpf,
netfilter-devel, linux-sctp, linux-arch, linux-bluetooth, bridge,
linux-can, dccp, linux-wpan, mptcp
All implementations of these two methods are dummies that always
return -EINVAL.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
drivers/atm/eni.c | 17 -----------------
drivers/atm/firestream.c | 2 --
drivers/atm/fore200e.c | 27 ---------------------------
drivers/atm/horizon.c | 40 ----------------------------------------
drivers/atm/iphase.c | 16 ----------------
drivers/atm/lanai.c | 2 --
drivers/atm/solos-pci.c | 2 --
drivers/atm/zatm.c | 16 ----------------
include/linux/atmdev.h | 9 ---------
net/atm/common.c | 14 ++------------
10 files changed, 2 insertions(+), 143 deletions(-)
diff --git a/drivers/atm/eni.c b/drivers/atm/eni.c
index 17d47ad03ab79e..b3d8e00e76716c 100644
--- a/drivers/atm/eni.c
+++ b/drivers/atm/eni.c
@@ -2027,21 +2027,6 @@ static int eni_ioctl(struct atm_dev *dev,unsigned int cmd,void __user *arg)
return dev->phy->ioctl(dev,cmd,arg);
}
-
-static int eni_getsockopt(struct atm_vcc *vcc,int level,int optname,
- void __user *optval,int optlen)
-{
- return -EINVAL;
-}
-
-
-static int eni_setsockopt(struct atm_vcc *vcc,int level,int optname,
- void __user *optval,unsigned int optlen)
-{
- return -EINVAL;
-}
-
-
static int eni_send(struct atm_vcc *vcc,struct sk_buff *skb)
{
enum enq_res res;
@@ -2215,8 +2200,6 @@ static const struct atmdev_ops ops = {
.open = eni_open,
.close = eni_close,
.ioctl = eni_ioctl,
- .getsockopt = eni_getsockopt,
- .setsockopt = eni_setsockopt,
.send = eni_send,
.phy_put = eni_phy_put,
.phy_get = eni_phy_get,
diff --git a/drivers/atm/firestream.c b/drivers/atm/firestream.c
index cc87004d5e2d62..2ca9ec80273429 100644
--- a/drivers/atm/firestream.c
+++ b/drivers/atm/firestream.c
@@ -1277,8 +1277,6 @@ static const struct atmdev_ops ops = {
.send = fs_send,
.owner = THIS_MODULE,
/* ioctl: fs_ioctl, */
- /* getsockopt: fs_getsockopt, */
- /* setsockopt: fs_setsockopt, */
/* change_qos: fs_change_qos, */
/* For now implement these internally here... */
diff --git a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c
index f4ad7ce25ae8d1..a81bc49c14acc6 100644
--- a/drivers/atm/fore200e.c
+++ b/drivers/atm/fore200e.c
@@ -1710,31 +1710,6 @@ fore200e_getstats(struct fore200e* fore200e)
return 0;
}
-
-static int
-fore200e_getsockopt(struct atm_vcc* vcc, int level, int optname, void __user *optval, int optlen)
-{
- /* struct fore200e* fore200e = FORE200E_DEV(vcc->dev); */
-
- DPRINTK(2, "getsockopt %d.%d.%d, level = %d, optname = 0x%x, optval = 0x%p, optlen = %d\n",
- vcc->itf, vcc->vpi, vcc->vci, level, optname, optval, optlen);
-
- return -EINVAL;
-}
-
-
-static int
-fore200e_setsockopt(struct atm_vcc* vcc, int level, int optname, void __user *optval, unsigned int optlen)
-{
- /* struct fore200e* fore200e = FORE200E_DEV(vcc->dev); */
-
- DPRINTK(2, "setsockopt %d.%d.%d, level = %d, optname = 0x%x, optval = 0x%p, optlen = %d\n",
- vcc->itf, vcc->vpi, vcc->vci, level, optname, optval, optlen);
-
- return -EINVAL;
-}
-
-
#if 0 /* currently unused */
static int
fore200e_get_oc3(struct fore200e* fore200e, struct oc3_regs* regs)
@@ -3026,8 +3001,6 @@ static const struct atmdev_ops fore200e_ops = {
.open = fore200e_open,
.close = fore200e_close,
.ioctl = fore200e_ioctl,
- .getsockopt = fore200e_getsockopt,
- .setsockopt = fore200e_setsockopt,
.send = fore200e_send,
.change_qos = fore200e_change_qos,
.proc_read = fore200e_proc_read,
diff --git a/drivers/atm/horizon.c b/drivers/atm/horizon.c
index e5da51f907a25d..4f2951cbe69c08 100644
--- a/drivers/atm/horizon.c
+++ b/drivers/atm/horizon.c
@@ -2527,46 +2527,6 @@ static void hrz_close (struct atm_vcc * atm_vcc) {
clear_bit(ATM_VF_ADDR,&atm_vcc->flags);
}
-#if 0
-static int hrz_getsockopt (struct atm_vcc * atm_vcc, int level, int optname,
- void *optval, int optlen) {
- hrz_dev * dev = HRZ_DEV(atm_vcc->dev);
- PRINTD (DBG_FLOW|DBG_VCC, "hrz_getsockopt");
- switch (level) {
- case SOL_SOCKET:
- switch (optname) {
-// case SO_BCTXOPT:
-// break;
-// case SO_BCRXOPT:
-// break;
- default:
- return -ENOPROTOOPT;
- };
- break;
- }
- return -EINVAL;
-}
-
-static int hrz_setsockopt (struct atm_vcc * atm_vcc, int level, int optname,
- void *optval, unsigned int optlen) {
- hrz_dev * dev = HRZ_DEV(atm_vcc->dev);
- PRINTD (DBG_FLOW|DBG_VCC, "hrz_setsockopt");
- switch (level) {
- case SOL_SOCKET:
- switch (optname) {
-// case SO_BCTXOPT:
-// break;
-// case SO_BCRXOPT:
-// break;
- default:
- return -ENOPROTOOPT;
- };
- break;
- }
- return -EINVAL;
-}
-#endif
-
#if 0
static int hrz_ioctl (struct atm_dev * atm_dev, unsigned int cmd, void *arg) {
hrz_dev * dev = HRZ_DEV(atm_dev);
diff --git a/drivers/atm/iphase.c b/drivers/atm/iphase.c
index 8c7a996d1f16cf..eef637fd90b323 100644
--- a/drivers/atm/iphase.c
+++ b/drivers/atm/iphase.c
@@ -2880,20 +2880,6 @@ static int ia_ioctl(struct atm_dev *dev, unsigned int cmd, void __user *arg)
return 0;
}
-static int ia_getsockopt(struct atm_vcc *vcc, int level, int optname,
- void __user *optval, int optlen)
-{
- IF_EVENT(printk(">ia_getsockopt\n");)
- return -EINVAL;
-}
-
-static int ia_setsockopt(struct atm_vcc *vcc, int level, int optname,
- void __user *optval, unsigned int optlen)
-{
- IF_EVENT(printk(">ia_setsockopt\n");)
- return -EINVAL;
-}
-
static int ia_pkt_tx (struct atm_vcc *vcc, struct sk_buff *skb) {
IADEV *iadev;
struct dle *wr_ptr;
@@ -3164,8 +3150,6 @@ static const struct atmdev_ops ops = {
.open = ia_open,
.close = ia_close,
.ioctl = ia_ioctl,
- .getsockopt = ia_getsockopt,
- .setsockopt = ia_setsockopt,
.send = ia_send,
.phy_put = ia_phy_put,
.phy_get = ia_phy_get,
diff --git a/drivers/atm/lanai.c b/drivers/atm/lanai.c
index 645a6bc1df8886..986c1313694c66 100644
--- a/drivers/atm/lanai.c
+++ b/drivers/atm/lanai.c
@@ -2537,8 +2537,6 @@ static const struct atmdev_ops ops = {
.dev_close = lanai_dev_close,
.open = lanai_open,
.close = lanai_close,
- .getsockopt = NULL,
- .setsockopt = NULL,
.send = lanai_send,
.phy_put = NULL,
.phy_get = NULL,
diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c
index b7646ae55942e6..94fbc3abe60e6a 100644
--- a/drivers/atm/solos-pci.c
+++ b/drivers/atm/solos-pci.c
@@ -1179,8 +1179,6 @@ static const struct atmdev_ops fpga_ops = {
.open = popen,
.close = pclose,
.ioctl = NULL,
- .getsockopt = NULL,
- .setsockopt = NULL,
.send = psend,
.send_oam = NULL,
.phy_put = NULL,
diff --git a/drivers/atm/zatm.c b/drivers/atm/zatm.c
index 57f97b95a4531c..2788b985edbe48 100644
--- a/drivers/atm/zatm.c
+++ b/drivers/atm/zatm.c
@@ -1515,20 +1515,6 @@ static int zatm_ioctl(struct atm_dev *dev,unsigned int cmd,void __user *arg)
}
}
-
-static int zatm_getsockopt(struct atm_vcc *vcc,int level,int optname,
- void __user *optval,int optlen)
-{
- return -EINVAL;
-}
-
-
-static int zatm_setsockopt(struct atm_vcc *vcc,int level,int optname,
- void __user *optval,unsigned int optlen)
-{
- return -EINVAL;
-}
-
static int zatm_send(struct atm_vcc *vcc,struct sk_buff *skb)
{
int error;
@@ -1582,8 +1568,6 @@ static const struct atmdev_ops ops = {
.open = zatm_open,
.close = zatm_close,
.ioctl = zatm_ioctl,
- .getsockopt = zatm_getsockopt,
- .setsockopt = zatm_setsockopt,
.send = zatm_send,
.phy_put = zatm_phy_put,
.phy_get = zatm_phy_get,
diff --git a/include/linux/atmdev.h b/include/linux/atmdev.h
index 8124815eb1218b..5d5ff2203fa220 100644
--- a/include/linux/atmdev.h
+++ b/include/linux/atmdev.h
@@ -176,11 +176,6 @@ struct atm_dev {
#define ATM_OF_IMMED 1 /* Attempt immediate delivery */
#define ATM_OF_INRATE 2 /* Attempt in-rate delivery */
-
-/*
- * ioctl, getsockopt, and setsockopt are optional and can be set to NULL.
- */
-
struct atmdev_ops { /* only send is required */
void (*dev_close)(struct atm_dev *dev);
int (*open)(struct atm_vcc *vcc);
@@ -190,10 +185,6 @@ struct atmdev_ops { /* only send is required */
int (*compat_ioctl)(struct atm_dev *dev,unsigned int cmd,
void __user *arg);
#endif
- int (*getsockopt)(struct atm_vcc *vcc,int level,int optname,
- void __user *optval,int optlen);
- int (*setsockopt)(struct atm_vcc *vcc,int level,int optname,
- void __user *optval,unsigned int optlen);
int (*send)(struct atm_vcc *vcc,struct sk_buff *skb);
int (*send_oam)(struct atm_vcc *vcc,void *cell,int flags);
void (*phy_put)(struct atm_dev *dev,unsigned char value,
diff --git a/net/atm/common.c b/net/atm/common.c
index 8575f5d52087d3..9b28f1fb3c69c8 100644
--- a/net/atm/common.c
+++ b/net/atm/common.c
@@ -782,13 +782,8 @@ int vcc_setsockopt(struct socket *sock, int level, int optname,
vcc->atm_options &= ~ATM_ATMOPT_CLP;
return 0;
default:
- if (level == SOL_SOCKET)
- return -EINVAL;
- break;
- }
- if (!vcc->dev || !vcc->dev->ops->setsockopt)
return -EINVAL;
- return vcc->dev->ops->setsockopt(vcc, level, optname, optval, optlen);
+ }
}
int vcc_getsockopt(struct socket *sock, int level, int optname,
@@ -826,13 +821,8 @@ int vcc_getsockopt(struct socket *sock, int level, int optname,
return copy_to_user(optval, &pvc, sizeof(pvc)) ? -EFAULT : 0;
}
default:
- if (level == SOL_SOCKET)
- return -EINVAL;
- break;
- }
- if (!vcc->dev || !vcc->dev->ops->getsockopt)
return -EINVAL;
- return vcc->dev->ops->getsockopt(vcc, level, optname, optval, len);
+ }
}
int register_atmdevice_notifier(struct notifier_block *nb)
--
2.27.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 02/22] net: streamline __sys_setsockopt
2020-07-17 6:23 sockopt cleanups Christoph Hellwig
2020-07-17 6:23 ` [PATCH 01/22] net/atm: remove the atmdev_ops {get,set}sockopt methods Christoph Hellwig
@ 2020-07-17 6:23 ` Christoph Hellwig
2020-07-17 6:23 ` [PATCH 03/22] net: streamline __sys_getsockopt Christoph Hellwig
` (20 subsequent siblings)
22 siblings, 0 replies; 27+ messages in thread
From: Christoph Hellwig @ 2020-07-17 6:23 UTC (permalink / raw)
To: David S. Miller
Cc: Alexei Starovoitov, Daniel Borkmann, Chas Williams,
Pablo Neira Ayuso, Jozsef Kadlecsik, Florian Westphal,
Alexey Kuznetsov, Hideaki YOSHIFUJI, linux-kernel, netdev, bpf,
netfilter-devel, linux-sctp, linux-arch, linux-bluetooth, bridge,
linux-can, dccp, linux-wpan, mptcp
Return early when sockfd_lookup_light fails to reduce a level of
indentation for most of the function body.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
net/socket.c | 57 +++++++++++++++++++++++++---------------------------
1 file changed, 27 insertions(+), 30 deletions(-)
diff --git a/net/socket.c b/net/socket.c
index 770503c4ca76c9..49a6daf0293b83 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -2107,43 +2107,40 @@ static int __sys_setsockopt(int fd, int level, int optname,
return -EINVAL;
sock = sockfd_lookup_light(fd, &err, &fput_needed);
- if (sock != NULL) {
- err = security_socket_setsockopt(sock, level, optname);
- if (err)
- goto out_put;
+ if (!sock)
+ return err;
- err = BPF_CGROUP_RUN_PROG_SETSOCKOPT(sock->sk, &level,
- &optname, optval, &optlen,
- &kernel_optval);
+ err = security_socket_setsockopt(sock, level, optname);
+ if (err)
+ goto out_put;
- if (err < 0) {
- goto out_put;
- } else if (err > 0) {
- err = 0;
- goto out_put;
- }
+ err = BPF_CGROUP_RUN_PROG_SETSOCKOPT(sock->sk, &level, &optname,
+ optval, &optlen, &kernel_optval);
+ if (err < 0)
+ goto out_put;
+ if (err > 0) {
+ err = 0;
+ goto out_put;
+ }
- if (kernel_optval) {
- set_fs(KERNEL_DS);
- optval = (char __user __force *)kernel_optval;
- }
+ if (kernel_optval) {
+ set_fs(KERNEL_DS);
+ optval = (char __user __force *)kernel_optval;
+ }
- if (level == SOL_SOCKET && !sock_use_custom_sol_socket(sock))
- err =
- sock_setsockopt(sock, level, optname, optval,
+ if (level == SOL_SOCKET && !sock_use_custom_sol_socket(sock))
+ err = sock_setsockopt(sock, level, optname, optval, optlen);
+ else
+ err = sock->ops->setsockopt(sock, level, optname, optval,
optlen);
- else
- err =
- sock->ops->setsockopt(sock, level, optname, optval,
- optlen);
- if (kernel_optval) {
- set_fs(oldfs);
- kfree(kernel_optval);
- }
-out_put:
- fput_light(sock->file, fput_needed);
+ if (kernel_optval) {
+ set_fs(oldfs);
+ kfree(kernel_optval);
}
+
+out_put:
+ fput_light(sock->file, fput_needed);
return err;
}
--
2.27.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 03/22] net: streamline __sys_getsockopt
2020-07-17 6:23 sockopt cleanups Christoph Hellwig
2020-07-17 6:23 ` [PATCH 01/22] net/atm: remove the atmdev_ops {get,set}sockopt methods Christoph Hellwig
2020-07-17 6:23 ` [PATCH 02/22] net: streamline __sys_setsockopt Christoph Hellwig
@ 2020-07-17 6:23 ` Christoph Hellwig
2020-07-17 6:23 ` [PATCH 04/22] net: simplify cBPF setsockopt compat handling Christoph Hellwig
` (19 subsequent siblings)
22 siblings, 0 replies; 27+ messages in thread
From: Christoph Hellwig @ 2020-07-17 6:23 UTC (permalink / raw)
To: David S. Miller
Cc: Alexei Starovoitov, Daniel Borkmann, Chas Williams,
Pablo Neira Ayuso, Jozsef Kadlecsik, Florian Westphal,
Alexey Kuznetsov, Hideaki YOSHIFUJI, linux-kernel, netdev, bpf,
netfilter-devel, linux-sctp, linux-arch, linux-bluetooth, bridge,
linux-can, dccp, linux-wpan, mptcp
Return early when sockfd_lookup_light fails to reduce a level of
indentation for most of the function body.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
net/socket.c | 31 ++++++++++++++-----------------
1 file changed, 14 insertions(+), 17 deletions(-)
diff --git a/net/socket.c b/net/socket.c
index 49a6daf0293b83..b79376b17b45b7 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -2163,28 +2163,25 @@ static int __sys_getsockopt(int fd, int level, int optname,
int max_optlen;
sock = sockfd_lookup_light(fd, &err, &fput_needed);
- if (sock != NULL) {
- err = security_socket_getsockopt(sock, level, optname);
- if (err)
- goto out_put;
+ if (!sock)
+ return err;
- max_optlen = BPF_CGROUP_GETSOCKOPT_MAX_OPTLEN(optlen);
+ err = security_socket_getsockopt(sock, level, optname);
+ if (err)
+ goto out_put;
- if (level == SOL_SOCKET)
- err =
- sock_getsockopt(sock, level, optname, optval,
+ max_optlen = BPF_CGROUP_GETSOCKOPT_MAX_OPTLEN(optlen);
+
+ if (level == SOL_SOCKET)
+ err = sock_getsockopt(sock, level, optname, optval, optlen);
+ else
+ err = sock->ops->getsockopt(sock, level, optname, optval,
optlen);
- else
- err =
- sock->ops->getsockopt(sock, level, optname, optval,
- optlen);
- err = BPF_CGROUP_RUN_PROG_GETSOCKOPT(sock->sk, level, optname,
- optval, optlen,
- max_optlen, err);
+ err = BPF_CGROUP_RUN_PROG_GETSOCKOPT(sock->sk, level, optname, optval,
+ optlen, max_optlen, err);
out_put:
- fput_light(sock->file, fput_needed);
- }
+ fput_light(sock->file, fput_needed);
return err;
}
--
2.27.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 04/22] net: simplify cBPF setsockopt compat handling
2020-07-17 6:23 sockopt cleanups Christoph Hellwig
` (2 preceding siblings ...)
2020-07-17 6:23 ` [PATCH 03/22] net: streamline __sys_getsockopt Christoph Hellwig
@ 2020-07-17 6:23 ` Christoph Hellwig
2020-07-17 6:23 ` [PATCH 05/22] net: remove compat_sock_common_{get,set}sockopt Christoph Hellwig
` (18 subsequent siblings)
22 siblings, 0 replies; 27+ messages in thread
From: Christoph Hellwig @ 2020-07-17 6:23 UTC (permalink / raw)
To: David S. Miller
Cc: Alexei Starovoitov, Daniel Borkmann, Chas Williams,
Pablo Neira Ayuso, Jozsef Kadlecsik, Florian Westphal,
Alexey Kuznetsov, Hideaki YOSHIFUJI, linux-kernel, netdev, bpf,
netfilter-devel, linux-sctp, linux-arch, linux-bluetooth, bridge,
linux-can, dccp, linux-wpan, mptcp
Add a helper that copies either a native or compat bpf_fprog from
userspace after verifying the length, and remove the compat setsockopt
handlers that now aren't required.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
include/linux/filter.h | 4 ++--
include/net/compat.h | 1 -
net/compat.c | 45 +-----------------------------------------
net/core/filter.c | 23 +++++++++++++++++++++
net/core/sock.c | 30 ++++++++++------------------
net/packet/af_packet.c | 33 ++++---------------------------
6 files changed, 40 insertions(+), 96 deletions(-)
diff --git a/include/linux/filter.h b/include/linux/filter.h
index 0b0144752d780a..4d049c8e1fbeaa 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -502,13 +502,11 @@ static inline bool insn_is_zext(const struct bpf_insn *insn)
offsetof(TYPE, MEMBER); \
})
-#ifdef CONFIG_COMPAT
/* A struct sock_filter is architecture independent. */
struct compat_sock_fprog {
u16 len;
compat_uptr_t filter; /* struct sock_filter * */
};
-#endif
struct sock_fprog_kern {
u16 len;
@@ -1278,4 +1276,6 @@ struct bpf_sockopt_kern {
s32 retval;
};
+int copy_bpf_fprog_from_user(struct sock_fprog *dst, void __user *src, int len);
+
#endif /* __LINUX_FILTER_H__ */
diff --git a/include/net/compat.h b/include/net/compat.h
index f241666117d88c..745db0d605b62b 100644
--- a/include/net/compat.h
+++ b/include/net/compat.h
@@ -61,7 +61,6 @@ int __get_compat_msghdr(struct msghdr *kmsg, struct compat_msghdr __user *umsg,
compat_size_t *len);
int get_compat_msghdr(struct msghdr *, struct compat_msghdr __user *,
struct sockaddr __user **, struct iovec **);
-struct sock_fprog __user *get_compat_bpf_fprog(char __user *optval);
int put_cmsg_compat(struct msghdr*, int, int, int, void *);
int cmsghdr_from_user_compat_to_kern(struct msghdr *, struct sock *,
diff --git a/net/compat.c b/net/compat.c
index 5e3041a2c37d4d..3e6c2c5ff2609c 100644
--- a/net/compat.c
+++ b/net/compat.c
@@ -335,49 +335,6 @@ void scm_detach_fds_compat(struct msghdr *kmsg, struct scm_cookie *scm)
__scm_destroy(scm);
}
-/* allocate a 64-bit sock_fprog on the user stack for duration of syscall. */
-struct sock_fprog __user *get_compat_bpf_fprog(char __user *optval)
-{
- struct compat_sock_fprog __user *fprog32 = (struct compat_sock_fprog __user *)optval;
- struct sock_fprog __user *kfprog = compat_alloc_user_space(sizeof(struct sock_fprog));
- struct compat_sock_fprog f32;
- struct sock_fprog f;
-
- if (copy_from_user(&f32, fprog32, sizeof(*fprog32)))
- return NULL;
- memset(&f, 0, sizeof(f));
- f.len = f32.len;
- f.filter = compat_ptr(f32.filter);
- if (copy_to_user(kfprog, &f, sizeof(struct sock_fprog)))
- return NULL;
-
- return kfprog;
-}
-EXPORT_SYMBOL_GPL(get_compat_bpf_fprog);
-
-static int do_set_attach_filter(struct socket *sock, int level, int optname,
- char __user *optval, unsigned int optlen)
-{
- struct sock_fprog __user *kfprog;
-
- kfprog = get_compat_bpf_fprog(optval);
- if (!kfprog)
- return -EFAULT;
-
- return sock_setsockopt(sock, level, optname, (char __user *)kfprog,
- sizeof(struct sock_fprog));
-}
-
-static int compat_sock_setsockopt(struct socket *sock, int level, int optname,
- char __user *optval, unsigned int optlen)
-{
- if (optname == SO_ATTACH_FILTER ||
- optname == SO_ATTACH_REUSEPORT_CBPF)
- return do_set_attach_filter(sock, level, optname,
- optval, optlen);
- return sock_setsockopt(sock, level, optname, optval, optlen);
-}
-
static int __compat_sys_setsockopt(int fd, int level, int optname,
char __user *optval, unsigned int optlen)
{
@@ -396,7 +353,7 @@ static int __compat_sys_setsockopt(int fd, int level, int optname,
}
if (level == SOL_SOCKET)
- err = compat_sock_setsockopt(sock, level,
+ err = sock_setsockopt(sock, level,
optname, optval, optlen);
else if (sock->ops->compat_setsockopt)
err = sock->ops->compat_setsockopt(sock, level,
diff --git a/net/core/filter.c b/net/core/filter.c
index bdd2382e655d85..2bf6624796d86f 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -77,6 +77,29 @@
#include <net/transp_v6.h>
#include <linux/btf_ids.h>
+int copy_bpf_fprog_from_user(struct sock_fprog *dst, void __user *src, int len)
+{
+ if (in_compat_syscall()) {
+ struct compat_sock_fprog f32;
+
+ if (len != sizeof(f32))
+ return -EINVAL;
+ if (copy_from_user(&f32, src, sizeof(f32)))
+ return -EFAULT;
+ memset(dst, 0, sizeof(*dst));
+ dst->len = f32.len;
+ dst->filter = compat_ptr(f32.filter);
+ } else {
+ if (len != sizeof(*dst))
+ return -EINVAL;
+ if (copy_from_user(dst, src, sizeof(*dst)))
+ return -EFAULT;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(copy_bpf_fprog_from_user);
+
/**
* sk_filter_trim_cap - run a packet through a socket filter
* @sk: sock associated with &sk_buff
diff --git a/net/core/sock.c b/net/core/sock.c
index 11d6f77dd56207..e085df79482520 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1059,19 +1059,14 @@ int sock_setsockopt(struct socket *sock, int level, int optname,
ret = sock_set_timeout(&sk->sk_sndtimeo, optval, optlen, optname == SO_SNDTIMEO_OLD);
break;
- case SO_ATTACH_FILTER:
- ret = -EINVAL;
- if (optlen == sizeof(struct sock_fprog)) {
- struct sock_fprog fprog;
-
- ret = -EFAULT;
- if (copy_from_user(&fprog, optval, sizeof(fprog)))
- break;
+ case SO_ATTACH_FILTER: {
+ struct sock_fprog fprog;
+ ret = copy_bpf_fprog_from_user(&fprog, optval, optlen);
+ if (!ret)
ret = sk_attach_filter(&fprog, sk);
- }
break;
-
+ }
case SO_ATTACH_BPF:
ret = -EINVAL;
if (optlen == sizeof(u32)) {
@@ -1085,19 +1080,14 @@ int sock_setsockopt(struct socket *sock, int level, int optname,
}
break;
- case SO_ATTACH_REUSEPORT_CBPF:
- ret = -EINVAL;
- if (optlen == sizeof(struct sock_fprog)) {
- struct sock_fprog fprog;
-
- ret = -EFAULT;
- if (copy_from_user(&fprog, optval, sizeof(fprog)))
- break;
+ case SO_ATTACH_REUSEPORT_CBPF: {
+ struct sock_fprog fprog;
+ ret = copy_bpf_fprog_from_user(&fprog, optval, optlen);
+ if (!ret)
ret = sk_reuseport_attach_filter(&fprog, sk);
- }
break;
-
+ }
case SO_ATTACH_REUSEPORT_EBPF:
ret = -EINVAL;
if (optlen == sizeof(u32)) {
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 781fee93b7d5e3..35aee9e980536d 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -1545,10 +1545,10 @@ static int fanout_set_data_cbpf(struct packet_sock *po, char __user *data,
if (sock_flag(&po->sk, SOCK_FILTER_LOCKED))
return -EPERM;
- if (len != sizeof(fprog))
- return -EINVAL;
- if (copy_from_user(&fprog, data, len))
- return -EFAULT;
+
+ ret = copy_bpf_fprog_from_user(&fprog, data, len);
+ if (ret)
+ return ret;
ret = bpf_prog_create_from_user(&new, &fprog, NULL, false);
if (ret)
@@ -4040,28 +4040,6 @@ static int packet_getsockopt(struct socket *sock, int level, int optname,
return 0;
}
-
-#ifdef CONFIG_COMPAT
-static int compat_packet_setsockopt(struct socket *sock, int level, int optname,
- char __user *optval, unsigned int optlen)
-{
- struct packet_sock *po = pkt_sk(sock->sk);
-
- if (level != SOL_PACKET)
- return -ENOPROTOOPT;
-
- if (optname == PACKET_FANOUT_DATA &&
- po->fanout && po->fanout->type == PACKET_FANOUT_CBPF) {
- optval = (char __user *)get_compat_bpf_fprog(optval);
- if (!optval)
- return -EFAULT;
- optlen = sizeof(struct sock_fprog);
- }
-
- return packet_setsockopt(sock, level, optname, optval, optlen);
-}
-#endif
-
static int packet_notifier(struct notifier_block *this,
unsigned long msg, void *ptr)
{
@@ -4549,9 +4527,6 @@ static const struct proto_ops packet_ops = {
.shutdown = sock_no_shutdown,
.setsockopt = packet_setsockopt,
.getsockopt = packet_getsockopt,
-#ifdef CONFIG_COMPAT
- .compat_setsockopt = compat_packet_setsockopt,
-#endif
.sendmsg = packet_sendmsg,
.recvmsg = packet_recvmsg,
.mmap = packet_mmap,
--
2.27.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 05/22] net: remove compat_sock_common_{get,set}sockopt
2020-07-17 6:23 sockopt cleanups Christoph Hellwig
` (3 preceding siblings ...)
2020-07-17 6:23 ` [PATCH 04/22] net: simplify cBPF setsockopt compat handling Christoph Hellwig
@ 2020-07-17 6:23 ` Christoph Hellwig
2020-07-17 9:18 ` [MPTCP] " Matthieu Baerts
2020-07-17 9:26 ` Stefan Schmidt
2020-07-17 6:23 ` [PATCH 06/22] net: remove compat_sys_{get,set}sockopt Christoph Hellwig
` (17 subsequent siblings)
22 siblings, 2 replies; 27+ messages in thread
From: Christoph Hellwig @ 2020-07-17 6:23 UTC (permalink / raw)
To: David S. Miller
Cc: Alexei Starovoitov, Daniel Borkmann, Chas Williams,
Pablo Neira Ayuso, Jozsef Kadlecsik, Florian Westphal,
Alexey Kuznetsov, Hideaki YOSHIFUJI, linux-kernel, netdev, bpf,
netfilter-devel, linux-sctp, linux-arch, linux-bluetooth, bridge,
linux-can, dccp, linux-wpan, mptcp
Add the compat handling to sock_common_{get,set}sockopt instead,
keyed of in_compat_syscall(). This allow to remove the now unused
->compat_{get,set}sockopt methods from struct proto_ops.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
include/linux/net.h | 6 ------
include/net/sock.h | 4 ----
net/core/sock.c | 30 ++++++------------------------
net/dccp/ipv4.c | 4 ----
net/dccp/ipv6.c | 2 --
net/ieee802154/socket.c | 8 --------
net/ipv4/af_inet.c | 6 ------
net/ipv6/af_inet6.c | 4 ----
net/ipv6/ipv6_sockglue.c | 12 ++----------
net/ipv6/raw.c | 2 --
net/l2tp/l2tp_ip.c | 4 ----
net/l2tp/l2tp_ip6.c | 2 --
net/mptcp/protocol.c | 6 ------
net/phonet/socket.c | 8 --------
net/sctp/ipv6.c | 2 --
net/sctp/protocol.c | 4 ----
16 files changed, 8 insertions(+), 96 deletions(-)
diff --git a/include/linux/net.h b/include/linux/net.h
index 016a9c5faa3479..858ff1d981540d 100644
--- a/include/linux/net.h
+++ b/include/linux/net.h
@@ -165,12 +165,6 @@ struct proto_ops {
int optname, char __user *optval, unsigned int optlen);
int (*getsockopt)(struct socket *sock, int level,
int optname, char __user *optval, int __user *optlen);
-#ifdef CONFIG_COMPAT
- int (*compat_setsockopt)(struct socket *sock, int level,
- int optname, char __user *optval, unsigned int optlen);
- int (*compat_getsockopt)(struct socket *sock, int level,
- int optname, char __user *optval, int __user *optlen);
-#endif
void (*show_fdinfo)(struct seq_file *m, struct socket *sock);
int (*sendmsg) (struct socket *sock, struct msghdr *m,
size_t total_len);
diff --git a/include/net/sock.h b/include/net/sock.h
index 4bf8841651486d..1fd7cf5fc7516c 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -1744,10 +1744,6 @@ int sock_common_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
int flags);
int sock_common_setsockopt(struct socket *sock, int level, int optname,
char __user *optval, unsigned int optlen);
-int compat_sock_common_getsockopt(struct socket *sock, int level,
- int optname, char __user *optval, int __user *optlen);
-int compat_sock_common_setsockopt(struct socket *sock, int level,
- int optname, char __user *optval, unsigned int optlen);
void sk_common_release(struct sock *sk);
diff --git a/net/core/sock.c b/net/core/sock.c
index e085df79482520..018404d1762682 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -3199,23 +3199,14 @@ int sock_common_getsockopt(struct socket *sock, int level, int optname,
{
struct sock *sk = sock->sk;
- return sk->sk_prot->getsockopt(sk, level, optname, optval, optlen);
-}
-EXPORT_SYMBOL(sock_common_getsockopt);
-
#ifdef CONFIG_COMPAT
-int compat_sock_common_getsockopt(struct socket *sock, int level, int optname,
- char __user *optval, int __user *optlen)
-{
- struct sock *sk = sock->sk;
-
- if (sk->sk_prot->compat_getsockopt != NULL)
+ if (in_compat_syscal() && sk->sk_prot->compat_getsockopt)
return sk->sk_prot->compat_getsockopt(sk, level, optname,
optval, optlen);
+#endif
return sk->sk_prot->getsockopt(sk, level, optname, optval, optlen);
}
-EXPORT_SYMBOL(compat_sock_common_getsockopt);
-#endif
+EXPORT_SYMBOL(sock_common_getsockopt);
int sock_common_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
int flags)
@@ -3240,23 +3231,14 @@ int sock_common_setsockopt(struct socket *sock, int level, int optname,
{
struct sock *sk = sock->sk;
- return sk->sk_prot->setsockopt(sk, level, optname, optval, optlen);
-}
-EXPORT_SYMBOL(sock_common_setsockopt);
-
#ifdef CONFIG_COMPAT
-int compat_sock_common_setsockopt(struct socket *sock, int level, int optname,
- char __user *optval, unsigned int optlen)
-{
- struct sock *sk = sock->sk;
-
- if (sk->sk_prot->compat_setsockopt != NULL)
+ if (in_compat_syscall() && sk->sk_prot->compat_setsockopt)
return sk->sk_prot->compat_setsockopt(sk, level, optname,
optval, optlen);
+#endif
return sk->sk_prot->setsockopt(sk, level, optname, optval, optlen);
}
-EXPORT_SYMBOL(compat_sock_common_setsockopt);
-#endif
+EXPORT_SYMBOL(sock_common_setsockopt);
void sk_common_release(struct sock *sk)
{
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index a7e989919c5307..316cc5ac0da72b 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -999,10 +999,6 @@ static const struct proto_ops inet_dccp_ops = {
.recvmsg = sock_common_recvmsg,
.mmap = sock_no_mmap,
.sendpage = sock_no_sendpage,
-#ifdef CONFIG_COMPAT
- .compat_setsockopt = compat_sock_common_setsockopt,
- .compat_getsockopt = compat_sock_common_getsockopt,
-#endif
};
static struct inet_protosw dccp_v4_protosw = {
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
index 650187d688519c..b50f85a72cd5fc 100644
--- a/net/dccp/ipv6.c
+++ b/net/dccp/ipv6.c
@@ -1083,8 +1083,6 @@ static const struct proto_ops inet6_dccp_ops = {
.sendpage = sock_no_sendpage,
#ifdef CONFIG_COMPAT
.compat_ioctl = inet6_compat_ioctl,
- .compat_setsockopt = compat_sock_common_setsockopt,
- .compat_getsockopt = compat_sock_common_getsockopt,
#endif
};
diff --git a/net/ieee802154/socket.c b/net/ieee802154/socket.c
index d93d4531aa9bc5..94ae9662133e30 100644
--- a/net/ieee802154/socket.c
+++ b/net/ieee802154/socket.c
@@ -423,10 +423,6 @@ static const struct proto_ops ieee802154_raw_ops = {
.recvmsg = sock_common_recvmsg,
.mmap = sock_no_mmap,
.sendpage = sock_no_sendpage,
-#ifdef CONFIG_COMPAT
- .compat_setsockopt = compat_sock_common_setsockopt,
- .compat_getsockopt = compat_sock_common_getsockopt,
-#endif
};
/* DGRAM Sockets (802.15.4 dataframes) */
@@ -986,10 +982,6 @@ static const struct proto_ops ieee802154_dgram_ops = {
.recvmsg = sock_common_recvmsg,
.mmap = sock_no_mmap,
.sendpage = sock_no_sendpage,
-#ifdef CONFIG_COMPAT
- .compat_setsockopt = compat_sock_common_setsockopt,
- .compat_getsockopt = compat_sock_common_getsockopt,
-#endif
};
/* Create a socket. Initialise the socket, blank the addresses
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index ff141d630bdf09..4307503a6f0b41 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1043,8 +1043,6 @@ const struct proto_ops inet_stream_ops = {
.sendpage_locked = tcp_sendpage_locked,
.peek_len = tcp_peek_len,
#ifdef CONFIG_COMPAT
- .compat_setsockopt = compat_sock_common_setsockopt,
- .compat_getsockopt = compat_sock_common_getsockopt,
.compat_ioctl = inet_compat_ioctl,
#endif
.set_rcvlowat = tcp_set_rcvlowat,
@@ -1073,8 +1071,6 @@ const struct proto_ops inet_dgram_ops = {
.sendpage = inet_sendpage,
.set_peek_off = sk_set_peek_off,
#ifdef CONFIG_COMPAT
- .compat_setsockopt = compat_sock_common_setsockopt,
- .compat_getsockopt = compat_sock_common_getsockopt,
.compat_ioctl = inet_compat_ioctl,
#endif
};
@@ -1105,8 +1101,6 @@ static const struct proto_ops inet_sockraw_ops = {
.mmap = sock_no_mmap,
.sendpage = inet_sendpage,
#ifdef CONFIG_COMPAT
- .compat_setsockopt = compat_sock_common_setsockopt,
- .compat_getsockopt = compat_sock_common_getsockopt,
.compat_ioctl = inet_compat_ioctl,
#endif
};
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index b304b882e0312f..0306509ab06374 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -688,8 +688,6 @@ const struct proto_ops inet6_stream_ops = {
.peek_len = tcp_peek_len,
#ifdef CONFIG_COMPAT
.compat_ioctl = inet6_compat_ioctl,
- .compat_setsockopt = compat_sock_common_setsockopt,
- .compat_getsockopt = compat_sock_common_getsockopt,
#endif
.set_rcvlowat = tcp_set_rcvlowat,
};
@@ -717,8 +715,6 @@ const struct proto_ops inet6_dgram_ops = {
.set_peek_off = sk_set_peek_off,
#ifdef CONFIG_COMPAT
.compat_ioctl = inet6_compat_ioctl,
- .compat_setsockopt = compat_sock_common_setsockopt,
- .compat_getsockopt = compat_sock_common_getsockopt,
#endif
};
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index 20576e87a5f7e8..6ab44ec2c369da 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -914,12 +914,8 @@ int compat_ipv6_setsockopt(struct sock *sk, int level, int optname,
{
int err;
- if (level == SOL_IP && sk->sk_type != SOCK_RAW) {
- if (udp_prot.compat_setsockopt != NULL)
- return udp_prot.compat_setsockopt(sk, level, optname,
- optval, optlen);
+ if (level == SOL_IP && sk->sk_type != SOCK_RAW)
return udp_prot.setsockopt(sk, level, optname, optval, optlen);
- }
if (level != SOL_IPV6)
return -ENOPROTOOPT;
@@ -1480,12 +1476,8 @@ int compat_ipv6_getsockopt(struct sock *sk, int level, int optname,
{
int err;
- if (level == SOL_IP && sk->sk_type != SOCK_RAW) {
- if (udp_prot.compat_getsockopt != NULL)
- return udp_prot.compat_getsockopt(sk, level, optname,
- optval, optlen);
+ if (level == SOL_IP && sk->sk_type != SOCK_RAW)
return udp_prot.getsockopt(sk, level, optname, optval, optlen);
- }
if (level != SOL_IPV6)
return -ENOPROTOOPT;
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 8ef5a7b30524fd..e23c6b46175870 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -1378,8 +1378,6 @@ const struct proto_ops inet6_sockraw_ops = {
.sendpage = sock_no_sendpage,
#ifdef CONFIG_COMPAT
.compat_ioctl = inet6_compat_ioctl,
- .compat_setsockopt = compat_sock_common_setsockopt,
- .compat_getsockopt = compat_sock_common_getsockopt,
#endif
};
diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c
index 955662a6dee754..f8d7412cfb3d37 100644
--- a/net/l2tp/l2tp_ip.c
+++ b/net/l2tp/l2tp_ip.c
@@ -638,10 +638,6 @@ static const struct proto_ops l2tp_ip_ops = {
.recvmsg = sock_common_recvmsg,
.mmap = sock_no_mmap,
.sendpage = sock_no_sendpage,
-#ifdef CONFIG_COMPAT
- .compat_setsockopt = compat_sock_common_setsockopt,
- .compat_getsockopt = compat_sock_common_getsockopt,
-#endif
};
static struct inet_protosw l2tp_ip_protosw = {
diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c
index 526ed2c24dd5e0..2cdc0b7a7a43c3 100644
--- a/net/l2tp/l2tp_ip6.c
+++ b/net/l2tp/l2tp_ip6.c
@@ -773,8 +773,6 @@ static const struct proto_ops l2tp_ip6_ops = {
.sendpage = sock_no_sendpage,
#ifdef CONFIG_COMPAT
.compat_ioctl = inet6_compat_ioctl,
- .compat_setsockopt = compat_sock_common_setsockopt,
- .compat_getsockopt = compat_sock_common_getsockopt,
#endif
};
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index dbe43e0cd734e4..f0b0b503c2628d 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -2166,10 +2166,6 @@ static const struct proto_ops mptcp_stream_ops = {
.recvmsg = inet_recvmsg,
.mmap = sock_no_mmap,
.sendpage = inet_sendpage,
-#ifdef CONFIG_COMPAT
- .compat_setsockopt = compat_sock_common_setsockopt,
- .compat_getsockopt = compat_sock_common_getsockopt,
-#endif
};
static struct inet_protosw mptcp_protosw = {
@@ -2222,8 +2218,6 @@ static const struct proto_ops mptcp_v6_stream_ops = {
.sendpage = inet_sendpage,
#ifdef CONFIG_COMPAT
.compat_ioctl = inet6_compat_ioctl,
- .compat_setsockopt = compat_sock_common_setsockopt,
- .compat_getsockopt = compat_sock_common_getsockopt,
#endif
};
diff --git a/net/phonet/socket.c b/net/phonet/socket.c
index 76d499f6af9ab3..87c60f83c18061 100644
--- a/net/phonet/socket.c
+++ b/net/phonet/socket.c
@@ -441,10 +441,6 @@ const struct proto_ops phonet_dgram_ops = {
.shutdown = sock_no_shutdown,
.setsockopt = sock_no_setsockopt,
.getsockopt = sock_no_getsockopt,
-#ifdef CONFIG_COMPAT
- .compat_setsockopt = sock_no_setsockopt,
- .compat_getsockopt = sock_no_getsockopt,
-#endif
.sendmsg = pn_socket_sendmsg,
.recvmsg = sock_common_recvmsg,
.mmap = sock_no_mmap,
@@ -466,10 +462,6 @@ const struct proto_ops phonet_stream_ops = {
.shutdown = sock_no_shutdown,
.setsockopt = sock_common_setsockopt,
.getsockopt = sock_common_getsockopt,
-#ifdef CONFIG_COMPAT
- .compat_setsockopt = compat_sock_common_setsockopt,
- .compat_getsockopt = compat_sock_common_getsockopt,
-#endif
.sendmsg = pn_socket_sendmsg,
.recvmsg = sock_common_recvmsg,
.mmap = sock_no_mmap,
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index ccfa0ab3e7f481..ebda31b7747d08 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -1033,8 +1033,6 @@ static const struct proto_ops inet6_seqpacket_ops = {
.mmap = sock_no_mmap,
#ifdef CONFIG_COMPAT
.compat_ioctl = inet6_compat_ioctl,
- .compat_setsockopt = compat_sock_common_setsockopt,
- .compat_getsockopt = compat_sock_common_getsockopt,
#endif
};
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index cde29f3c7fb3c4..8d25cc464efdf3 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -1036,10 +1036,6 @@ static const struct proto_ops inet_seqpacket_ops = {
.recvmsg = inet_recvmsg,
.mmap = sock_no_mmap,
.sendpage = sock_no_sendpage,
-#ifdef CONFIG_COMPAT
- .compat_setsockopt = compat_sock_common_setsockopt,
- .compat_getsockopt = compat_sock_common_getsockopt,
-#endif
};
/* Registration with AF_INET family. */
--
2.27.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* Re: [MPTCP] [PATCH 05/22] net: remove compat_sock_common_{get,set}sockopt
2020-07-17 6:23 ` [PATCH 05/22] net: remove compat_sock_common_{get,set}sockopt Christoph Hellwig
@ 2020-07-17 9:18 ` Matthieu Baerts
2020-07-17 9:26 ` Stefan Schmidt
1 sibling, 0 replies; 27+ messages in thread
From: Matthieu Baerts @ 2020-07-17 9:18 UTC (permalink / raw)
To: Christoph Hellwig, David S. Miller
Cc: Alexei Starovoitov, Daniel Borkmann, Chas Williams,
Pablo Neira Ayuso, Jozsef Kadlecsik, Alexey Kuznetsov,
Hideaki YOSHIFUJI, linux-kernel, netdev, bpf, netfilter-devel,
linux-sctp, linux-arch, linux-bluetooth, bridge, linux-can, dccp,
linux-wpan, mptcp
Hi Christoph,
On 17/07/2020 08:23, Christoph Hellwig wrote:
> Add the compat handling to sock_common_{get,set}sockopt instead,
> keyed of in_compat_syscall(). This allow to remove the now unused
> ->compat_{get,set}sockopt methods from struct proto_ops.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
> include/linux/net.h | 6 ------
> include/net/sock.h | 4 ----
> net/core/sock.c | 30 ++++++------------------------
> net/mptcp/protocol.c | 6 ------
Thank you for looking at that!
For MPTCP-related code:
Acked-by: Matthieu Baerts <matthieu.baerts@tessares.net>
Cheers,
Matt
--
Tessares | Belgium | Hybrid Access Solutions
www.tessares.net
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 05/22] net: remove compat_sock_common_{get,set}sockopt
2020-07-17 6:23 ` [PATCH 05/22] net: remove compat_sock_common_{get,set}sockopt Christoph Hellwig
2020-07-17 9:18 ` [MPTCP] " Matthieu Baerts
@ 2020-07-17 9:26 ` Stefan Schmidt
1 sibling, 0 replies; 27+ messages in thread
From: Stefan Schmidt @ 2020-07-17 9:26 UTC (permalink / raw)
To: Christoph Hellwig, David S. Miller
Cc: Alexei Starovoitov, Daniel Borkmann, Chas Williams,
Pablo Neira Ayuso, Jozsef Kadlecsik, Florian Westphal,
Alexey Kuznetsov, Hideaki YOSHIFUJI, linux-kernel, netdev, bpf,
netfilter-devel, linux-sctp, linux-arch, linux-bluetooth, bridge,
linux-can, dccp, linux-wpan, mptcp
Hello.
On 17.07.20 08:23, Christoph Hellwig wrote:
> Add the compat handling to sock_common_{get,set}sockopt instead,
> keyed of in_compat_syscall(). This allow to remove the now unused
> ->compat_{get,set}sockopt methods from struct proto_ops.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
> include/linux/net.h | 6 ------
> include/net/sock.h | 4 ----
> net/core/sock.c | 30 ++++++------------------------
> net/dccp/ipv4.c | 4 ----
> net/dccp/ipv6.c | 2 --
> net/ieee802154/socket.c | 8 --------
> net/ipv4/af_inet.c | 6 ------
> net/ipv6/af_inet6.c | 4 ----
> net/ipv6/ipv6_sockglue.c | 12 ++----------
> net/ipv6/raw.c | 2 --
> net/l2tp/l2tp_ip.c | 4 ----
> net/l2tp/l2tp_ip6.c | 2 --
> net/mptcp/protocol.c | 6 ------
> net/phonet/socket.c | 8 --------
> net/sctp/ipv6.c | 2 --
> net/sctp/protocol.c | 4 ----
> 16 files changed, 8 insertions(+), 96 deletions(-)
>
> diff --git a/include/linux/net.h b/include/linux/net.h
> index 016a9c5faa3479..858ff1d981540d 100644
> --- a/include/linux/net.h
> +++ b/include/linux/net.h
> @@ -165,12 +165,6 @@ struct proto_ops {
> int optname, char __user *optval, unsigned int optlen);
> int (*getsockopt)(struct socket *sock, int level,
> int optname, char __user *optval, int __user *optlen);
> -#ifdef CONFIG_COMPAT
> - int (*compat_setsockopt)(struct socket *sock, int level,
> - int optname, char __user *optval, unsigned int optlen);
> - int (*compat_getsockopt)(struct socket *sock, int level,
> - int optname, char __user *optval, int __user *optlen);
> -#endif
> void (*show_fdinfo)(struct seq_file *m, struct socket *sock);
> int (*sendmsg) (struct socket *sock, struct msghdr *m,
> size_t total_len);
> diff --git a/include/net/sock.h b/include/net/sock.h
> index 4bf8841651486d..1fd7cf5fc7516c 100644
> --- a/include/net/sock.h
> +++ b/include/net/sock.h
> @@ -1744,10 +1744,6 @@ int sock_common_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
> int flags);
> int sock_common_setsockopt(struct socket *sock, int level, int optname,
> char __user *optval, unsigned int optlen);
> -int compat_sock_common_getsockopt(struct socket *sock, int level,
> - int optname, char __user *optval, int __user *optlen);
> -int compat_sock_common_setsockopt(struct socket *sock, int level,
> - int optname, char __user *optval, unsigned int optlen);
>
> void sk_common_release(struct sock *sk);
>
> diff --git a/net/core/sock.c b/net/core/sock.c
> index e085df79482520..018404d1762682 100644
> --- a/net/core/sock.c
> +++ b/net/core/sock.c
> @@ -3199,23 +3199,14 @@ int sock_common_getsockopt(struct socket *sock, int level, int optname,
> {
> struct sock *sk = sock->sk;
>
> - return sk->sk_prot->getsockopt(sk, level, optname, optval, optlen);
> -}
> -EXPORT_SYMBOL(sock_common_getsockopt);
> -
> #ifdef CONFIG_COMPAT
> -int compat_sock_common_getsockopt(struct socket *sock, int level, int optname,
> - char __user *optval, int __user *optlen)
> -{
> - struct sock *sk = sock->sk;
> -
> - if (sk->sk_prot->compat_getsockopt != NULL)
> + if (in_compat_syscal() && sk->sk_prot->compat_getsockopt)
> return sk->sk_prot->compat_getsockopt(sk, level, optname,
> optval, optlen);
> +#endif
> return sk->sk_prot->getsockopt(sk, level, optname, optval, optlen);
> }
> -EXPORT_SYMBOL(compat_sock_common_getsockopt);
> -#endif
> +EXPORT_SYMBOL(sock_common_getsockopt);
>
> int sock_common_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
> int flags)
> @@ -3240,23 +3231,14 @@ int sock_common_setsockopt(struct socket *sock, int level, int optname,
> {
> struct sock *sk = sock->sk;
>
> - return sk->sk_prot->setsockopt(sk, level, optname, optval, optlen);
> -}
> -EXPORT_SYMBOL(sock_common_setsockopt);
> -
> #ifdef CONFIG_COMPAT
> -int compat_sock_common_setsockopt(struct socket *sock, int level, int optname,
> - char __user *optval, unsigned int optlen)
> -{
> - struct sock *sk = sock->sk;
> -
> - if (sk->sk_prot->compat_setsockopt != NULL)
> + if (in_compat_syscall() && sk->sk_prot->compat_setsockopt)
> return sk->sk_prot->compat_setsockopt(sk, level, optname,
> optval, optlen);
> +#endif
> return sk->sk_prot->setsockopt(sk, level, optname, optval, optlen);
> }
> -EXPORT_SYMBOL(compat_sock_common_setsockopt);
> -#endif
> +EXPORT_SYMBOL(sock_common_setsockopt);
>
> void sk_common_release(struct sock *sk)
> {
> diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
> index a7e989919c5307..316cc5ac0da72b 100644
> --- a/net/dccp/ipv4.c
> +++ b/net/dccp/ipv4.c
> @@ -999,10 +999,6 @@ static const struct proto_ops inet_dccp_ops = {
> .recvmsg = sock_common_recvmsg,
> .mmap = sock_no_mmap,
> .sendpage = sock_no_sendpage,
> -#ifdef CONFIG_COMPAT
> - .compat_setsockopt = compat_sock_common_setsockopt,
> - .compat_getsockopt = compat_sock_common_getsockopt,
> -#endif
> };
>
> static struct inet_protosw dccp_v4_protosw = {
> diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
> index 650187d688519c..b50f85a72cd5fc 100644
> --- a/net/dccp/ipv6.c
> +++ b/net/dccp/ipv6.c
> @@ -1083,8 +1083,6 @@ static const struct proto_ops inet6_dccp_ops = {
> .sendpage = sock_no_sendpage,
> #ifdef CONFIG_COMPAT
> .compat_ioctl = inet6_compat_ioctl,
> - .compat_setsockopt = compat_sock_common_setsockopt,
> - .compat_getsockopt = compat_sock_common_getsockopt,
> #endif
> };
>
> diff --git a/net/ieee802154/socket.c b/net/ieee802154/socket.c
> index d93d4531aa9bc5..94ae9662133e30 100644
> --- a/net/ieee802154/socket.c
> +++ b/net/ieee802154/socket.c
> @@ -423,10 +423,6 @@ static const struct proto_ops ieee802154_raw_ops = {
> .recvmsg = sock_common_recvmsg,
> .mmap = sock_no_mmap,
> .sendpage = sock_no_sendpage,
> -#ifdef CONFIG_COMPAT
> - .compat_setsockopt = compat_sock_common_setsockopt,
> - .compat_getsockopt = compat_sock_common_getsockopt,
> -#endif
> };
>
> /* DGRAM Sockets (802.15.4 dataframes) */
> @@ -986,10 +982,6 @@ static const struct proto_ops ieee802154_dgram_ops = {
> .recvmsg = sock_common_recvmsg,
> .mmap = sock_no_mmap,
> .sendpage = sock_no_sendpage,
> -#ifdef CONFIG_COMPAT
> - .compat_setsockopt = compat_sock_common_setsockopt,
> - .compat_getsockopt = compat_sock_common_getsockopt,
> -#endif
For the ieee802154 part:
Acked-by: Stefan Schmidt <stefan@datenfreihafen.org>
regards
Stefan Schmidt
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH 06/22] net: remove compat_sys_{get,set}sockopt
2020-07-17 6:23 sockopt cleanups Christoph Hellwig
` (4 preceding siblings ...)
2020-07-17 6:23 ` [PATCH 05/22] net: remove compat_sock_common_{get,set}sockopt Christoph Hellwig
@ 2020-07-17 6:23 ` Christoph Hellwig
2020-07-17 6:23 ` [PATCH 07/22] netfilter/arp_tables: clean up compat {get,set}sockopt handling Christoph Hellwig
` (16 subsequent siblings)
22 siblings, 0 replies; 27+ messages in thread
From: Christoph Hellwig @ 2020-07-17 6:23 UTC (permalink / raw)
To: David S. Miller
Cc: Alexei Starovoitov, Daniel Borkmann, Chas Williams,
Pablo Neira Ayuso, Jozsef Kadlecsik, Florian Westphal,
Alexey Kuznetsov, Hideaki YOSHIFUJI, linux-kernel, netdev, bpf,
netfilter-devel, linux-sctp, linux-arch, linux-bluetooth, bridge,
linux-can, dccp, linux-wpan, mptcp
Now that the ->compat_{get,set}sockopt proto_ops methods are gone
there is no good reason left to keep the compat syscalls separate.
This fixes the odd use of unsigned int for the compat_setsockopt
optlen and the missing sock_use_custom_sol_socket.
It would also easily allow running the eBPF hooks for the compat
syscalls, but such a large change in behavior does not belong into
a consolidation patch like this one.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/arm64/include/asm/unistd32.h | 4 +-
arch/mips/kernel/syscalls/syscall_n32.tbl | 4 +-
arch/mips/kernel/syscalls/syscall_o32.tbl | 4 +-
arch/parisc/kernel/syscalls/syscall.tbl | 4 +-
arch/powerpc/kernel/syscalls/syscall.tbl | 4 +-
arch/s390/kernel/syscalls/syscall.tbl | 4 +-
arch/sparc/kernel/sys32.S | 12 +--
arch/sparc/kernel/syscalls/syscall.tbl | 4 +-
arch/x86/entry/syscall_x32.c | 7 ++
arch/x86/entry/syscalls/syscall_32.tbl | 4 +-
arch/x86/entry/syscalls/syscall_64.tbl | 4 +-
include/linux/compat.h | 4 -
include/linux/syscalls.h | 4 +
include/uapi/asm-generic/unistd.h | 4 +-
net/compat.c | 79 +------------------
net/socket.c | 25 +++---
tools/include/uapi/asm-generic/unistd.h | 4 +-
.../arch/powerpc/entry/syscalls/syscall.tbl | 4 +-
.../perf/arch/s390/entry/syscalls/syscall.tbl | 4 +-
.../arch/x86/entry/syscalls/syscall_64.tbl | 4 +-
20 files changed, 62 insertions(+), 125 deletions(-)
diff --git a/arch/arm64/include/asm/unistd32.h b/arch/arm64/include/asm/unistd32.h
index 6d95d0c8bf2f47..166e369031108a 100644
--- a/arch/arm64/include/asm/unistd32.h
+++ b/arch/arm64/include/asm/unistd32.h
@@ -599,9 +599,9 @@ __SYSCALL(__NR_recvfrom, compat_sys_recvfrom)
#define __NR_shutdown 293
__SYSCALL(__NR_shutdown, sys_shutdown)
#define __NR_setsockopt 294
-__SYSCALL(__NR_setsockopt, compat_sys_setsockopt)
+__SYSCALL(__NR_setsockopt, sys_setsockopt)
#define __NR_getsockopt 295
-__SYSCALL(__NR_getsockopt, compat_sys_getsockopt)
+__SYSCALL(__NR_getsockopt, sys_getsockopt)
#define __NR_sendmsg 296
__SYSCALL(__NR_sendmsg, compat_sys_sendmsg)
#define __NR_recvmsg 297
diff --git a/arch/mips/kernel/syscalls/syscall_n32.tbl b/arch/mips/kernel/syscalls/syscall_n32.tbl
index f777141f52568f..8488b0d0a99e2a 100644
--- a/arch/mips/kernel/syscalls/syscall_n32.tbl
+++ b/arch/mips/kernel/syscalls/syscall_n32.tbl
@@ -60,8 +60,8 @@
50 n32 getsockname sys_getsockname
51 n32 getpeername sys_getpeername
52 n32 socketpair sys_socketpair
-53 n32 setsockopt compat_sys_setsockopt
-54 n32 getsockopt compat_sys_getsockopt
+53 n32 setsockopt sys_setsockopt
+54 n32 getsockopt sys_getsockopt
55 n32 clone __sys_clone
56 n32 fork __sys_fork
57 n32 execve compat_sys_execve
diff --git a/arch/mips/kernel/syscalls/syscall_o32.tbl b/arch/mips/kernel/syscalls/syscall_o32.tbl
index 13280625d312e9..b20522f813f9d7 100644
--- a/arch/mips/kernel/syscalls/syscall_o32.tbl
+++ b/arch/mips/kernel/syscalls/syscall_o32.tbl
@@ -184,7 +184,7 @@
170 o32 connect sys_connect
171 o32 getpeername sys_getpeername
172 o32 getsockname sys_getsockname
-173 o32 getsockopt sys_getsockopt compat_sys_getsockopt
+173 o32 getsockopt sys_getsockopt sys_getsockopt
174 o32 listen sys_listen
175 o32 recv sys_recv compat_sys_recv
176 o32 recvfrom sys_recvfrom compat_sys_recvfrom
@@ -192,7 +192,7 @@
178 o32 send sys_send
179 o32 sendmsg sys_sendmsg compat_sys_sendmsg
180 o32 sendto sys_sendto
-181 o32 setsockopt sys_setsockopt compat_sys_setsockopt
+181 o32 setsockopt sys_setsockopt sys_setsockopt
182 o32 shutdown sys_shutdown
183 o32 socket sys_socket
184 o32 socketpair sys_socketpair
diff --git a/arch/parisc/kernel/syscalls/syscall.tbl b/arch/parisc/kernel/syscalls/syscall.tbl
index 5a758fa6ec5242..3494e4fa1a1768 100644
--- a/arch/parisc/kernel/syscalls/syscall.tbl
+++ b/arch/parisc/kernel/syscalls/syscall.tbl
@@ -198,8 +198,8 @@
178 common rt_sigqueueinfo sys_rt_sigqueueinfo compat_sys_rt_sigqueueinfo
179 common rt_sigsuspend sys_rt_sigsuspend compat_sys_rt_sigsuspend
180 common chown sys_chown
-181 common setsockopt sys_setsockopt compat_sys_setsockopt
-182 common getsockopt sys_getsockopt compat_sys_getsockopt
+181 common setsockopt sys_setsockopt sys_setsockopt
+182 common getsockopt sys_getsockopt sys_getsockopt
183 common sendmsg sys_sendmsg compat_sys_sendmsg
184 common recvmsg sys_recvmsg compat_sys_recvmsg
185 common semop sys_semop
diff --git a/arch/powerpc/kernel/syscalls/syscall.tbl b/arch/powerpc/kernel/syscalls/syscall.tbl
index f833a319082247..94eb5b27ef65e3 100644
--- a/arch/powerpc/kernel/syscalls/syscall.tbl
+++ b/arch/powerpc/kernel/syscalls/syscall.tbl
@@ -433,8 +433,8 @@
336 common recv sys_recv compat_sys_recv
337 common recvfrom sys_recvfrom compat_sys_recvfrom
338 common shutdown sys_shutdown
-339 common setsockopt sys_setsockopt compat_sys_setsockopt
-340 common getsockopt sys_getsockopt compat_sys_getsockopt
+339 common setsockopt sys_setsockopt sys_setsockopt
+340 common getsockopt sys_getsockopt sys_getsockopt
341 common sendmsg sys_sendmsg compat_sys_sendmsg
342 common recvmsg sys_recvmsg compat_sys_recvmsg
343 32 recvmmsg sys_recvmmsg_time32 compat_sys_recvmmsg_time32
diff --git a/arch/s390/kernel/syscalls/syscall.tbl b/arch/s390/kernel/syscalls/syscall.tbl
index bfdcb763395735..0d63c71fc54440 100644
--- a/arch/s390/kernel/syscalls/syscall.tbl
+++ b/arch/s390/kernel/syscalls/syscall.tbl
@@ -372,8 +372,8 @@
362 common connect sys_connect sys_connect
363 common listen sys_listen sys_listen
364 common accept4 sys_accept4 sys_accept4
-365 common getsockopt sys_getsockopt compat_sys_getsockopt
-366 common setsockopt sys_setsockopt compat_sys_setsockopt
+365 common getsockopt sys_getsockopt sys_getsockopt
+366 common setsockopt sys_setsockopt sys_setsockopt
367 common getsockname sys_getsockname sys_getsockname
368 common getpeername sys_getpeername sys_getpeername
369 common sendto sys_sendto sys_sendto
diff --git a/arch/sparc/kernel/sys32.S b/arch/sparc/kernel/sys32.S
index 489ffab918a835..a45f0f31fe51ab 100644
--- a/arch/sparc/kernel/sys32.S
+++ b/arch/sparc/kernel/sys32.S
@@ -157,22 +157,22 @@ do_sys_shutdown: /* sys_shutdown(int, int) */
nop
nop
nop
-do_sys_setsockopt: /* compat_sys_setsockopt(int, int, int, char *, int) */
+do_sys_setsockopt: /* sys_setsockopt(int, int, int, char *, int) */
47: ldswa [%o1 + 0x0] %asi, %o0
- sethi %hi(compat_sys_setsockopt), %g1
+ sethi %hi(sys_setsockopt), %g1
48: ldswa [%o1 + 0x8] %asi, %o2
49: lduwa [%o1 + 0xc] %asi, %o3
50: ldswa [%o1 + 0x10] %asi, %o4
- jmpl %g1 + %lo(compat_sys_setsockopt), %g0
+ jmpl %g1 + %lo(sys_setsockopt), %g0
51: ldswa [%o1 + 0x4] %asi, %o1
nop
-do_sys_getsockopt: /* compat_sys_getsockopt(int, int, int, u32, u32) */
+do_sys_getsockopt: /* sys_getsockopt(int, int, int, u32, u32) */
52: ldswa [%o1 + 0x0] %asi, %o0
- sethi %hi(compat_sys_getsockopt), %g1
+ sethi %hi(sys_getsockopt), %g1
53: ldswa [%o1 + 0x8] %asi, %o2
54: lduwa [%o1 + 0xc] %asi, %o3
55: lduwa [%o1 + 0x10] %asi, %o4
- jmpl %g1 + %lo(compat_sys_getsockopt), %g0
+ jmpl %g1 + %lo(sys_getsockopt), %g0
56: ldswa [%o1 + 0x4] %asi, %o1
nop
do_sys_sendmsg: /* compat_sys_sendmsg(int, struct compat_msghdr *, unsigned int) */
diff --git a/arch/sparc/kernel/syscalls/syscall.tbl b/arch/sparc/kernel/syscalls/syscall.tbl
index 8004a276cb74be..c59b37965add7e 100644
--- a/arch/sparc/kernel/syscalls/syscall.tbl
+++ b/arch/sparc/kernel/syscalls/syscall.tbl
@@ -147,7 +147,7 @@
115 32 getgroups32 sys_getgroups
116 common gettimeofday sys_gettimeofday compat_sys_gettimeofday
117 common getrusage sys_getrusage compat_sys_getrusage
-118 common getsockopt sys_getsockopt compat_sys_getsockopt
+118 common getsockopt sys_getsockopt sys_getsockopt
119 common getcwd sys_getcwd
120 common readv sys_readv compat_sys_readv
121 common writev sys_writev compat_sys_writev
@@ -425,7 +425,7 @@
352 common userfaultfd sys_userfaultfd
353 common bind sys_bind
354 common listen sys_listen
-355 common setsockopt sys_setsockopt compat_sys_setsockopt
+355 common setsockopt sys_setsockopt sys_setsockopt
356 common mlock2 sys_mlock2
357 common copy_file_range sys_copy_file_range
358 common preadv2 sys_preadv2 compat_sys_preadv2
diff --git a/arch/x86/entry/syscall_x32.c b/arch/x86/entry/syscall_x32.c
index 3d8d70d3896c87..1583831f61a9df 100644
--- a/arch/x86/entry/syscall_x32.c
+++ b/arch/x86/entry/syscall_x32.c
@@ -8,6 +8,13 @@
#include <asm/unistd.h>
#include <asm/syscall.h>
+/*
+ * Reuse the 64-bit entry points for the x32 versions that occupy different
+ * slots in the syscall table.
+ */
+#define __x32_sys_getsockopt __x64_sys_getsockopt
+#define __x32_sys_setsockopt __x64_sys_setsockopt
+
#define __SYSCALL_64(nr, sym)
#define __SYSCALL_X32(nr, sym) extern long __x32_##sym(const struct pt_regs *);
diff --git a/arch/x86/entry/syscalls/syscall_32.tbl b/arch/x86/entry/syscalls/syscall_32.tbl
index d8f8a1a69ed11f..43742a69dba13a 100644
--- a/arch/x86/entry/syscalls/syscall_32.tbl
+++ b/arch/x86/entry/syscalls/syscall_32.tbl
@@ -376,8 +376,8 @@
362 i386 connect sys_connect
363 i386 listen sys_listen
364 i386 accept4 sys_accept4
-365 i386 getsockopt sys_getsockopt compat_sys_getsockopt
-366 i386 setsockopt sys_setsockopt compat_sys_setsockopt
+365 i386 getsockopt sys_getsockopt sys_getsockopt
+366 i386 setsockopt sys_setsockopt sys_setsockopt
367 i386 getsockname sys_getsockname
368 i386 getpeername sys_getpeername
369 i386 sendto sys_sendto
diff --git a/arch/x86/entry/syscalls/syscall_64.tbl b/arch/x86/entry/syscalls/syscall_64.tbl
index 78847b32e1370f..e008d638e6417f 100644
--- a/arch/x86/entry/syscalls/syscall_64.tbl
+++ b/arch/x86/entry/syscalls/syscall_64.tbl
@@ -396,8 +396,8 @@
538 x32 sendmmsg compat_sys_sendmmsg
539 x32 process_vm_readv compat_sys_process_vm_readv
540 x32 process_vm_writev compat_sys_process_vm_writev
-541 x32 setsockopt compat_sys_setsockopt
-542 x32 getsockopt compat_sys_getsockopt
+541 x32 setsockopt sys_setsockopt
+542 x32 getsockopt sys_getsockopt
543 x32 io_setup compat_sys_io_setup
544 x32 io_submit compat_sys_io_submit
545 x32 execveat compat_sys_execveat
diff --git a/include/linux/compat.h b/include/linux/compat.h
index e90100c0de72e4..c4255d8a4a8aea 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -737,10 +737,6 @@ asmlinkage long compat_sys_shmat(int shmid, compat_uptr_t shmaddr, int shmflg);
asmlinkage long compat_sys_recvfrom(int fd, void __user *buf, compat_size_t len,
unsigned flags, struct sockaddr __user *addr,
int __user *addrlen);
-asmlinkage long compat_sys_setsockopt(int fd, int level, int optname,
- char __user *optval, unsigned int optlen);
-asmlinkage long compat_sys_getsockopt(int fd, int level, int optname,
- char __user *optval, int __user *optlen);
asmlinkage long compat_sys_sendmsg(int fd, struct compat_msghdr __user *msg,
unsigned flags);
asmlinkage long compat_sys_recvmsg(int fd, struct compat_msghdr __user *msg,
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index b951a87da9877c..aa46825c6f9d78 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -1424,4 +1424,8 @@ long compat_ksys_semtimedop(int semid, struct sembuf __user *tsems,
unsigned int nsops,
const struct old_timespec32 __user *timeout);
+int __sys_getsockopt(int fd, int level, int optname, char __user *optval,
+ int __user *optlen);
+int __sys_setsockopt(int fd, int level, int optname, char __user *optval,
+ int optlen);
#endif
diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h
index f4a01305d9a65c..c8c189a5f0a6bd 100644
--- a/include/uapi/asm-generic/unistd.h
+++ b/include/uapi/asm-generic/unistd.h
@@ -606,9 +606,9 @@ __SYSCALL(__NR_sendto, sys_sendto)
#define __NR_recvfrom 207
__SC_COMP(__NR_recvfrom, sys_recvfrom, compat_sys_recvfrom)
#define __NR_setsockopt 208
-__SC_COMP(__NR_setsockopt, sys_setsockopt, compat_sys_setsockopt)
+__SC_COMP(__NR_setsockopt, sys_setsockopt, sys_setsockopt)
#define __NR_getsockopt 209
-__SC_COMP(__NR_getsockopt, sys_getsockopt, compat_sys_getsockopt)
+__SC_COMP(__NR_getsockopt, sys_getsockopt, sys_getsockopt)
#define __NR_shutdown 210
__SYSCALL(__NR_shutdown, sys_shutdown)
#define __NR_sendmsg 211
diff --git a/net/compat.c b/net/compat.c
index 3e6c2c5ff2609c..091875bd621048 100644
--- a/net/compat.c
+++ b/net/compat.c
@@ -335,77 +335,6 @@ void scm_detach_fds_compat(struct msghdr *kmsg, struct scm_cookie *scm)
__scm_destroy(scm);
}
-static int __compat_sys_setsockopt(int fd, int level, int optname,
- char __user *optval, unsigned int optlen)
-{
- int err;
- struct socket *sock;
-
- if (optlen > INT_MAX)
- return -EINVAL;
-
- sock = sockfd_lookup(fd, &err);
- if (sock) {
- err = security_socket_setsockopt(sock, level, optname);
- if (err) {
- sockfd_put(sock);
- return err;
- }
-
- if (level == SOL_SOCKET)
- err = sock_setsockopt(sock, level,
- optname, optval, optlen);
- else if (sock->ops->compat_setsockopt)
- err = sock->ops->compat_setsockopt(sock, level,
- optname, optval, optlen);
- else
- err = sock->ops->setsockopt(sock, level,
- optname, optval, optlen);
- sockfd_put(sock);
- }
- return err;
-}
-
-COMPAT_SYSCALL_DEFINE5(setsockopt, int, fd, int, level, int, optname,
- char __user *, optval, unsigned int, optlen)
-{
- return __compat_sys_setsockopt(fd, level, optname, optval, optlen);
-}
-
-static int __compat_sys_getsockopt(int fd, int level, int optname,
- char __user *optval,
- int __user *optlen)
-{
- int err;
- struct socket *sock = sockfd_lookup(fd, &err);
-
- if (sock) {
- err = security_socket_getsockopt(sock, level, optname);
- if (err) {
- sockfd_put(sock);
- return err;
- }
-
- if (level == SOL_SOCKET)
- err = sock_getsockopt(sock, level,
- optname, optval, optlen);
- else if (sock->ops->compat_getsockopt)
- err = sock->ops->compat_getsockopt(sock, level,
- optname, optval, optlen);
- else
- err = sock->ops->getsockopt(sock, level,
- optname, optval, optlen);
- sockfd_put(sock);
- }
- return err;
-}
-
-COMPAT_SYSCALL_DEFINE5(getsockopt, int, fd, int, level, int, optname,
- char __user *, optval, int __user *, optlen)
-{
- return __compat_sys_getsockopt(fd, level, optname, optval, optlen);
-}
-
/* Argument list sizes for compat_sys_socketcall */
#define AL(x) ((x) * sizeof(u32))
static unsigned char nas[21] = {
@@ -565,13 +494,11 @@ COMPAT_SYSCALL_DEFINE2(socketcall, int, call, u32 __user *, args)
ret = __sys_shutdown(a0, a1);
break;
case SYS_SETSOCKOPT:
- ret = __compat_sys_setsockopt(a0, a1, a[2],
- compat_ptr(a[3]), a[4]);
+ ret = __sys_setsockopt(a0, a1, a[2], compat_ptr(a[3]), a[4]);
break;
case SYS_GETSOCKOPT:
- ret = __compat_sys_getsockopt(a0, a1, a[2],
- compat_ptr(a[3]),
- compat_ptr(a[4]));
+ ret = __sys_getsockopt(a0, a1, a[2], compat_ptr(a[3]),
+ compat_ptr(a[4]));
break;
case SYS_SENDMSG:
ret = __compat_sys_sendmsg(a0, compat_ptr(a1), a[2]);
diff --git a/net/socket.c b/net/socket.c
index b79376b17b45b7..dec345982abbb6 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -2094,9 +2094,8 @@ 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
* to pass the user mode parameter for the protocols to sort out.
*/
-
-static int __sys_setsockopt(int fd, int level, int optname,
- char __user *optval, int optlen)
+int __sys_setsockopt(int fd, int level, int optname, char __user *optval,
+ int optlen)
{
mm_segment_t oldfs = get_fs();
char *kernel_optval = NULL;
@@ -2114,8 +2113,10 @@ static int __sys_setsockopt(int fd, int level, int optname,
if (err)
goto out_put;
- err = BPF_CGROUP_RUN_PROG_SETSOCKOPT(sock->sk, &level, &optname,
- optval, &optlen, &kernel_optval);
+ if (!in_compat_syscall())
+ err = BPF_CGROUP_RUN_PROG_SETSOCKOPT(sock->sk, &level, &optname,
+ optval, &optlen,
+ &kernel_optval);
if (err < 0)
goto out_put;
if (err > 0) {
@@ -2154,9 +2155,8 @@ SYSCALL_DEFINE5(setsockopt, int, fd, int, level, int, optname,
* Get a socket option. Because we don't know the option lengths we have
* to pass a user mode parameter for the protocols to sort out.
*/
-
-static int __sys_getsockopt(int fd, int level, int optname,
- char __user *optval, int __user *optlen)
+int __sys_getsockopt(int fd, int level, int optname, char __user *optval,
+ int __user *optlen)
{
int err, fput_needed;
struct socket *sock;
@@ -2170,7 +2170,8 @@ static int __sys_getsockopt(int fd, int level, int optname,
if (err)
goto out_put;
- max_optlen = BPF_CGROUP_GETSOCKOPT_MAX_OPTLEN(optlen);
+ if (!in_compat_syscall())
+ max_optlen = BPF_CGROUP_GETSOCKOPT_MAX_OPTLEN(optlen);
if (level == SOL_SOCKET)
err = sock_getsockopt(sock, level, optname, optval, optlen);
@@ -2178,8 +2179,10 @@ static int __sys_getsockopt(int fd, int level, int optname,
err = sock->ops->getsockopt(sock, level, optname, optval,
optlen);
- err = BPF_CGROUP_RUN_PROG_GETSOCKOPT(sock->sk, level, optname, optval,
- optlen, max_optlen, err);
+ if (!in_compat_syscall())
+ err = BPF_CGROUP_RUN_PROG_GETSOCKOPT(sock->sk, level, optname,
+ optval, optlen, max_optlen,
+ err);
out_put:
fput_light(sock->file, fput_needed);
return err;
diff --git a/tools/include/uapi/asm-generic/unistd.h b/tools/include/uapi/asm-generic/unistd.h
index f4a01305d9a65c..c8c189a5f0a6bd 100644
--- a/tools/include/uapi/asm-generic/unistd.h
+++ b/tools/include/uapi/asm-generic/unistd.h
@@ -606,9 +606,9 @@ __SYSCALL(__NR_sendto, sys_sendto)
#define __NR_recvfrom 207
__SC_COMP(__NR_recvfrom, sys_recvfrom, compat_sys_recvfrom)
#define __NR_setsockopt 208
-__SC_COMP(__NR_setsockopt, sys_setsockopt, compat_sys_setsockopt)
+__SC_COMP(__NR_setsockopt, sys_setsockopt, sys_setsockopt)
#define __NR_getsockopt 209
-__SC_COMP(__NR_getsockopt, sys_getsockopt, compat_sys_getsockopt)
+__SC_COMP(__NR_getsockopt, sys_getsockopt, sys_getsockopt)
#define __NR_shutdown 210
__SYSCALL(__NR_shutdown, sys_shutdown)
#define __NR_sendmsg 211
diff --git a/tools/perf/arch/powerpc/entry/syscalls/syscall.tbl b/tools/perf/arch/powerpc/entry/syscalls/syscall.tbl
index 35b61bfc1b1ae9..b190f2eb2611b3 100644
--- a/tools/perf/arch/powerpc/entry/syscalls/syscall.tbl
+++ b/tools/perf/arch/powerpc/entry/syscalls/syscall.tbl
@@ -427,8 +427,8 @@
336 common recv sys_recv compat_sys_recv
337 common recvfrom sys_recvfrom compat_sys_recvfrom
338 common shutdown sys_shutdown
-339 common setsockopt sys_setsockopt compat_sys_setsockopt
-340 common getsockopt sys_getsockopt compat_sys_getsockopt
+339 common setsockopt sys_setsockopt sys_setsockopt
+340 common getsockopt sys_getsockopt sys_getsockopt
341 common sendmsg sys_sendmsg compat_sys_sendmsg
342 common recvmsg sys_recvmsg compat_sys_recvmsg
343 32 recvmmsg sys_recvmmsg_time32 compat_sys_recvmmsg_time32
diff --git a/tools/perf/arch/s390/entry/syscalls/syscall.tbl b/tools/perf/arch/s390/entry/syscalls/syscall.tbl
index b38d48464368dc..56ae24b6e4be6e 100644
--- a/tools/perf/arch/s390/entry/syscalls/syscall.tbl
+++ b/tools/perf/arch/s390/entry/syscalls/syscall.tbl
@@ -372,8 +372,8 @@
362 common connect sys_connect compat_sys_connect
363 common listen sys_listen sys_listen
364 common accept4 sys_accept4 compat_sys_accept4
-365 common getsockopt sys_getsockopt compat_sys_getsockopt
-366 common setsockopt sys_setsockopt compat_sys_setsockopt
+365 common getsockopt sys_getsockopt sys_getsockopt
+366 common setsockopt sys_setsockopt sys_setsockopt
367 common getsockname sys_getsockname compat_sys_getsockname
368 common getpeername sys_getpeername compat_sys_getpeername
369 common sendto sys_sendto compat_sys_sendto
diff --git a/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl b/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl
index 78847b32e1370f..e008d638e6417f 100644
--- a/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl
+++ b/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl
@@ -396,8 +396,8 @@
538 x32 sendmmsg compat_sys_sendmmsg
539 x32 process_vm_readv compat_sys_process_vm_readv
540 x32 process_vm_writev compat_sys_process_vm_writev
-541 x32 setsockopt compat_sys_setsockopt
-542 x32 getsockopt compat_sys_getsockopt
+541 x32 setsockopt sys_setsockopt
+542 x32 getsockopt sys_getsockopt
543 x32 io_setup compat_sys_io_setup
544 x32 io_submit compat_sys_io_submit
545 x32 execveat compat_sys_execveat
--
2.27.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 07/22] netfilter/arp_tables: clean up compat {get,set}sockopt handling
2020-07-17 6:23 sockopt cleanups Christoph Hellwig
` (5 preceding siblings ...)
2020-07-17 6:23 ` [PATCH 06/22] net: remove compat_sys_{get,set}sockopt Christoph Hellwig
@ 2020-07-17 6:23 ` Christoph Hellwig
2020-07-17 6:23 ` [PATCH 08/22] netfilter/ip_tables: " Christoph Hellwig
` (15 subsequent siblings)
22 siblings, 0 replies; 27+ messages in thread
From: Christoph Hellwig @ 2020-07-17 6:23 UTC (permalink / raw)
To: David S. Miller
Cc: Alexei Starovoitov, Daniel Borkmann, Chas Williams,
Pablo Neira Ayuso, Jozsef Kadlecsik, Florian Westphal,
Alexey Kuznetsov, Hideaki YOSHIFUJI, linux-kernel, netdev, bpf,
netfilter-devel, linux-sctp, linux-arch, linux-bluetooth, bridge,
linux-can, dccp, linux-wpan, mptcp
Merge the native and compat {get,set}sockopt handlers using
in_compat_syscall().
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
net/ipv4/netfilter/arp_tables.c | 85 ++++++++-------------------------
1 file changed, 21 insertions(+), 64 deletions(-)
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index b167f4a5b68453..15807fb4a65f3e 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -787,8 +787,7 @@ static int compat_table_info(const struct xt_table_info *info,
}
#endif
-static int get_info(struct net *net, void __user *user,
- const int *len, int compat)
+static int get_info(struct net *net, void __user *user, const int *len)
{
char name[XT_TABLE_MAXNAMELEN];
struct xt_table *t;
@@ -802,7 +801,7 @@ static int get_info(struct net *net, void __user *user,
name[XT_TABLE_MAXNAMELEN-1] = '\0';
#ifdef CONFIG_COMPAT
- if (compat)
+ if (in_compat_syscall())
xt_compat_lock(NFPROTO_ARP);
#endif
t = xt_request_find_table_lock(net, NFPROTO_ARP, name);
@@ -812,7 +811,7 @@ static int get_info(struct net *net, void __user *user,
#ifdef CONFIG_COMPAT
struct xt_table_info tmp;
- if (compat) {
+ if (in_compat_syscall()) {
ret = compat_table_info(private, &tmp);
xt_compat_flush_offsets(NFPROTO_ARP);
private = &tmp;
@@ -837,7 +836,7 @@ static int get_info(struct net *net, void __user *user,
} else
ret = PTR_ERR(t);
#ifdef CONFIG_COMPAT
- if (compat)
+ if (in_compat_syscall())
xt_compat_unlock(NFPROTO_ARP);
#endif
return ret;
@@ -998,7 +997,7 @@ static int do_replace(struct net *net, const void __user *user,
}
static int do_add_counters(struct net *net, const void __user *user,
- unsigned int len, int compat)
+ unsigned int len)
{
unsigned int i;
struct xt_counters_info tmp;
@@ -1009,7 +1008,8 @@ static int do_add_counters(struct net *net, const void __user *user,
struct arpt_entry *iter;
unsigned int addend;
- paddc = xt_copy_counters_from_user(user, len, &tmp, compat);
+ paddc = xt_copy_counters_from_user(user, len, &tmp,
+ in_compat_syscall());
if (IS_ERR(paddc))
return PTR_ERR(paddc);
@@ -1294,30 +1294,6 @@ static int compat_do_replace(struct net *net, void __user *user,
return ret;
}
-static int compat_do_arpt_set_ctl(struct sock *sk, int cmd, void __user *user,
- unsigned int len)
-{
- int ret;
-
- if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN))
- return -EPERM;
-
- switch (cmd) {
- case ARPT_SO_SET_REPLACE:
- ret = compat_do_replace(sock_net(sk), user, len);
- break;
-
- case ARPT_SO_SET_ADD_COUNTERS:
- ret = do_add_counters(sock_net(sk), user, len, 1);
- break;
-
- default:
- ret = -EINVAL;
- }
-
- return ret;
-}
-
static int compat_copy_entry_to_user(struct arpt_entry *e, void __user **dstptr,
compat_uint_t *size,
struct xt_counters *counters,
@@ -1425,29 +1401,6 @@ static int compat_get_entries(struct net *net,
xt_compat_unlock(NFPROTO_ARP);
return ret;
}
-
-static int do_arpt_get_ctl(struct sock *, int, void __user *, int *);
-
-static int compat_do_arpt_get_ctl(struct sock *sk, int cmd, void __user *user,
- int *len)
-{
- int ret;
-
- if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN))
- return -EPERM;
-
- switch (cmd) {
- case ARPT_SO_GET_INFO:
- ret = get_info(sock_net(sk), user, len, 1);
- break;
- case ARPT_SO_GET_ENTRIES:
- ret = compat_get_entries(sock_net(sk), user, len);
- break;
- default:
- ret = do_arpt_get_ctl(sk, cmd, user, len);
- }
- return ret;
-}
#endif
static int do_arpt_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
@@ -1459,11 +1412,16 @@ static int do_arpt_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned
switch (cmd) {
case ARPT_SO_SET_REPLACE:
- ret = do_replace(sock_net(sk), user, len);
+#ifdef CONFIG_COMPAT
+ if (in_compat_syscall())
+ ret = compat_do_replace(sock_net(sk), user, len);
+ else
+#endif
+ ret = do_replace(sock_net(sk), user, len);
break;
case ARPT_SO_SET_ADD_COUNTERS:
- ret = do_add_counters(sock_net(sk), user, len, 0);
+ ret = do_add_counters(sock_net(sk), user, len);
break;
default:
@@ -1482,11 +1440,16 @@ static int do_arpt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len
switch (cmd) {
case ARPT_SO_GET_INFO:
- ret = get_info(sock_net(sk), user, len, 0);
+ ret = get_info(sock_net(sk), user, len);
break;
case ARPT_SO_GET_ENTRIES:
- ret = get_entries(sock_net(sk), user, len);
+#ifdef CONFIG_COMPAT
+ if (in_compat_syscall())
+ ret = compat_get_entries(sock_net(sk), user, len);
+ else
+#endif
+ ret = get_entries(sock_net(sk), user, len);
break;
case ARPT_SO_GET_REVISION_TARGET: {
@@ -1610,15 +1573,9 @@ static struct nf_sockopt_ops arpt_sockopts = {
.set_optmin = ARPT_BASE_CTL,
.set_optmax = ARPT_SO_SET_MAX+1,
.set = do_arpt_set_ctl,
-#ifdef CONFIG_COMPAT
- .compat_set = compat_do_arpt_set_ctl,
-#endif
.get_optmin = ARPT_BASE_CTL,
.get_optmax = ARPT_SO_GET_MAX+1,
.get = do_arpt_get_ctl,
-#ifdef CONFIG_COMPAT
- .compat_get = compat_do_arpt_get_ctl,
-#endif
.owner = THIS_MODULE,
};
--
2.27.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 08/22] netfilter/ip_tables: clean up compat {get,set}sockopt handling
2020-07-17 6:23 sockopt cleanups Christoph Hellwig
` (6 preceding siblings ...)
2020-07-17 6:23 ` [PATCH 07/22] netfilter/arp_tables: clean up compat {get,set}sockopt handling Christoph Hellwig
@ 2020-07-17 6:23 ` Christoph Hellwig
2020-07-17 6:23 ` [PATCH 09/22] netfilter/ip6_tables: " Christoph Hellwig
` (14 subsequent siblings)
22 siblings, 0 replies; 27+ messages in thread
From: Christoph Hellwig @ 2020-07-17 6:23 UTC (permalink / raw)
To: David S. Miller
Cc: Alexei Starovoitov, Daniel Borkmann, Chas Williams,
Pablo Neira Ayuso, Jozsef Kadlecsik, Florian Westphal,
Alexey Kuznetsov, Hideaki YOSHIFUJI, linux-kernel, netdev, bpf,
netfilter-devel, linux-sctp, linux-arch, linux-bluetooth, bridge,
linux-can, dccp, linux-wpan, mptcp
Merge the native and compat {get,set}sockopt handlers using
in_compat_syscall().
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
net/ipv4/netfilter/ip_tables.c | 86 +++++++++-------------------------
1 file changed, 21 insertions(+), 65 deletions(-)
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index 5bf9fa06aee0be..fbfad38f397949 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -944,8 +944,7 @@ static int compat_table_info(const struct xt_table_info *info,
}
#endif
-static int get_info(struct net *net, void __user *user,
- const int *len, int compat)
+static int get_info(struct net *net, void __user *user, const int *len)
{
char name[XT_TABLE_MAXNAMELEN];
struct xt_table *t;
@@ -959,7 +958,7 @@ static int get_info(struct net *net, void __user *user,
name[XT_TABLE_MAXNAMELEN-1] = '\0';
#ifdef CONFIG_COMPAT
- if (compat)
+ if (in_compat_syscall())
xt_compat_lock(AF_INET);
#endif
t = xt_request_find_table_lock(net, AF_INET, name);
@@ -969,7 +968,7 @@ static int get_info(struct net *net, void __user *user,
#ifdef CONFIG_COMPAT
struct xt_table_info tmp;
- if (compat) {
+ if (in_compat_syscall()) {
ret = compat_table_info(private, &tmp);
xt_compat_flush_offsets(AF_INET);
private = &tmp;
@@ -995,7 +994,7 @@ static int get_info(struct net *net, void __user *user,
} else
ret = PTR_ERR(t);
#ifdef CONFIG_COMPAT
- if (compat)
+ if (in_compat_syscall())
xt_compat_unlock(AF_INET);
#endif
return ret;
@@ -1153,7 +1152,7 @@ do_replace(struct net *net, const void __user *user, unsigned int len)
static int
do_add_counters(struct net *net, const void __user *user,
- unsigned int len, int compat)
+ unsigned int len)
{
unsigned int i;
struct xt_counters_info tmp;
@@ -1164,7 +1163,8 @@ do_add_counters(struct net *net, const void __user *user,
struct ipt_entry *iter;
unsigned int addend;
- paddc = xt_copy_counters_from_user(user, len, &tmp, compat);
+ paddc = xt_copy_counters_from_user(user, len, &tmp,
+ in_compat_syscall());
if (IS_ERR(paddc))
return PTR_ERR(paddc);
@@ -1534,31 +1534,6 @@ compat_do_replace(struct net *net, void __user *user, unsigned int len)
return ret;
}
-static int
-compat_do_ipt_set_ctl(struct sock *sk, int cmd, void __user *user,
- unsigned int len)
-{
- int ret;
-
- if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN))
- return -EPERM;
-
- switch (cmd) {
- case IPT_SO_SET_REPLACE:
- ret = compat_do_replace(sock_net(sk), user, len);
- break;
-
- case IPT_SO_SET_ADD_COUNTERS:
- ret = do_add_counters(sock_net(sk), user, len, 1);
- break;
-
- default:
- ret = -EINVAL;
- }
-
- return ret;
-}
-
struct compat_ipt_get_entries {
char name[XT_TABLE_MAXNAMELEN];
compat_uint_t size;
@@ -1634,29 +1609,6 @@ compat_get_entries(struct net *net, struct compat_ipt_get_entries __user *uptr,
xt_compat_unlock(AF_INET);
return ret;
}
-
-static int do_ipt_get_ctl(struct sock *, int, void __user *, int *);
-
-static int
-compat_do_ipt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
-{
- int ret;
-
- if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN))
- return -EPERM;
-
- switch (cmd) {
- case IPT_SO_GET_INFO:
- ret = get_info(sock_net(sk), user, len, 1);
- break;
- case IPT_SO_GET_ENTRIES:
- ret = compat_get_entries(sock_net(sk), user, len);
- break;
- default:
- ret = do_ipt_get_ctl(sk, cmd, user, len);
- }
- return ret;
-}
#endif
static int
@@ -1669,11 +1621,16 @@ do_ipt_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
switch (cmd) {
case IPT_SO_SET_REPLACE:
- ret = do_replace(sock_net(sk), user, len);
+#ifdef CONFIG_COMPAT
+ if (in_compat_syscall())
+ ret = compat_do_replace(sock_net(sk), user, len);
+ else
+#endif
+ ret = do_replace(sock_net(sk), user, len);
break;
case IPT_SO_SET_ADD_COUNTERS:
- ret = do_add_counters(sock_net(sk), user, len, 0);
+ ret = do_add_counters(sock_net(sk), user, len);
break;
default:
@@ -1693,11 +1650,16 @@ do_ipt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
switch (cmd) {
case IPT_SO_GET_INFO:
- ret = get_info(sock_net(sk), user, len, 0);
+ ret = get_info(sock_net(sk), user, len);
break;
case IPT_SO_GET_ENTRIES:
- ret = get_entries(sock_net(sk), user, len);
+#ifdef CONFIG_COMPAT
+ if (in_compat_syscall())
+ ret = compat_get_entries(sock_net(sk), user, len);
+ else
+#endif
+ ret = get_entries(sock_net(sk), user, len);
break;
case IPT_SO_GET_REVISION_MATCH:
@@ -1886,15 +1848,9 @@ static struct nf_sockopt_ops ipt_sockopts = {
.set_optmin = IPT_BASE_CTL,
.set_optmax = IPT_SO_SET_MAX+1,
.set = do_ipt_set_ctl,
-#ifdef CONFIG_COMPAT
- .compat_set = compat_do_ipt_set_ctl,
-#endif
.get_optmin = IPT_BASE_CTL,
.get_optmax = IPT_SO_GET_MAX+1,
.get = do_ipt_get_ctl,
-#ifdef CONFIG_COMPAT
- .compat_get = compat_do_ipt_get_ctl,
-#endif
.owner = THIS_MODULE,
};
--
2.27.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 09/22] netfilter/ip6_tables: clean up compat {get,set}sockopt handling
2020-07-17 6:23 sockopt cleanups Christoph Hellwig
` (7 preceding siblings ...)
2020-07-17 6:23 ` [PATCH 08/22] netfilter/ip_tables: " Christoph Hellwig
@ 2020-07-17 6:23 ` Christoph Hellwig
2020-07-17 6:23 ` [PATCH 10/22] netfilter/ebtables: " Christoph Hellwig
` (13 subsequent siblings)
22 siblings, 0 replies; 27+ messages in thread
From: Christoph Hellwig @ 2020-07-17 6:23 UTC (permalink / raw)
To: David S. Miller
Cc: Alexei Starovoitov, Daniel Borkmann, Chas Williams,
Pablo Neira Ayuso, Jozsef Kadlecsik, Florian Westphal,
Alexey Kuznetsov, Hideaki YOSHIFUJI, linux-kernel, netdev, bpf,
netfilter-devel, linux-sctp, linux-arch, linux-bluetooth, bridge,
linux-can, dccp, linux-wpan, mptcp
Merge the native and compat {get,set}sockopt handlers using
in_compat_syscall().
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
net/ipv6/netfilter/ip6_tables.c | 87 ++++++++-------------------------
1 file changed, 21 insertions(+), 66 deletions(-)
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index e96a431549bcc9..96c48e91e6c7f7 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -960,8 +960,7 @@ static int compat_table_info(const struct xt_table_info *info,
}
#endif
-static int get_info(struct net *net, void __user *user,
- const int *len, int compat)
+static int get_info(struct net *net, void __user *user, const int *len)
{
char name[XT_TABLE_MAXNAMELEN];
struct xt_table *t;
@@ -975,7 +974,7 @@ static int get_info(struct net *net, void __user *user,
name[XT_TABLE_MAXNAMELEN-1] = '\0';
#ifdef CONFIG_COMPAT
- if (compat)
+ if (in_compat_syscall())
xt_compat_lock(AF_INET6);
#endif
t = xt_request_find_table_lock(net, AF_INET6, name);
@@ -985,7 +984,7 @@ static int get_info(struct net *net, void __user *user,
#ifdef CONFIG_COMPAT
struct xt_table_info tmp;
- if (compat) {
+ if (in_compat_syscall()) {
ret = compat_table_info(private, &tmp);
xt_compat_flush_offsets(AF_INET6);
private = &tmp;
@@ -1011,7 +1010,7 @@ static int get_info(struct net *net, void __user *user,
} else
ret = PTR_ERR(t);
#ifdef CONFIG_COMPAT
- if (compat)
+ if (in_compat_syscall())
xt_compat_unlock(AF_INET6);
#endif
return ret;
@@ -1169,8 +1168,7 @@ do_replace(struct net *net, const void __user *user, unsigned int len)
}
static int
-do_add_counters(struct net *net, const void __user *user, unsigned int len,
- int compat)
+do_add_counters(struct net *net, const void __user *user, unsigned int len)
{
unsigned int i;
struct xt_counters_info tmp;
@@ -1181,7 +1179,8 @@ do_add_counters(struct net *net, const void __user *user, unsigned int len,
struct ip6t_entry *iter;
unsigned int addend;
- paddc = xt_copy_counters_from_user(user, len, &tmp, compat);
+ paddc = xt_copy_counters_from_user(user, len, &tmp,
+ in_compat_syscall());
if (IS_ERR(paddc))
return PTR_ERR(paddc);
t = xt_find_table_lock(net, AF_INET6, tmp.name);
@@ -1543,31 +1542,6 @@ compat_do_replace(struct net *net, void __user *user, unsigned int len)
return ret;
}
-static int
-compat_do_ip6t_set_ctl(struct sock *sk, int cmd, void __user *user,
- unsigned int len)
-{
- int ret;
-
- if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN))
- return -EPERM;
-
- switch (cmd) {
- case IP6T_SO_SET_REPLACE:
- ret = compat_do_replace(sock_net(sk), user, len);
- break;
-
- case IP6T_SO_SET_ADD_COUNTERS:
- ret = do_add_counters(sock_net(sk), user, len, 1);
- break;
-
- default:
- ret = -EINVAL;
- }
-
- return ret;
-}
-
struct compat_ip6t_get_entries {
char name[XT_TABLE_MAXNAMELEN];
compat_uint_t size;
@@ -1643,29 +1617,6 @@ compat_get_entries(struct net *net, struct compat_ip6t_get_entries __user *uptr,
xt_compat_unlock(AF_INET6);
return ret;
}
-
-static int do_ip6t_get_ctl(struct sock *, int, void __user *, int *);
-
-static int
-compat_do_ip6t_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
-{
- int ret;
-
- if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN))
- return -EPERM;
-
- switch (cmd) {
- case IP6T_SO_GET_INFO:
- ret = get_info(sock_net(sk), user, len, 1);
- break;
- case IP6T_SO_GET_ENTRIES:
- ret = compat_get_entries(sock_net(sk), user, len);
- break;
- default:
- ret = do_ip6t_get_ctl(sk, cmd, user, len);
- }
- return ret;
-}
#endif
static int
@@ -1678,11 +1629,16 @@ do_ip6t_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
switch (cmd) {
case IP6T_SO_SET_REPLACE:
- ret = do_replace(sock_net(sk), user, len);
+#ifdef CONFIG_COMPAT
+ if (in_compat_syscall())
+ ret = compat_do_replace(sock_net(sk), user, len);
+ else
+#endif
+ ret = do_replace(sock_net(sk), user, len);
break;
case IP6T_SO_SET_ADD_COUNTERS:
- ret = do_add_counters(sock_net(sk), user, len, 0);
+ ret = do_add_counters(sock_net(sk), user, len);
break;
default:
@@ -1702,11 +1658,16 @@ do_ip6t_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
switch (cmd) {
case IP6T_SO_GET_INFO:
- ret = get_info(sock_net(sk), user, len, 0);
+ ret = get_info(sock_net(sk), user, len);
break;
case IP6T_SO_GET_ENTRIES:
- ret = get_entries(sock_net(sk), user, len);
+#ifdef CONFIG_COMPAT
+ if (in_compat_syscall())
+ ret = compat_get_entries(sock_net(sk), user, len);
+ else
+#endif
+ ret = get_entries(sock_net(sk), user, len);
break;
case IP6T_SO_GET_REVISION_MATCH:
@@ -1897,15 +1858,9 @@ static struct nf_sockopt_ops ip6t_sockopts = {
.set_optmin = IP6T_BASE_CTL,
.set_optmax = IP6T_SO_SET_MAX+1,
.set = do_ip6t_set_ctl,
-#ifdef CONFIG_COMPAT
- .compat_set = compat_do_ip6t_set_ctl,
-#endif
.get_optmin = IP6T_BASE_CTL,
.get_optmax = IP6T_SO_GET_MAX+1,
.get = do_ip6t_get_ctl,
-#ifdef CONFIG_COMPAT
- .compat_get = compat_do_ip6t_get_ctl,
-#endif
.owner = THIS_MODULE,
};
--
2.27.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 10/22] netfilter/ebtables: clean up compat {get,set}sockopt handling
2020-07-17 6:23 sockopt cleanups Christoph Hellwig
` (8 preceding siblings ...)
2020-07-17 6:23 ` [PATCH 09/22] netfilter/ip6_tables: " Christoph Hellwig
@ 2020-07-17 6:23 ` Christoph Hellwig
2020-07-17 6:23 ` [PATCH 11/22] netfilter: remove the compat_{get,set} methods Christoph Hellwig
` (12 subsequent siblings)
22 siblings, 0 replies; 27+ messages in thread
From: Christoph Hellwig @ 2020-07-17 6:23 UTC (permalink / raw)
To: David S. Miller
Cc: Alexei Starovoitov, Daniel Borkmann, Chas Williams,
Pablo Neira Ayuso, Jozsef Kadlecsik, Florian Westphal,
Alexey Kuznetsov, Hideaki YOSHIFUJI, linux-kernel, netdev, bpf,
netfilter-devel, linux-sctp, linux-arch, linux-bluetooth, bridge,
linux-can, dccp, linux-wpan, mptcp
Merge the native and compat {get,set}sockopt handlers using
in_compat_syscall(). Note that this required moving a fair
amout of code around to be done sanely.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
net/bridge/netfilter/ebtables.c | 214 +++++++++++++++-----------------
1 file changed, 98 insertions(+), 116 deletions(-)
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
index c83ffe9121639c..fe13108af1f542 100644
--- a/net/bridge/netfilter/ebtables.c
+++ b/net/bridge/netfilter/ebtables.c
@@ -1451,86 +1451,6 @@ static int copy_everything_to_user(struct ebt_table *t, void __user *user,
ebt_entry_to_user, entries, tmp.entries);
}
-static int do_ebt_set_ctl(struct sock *sk,
- int cmd, void __user *user, unsigned int len)
-{
- int ret;
- struct net *net = sock_net(sk);
-
- if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
- return -EPERM;
-
- switch (cmd) {
- case EBT_SO_SET_ENTRIES:
- ret = do_replace(net, user, len);
- break;
- case EBT_SO_SET_COUNTERS:
- ret = update_counters(net, user, len);
- break;
- default:
- ret = -EINVAL;
- }
- return ret;
-}
-
-static int do_ebt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
-{
- int ret;
- struct ebt_replace tmp;
- struct ebt_table *t;
- struct net *net = sock_net(sk);
-
- if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
- return -EPERM;
-
- if (copy_from_user(&tmp, user, sizeof(tmp)))
- return -EFAULT;
-
- tmp.name[sizeof(tmp.name) - 1] = '\0';
-
- t = find_table_lock(net, tmp.name, &ret, &ebt_mutex);
- if (!t)
- return ret;
-
- switch (cmd) {
- case EBT_SO_GET_INFO:
- case EBT_SO_GET_INIT_INFO:
- if (*len != sizeof(struct ebt_replace)) {
- ret = -EINVAL;
- mutex_unlock(&ebt_mutex);
- break;
- }
- if (cmd == EBT_SO_GET_INFO) {
- tmp.nentries = t->private->nentries;
- tmp.entries_size = t->private->entries_size;
- tmp.valid_hooks = t->valid_hooks;
- } else {
- tmp.nentries = t->table->nentries;
- tmp.entries_size = t->table->entries_size;
- tmp.valid_hooks = t->table->valid_hooks;
- }
- mutex_unlock(&ebt_mutex);
- if (copy_to_user(user, &tmp, *len) != 0) {
- ret = -EFAULT;
- break;
- }
- ret = 0;
- break;
-
- case EBT_SO_GET_ENTRIES:
- case EBT_SO_GET_INIT_ENTRIES:
- ret = copy_everything_to_user(t, user, len, cmd);
- mutex_unlock(&ebt_mutex);
- break;
-
- default:
- mutex_unlock(&ebt_mutex);
- ret = -EINVAL;
- }
-
- return ret;
-}
-
#ifdef CONFIG_COMPAT
/* 32 bit-userspace compatibility definitions. */
struct compat_ebt_replace {
@@ -2314,28 +2234,6 @@ static int compat_update_counters(struct net *net, void __user *user,
hlp.num_counters, user, len);
}
-static int compat_do_ebt_set_ctl(struct sock *sk,
- int cmd, void __user *user, unsigned int len)
-{
- int ret;
- struct net *net = sock_net(sk);
-
- if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
- return -EPERM;
-
- switch (cmd) {
- case EBT_SO_SET_ENTRIES:
- ret = compat_do_replace(net, user, len);
- break;
- case EBT_SO_SET_COUNTERS:
- ret = compat_update_counters(net, user, len);
- break;
- default:
- ret = -EINVAL;
- }
- return ret;
-}
-
static int compat_do_ebt_get_ctl(struct sock *sk, int cmd,
void __user *user, int *len)
{
@@ -2344,14 +2242,6 @@ static int compat_do_ebt_get_ctl(struct sock *sk, int cmd,
struct ebt_table *t;
struct net *net = sock_net(sk);
- if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
- return -EPERM;
-
- /* try real handler in case userland supplied needed padding */
- if ((cmd == EBT_SO_GET_INFO ||
- cmd == EBT_SO_GET_INIT_INFO) && *len != sizeof(tmp))
- return do_ebt_get_ctl(sk, cmd, user, len);
-
if (copy_from_user(&tmp, user, sizeof(tmp)))
return -EFAULT;
@@ -2413,20 +2303,112 @@ static int compat_do_ebt_get_ctl(struct sock *sk, int cmd,
}
#endif
+static int do_ebt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
+{
+ struct net *net = sock_net(sk);
+ struct ebt_replace tmp;
+ struct ebt_table *t;
+ int ret;
+
+ if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
+ return -EPERM;
+
+#ifdef CONFIG_COMPAT
+ /* try real handler in case userland supplied needed padding */
+ if (in_compat_syscall() &&
+ ((cmd != EBT_SO_GET_INFO && cmd != EBT_SO_GET_INIT_INFO) ||
+ *len != sizeof(tmp)))
+ return compat_do_ebt_get_ctl(sk, cmd, user, len);
+#endif
+
+ if (copy_from_user(&tmp, user, sizeof(tmp)))
+ return -EFAULT;
+
+ tmp.name[sizeof(tmp.name) - 1] = '\0';
+
+ t = find_table_lock(net, tmp.name, &ret, &ebt_mutex);
+ if (!t)
+ return ret;
+
+ switch (cmd) {
+ case EBT_SO_GET_INFO:
+ case EBT_SO_GET_INIT_INFO:
+ if (*len != sizeof(struct ebt_replace)) {
+ ret = -EINVAL;
+ mutex_unlock(&ebt_mutex);
+ break;
+ }
+ if (cmd == EBT_SO_GET_INFO) {
+ tmp.nentries = t->private->nentries;
+ tmp.entries_size = t->private->entries_size;
+ tmp.valid_hooks = t->valid_hooks;
+ } else {
+ tmp.nentries = t->table->nentries;
+ tmp.entries_size = t->table->entries_size;
+ tmp.valid_hooks = t->table->valid_hooks;
+ }
+ mutex_unlock(&ebt_mutex);
+ if (copy_to_user(user, &tmp, *len) != 0) {
+ ret = -EFAULT;
+ break;
+ }
+ ret = 0;
+ break;
+
+ case EBT_SO_GET_ENTRIES:
+ case EBT_SO_GET_INIT_ENTRIES:
+ ret = copy_everything_to_user(t, user, len, cmd);
+ mutex_unlock(&ebt_mutex);
+ break;
+
+ default:
+ mutex_unlock(&ebt_mutex);
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static int do_ebt_set_ctl(struct sock *sk, int cmd, void __user *user,
+ unsigned int len)
+{
+ struct net *net = sock_net(sk);
+ int ret;
+
+ if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
+ return -EPERM;
+
+ switch (cmd) {
+ case EBT_SO_SET_ENTRIES:
+#ifdef CONFIG_COMPAT
+ if (in_compat_syscall())
+ ret = compat_do_replace(net, user, len);
+ else
+#endif
+ ret = do_replace(net, user, len);
+ break;
+ case EBT_SO_SET_COUNTERS:
+#ifdef CONFIG_COMPAT
+ if (in_compat_syscall())
+ ret = compat_update_counters(net, user, len);
+ else
+#endif
+ ret = update_counters(net, user, len);
+ break;
+ default:
+ ret = -EINVAL;
+ }
+ return ret;
+}
+
static struct nf_sockopt_ops ebt_sockopts = {
.pf = PF_INET,
.set_optmin = EBT_BASE_CTL,
.set_optmax = EBT_SO_SET_MAX + 1,
.set = do_ebt_set_ctl,
-#ifdef CONFIG_COMPAT
- .compat_set = compat_do_ebt_set_ctl,
-#endif
.get_optmin = EBT_BASE_CTL,
.get_optmax = EBT_SO_GET_MAX + 1,
.get = do_ebt_get_ctl,
-#ifdef CONFIG_COMPAT
- .compat_get = compat_do_ebt_get_ctl,
-#endif
.owner = THIS_MODULE,
};
--
2.27.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 11/22] netfilter: remove the compat_{get,set} methods
2020-07-17 6:23 sockopt cleanups Christoph Hellwig
` (9 preceding siblings ...)
2020-07-17 6:23 ` [PATCH 10/22] netfilter/ebtables: " Christoph Hellwig
@ 2020-07-17 6:23 ` Christoph Hellwig
2020-07-17 6:23 ` [PATCH 12/22] netfilter: remove the compat argument to xt_copy_counters_from_user Christoph Hellwig
` (11 subsequent siblings)
22 siblings, 0 replies; 27+ messages in thread
From: Christoph Hellwig @ 2020-07-17 6:23 UTC (permalink / raw)
To: David S. Miller
Cc: Alexei Starovoitov, Daniel Borkmann, Chas Williams,
Pablo Neira Ayuso, Jozsef Kadlecsik, Florian Westphal,
Alexey Kuznetsov, Hideaki YOSHIFUJI, linux-kernel, netdev, bpf,
netfilter-devel, linux-sctp, linux-arch, linux-bluetooth, bridge,
linux-can, dccp, linux-wpan, mptcp
All instances handle compat sockopts via in_compat_syscall() now, so
remove the compat_{get,set} methods as well as the
compat_nf_{get,set}sockopt wrappers.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
include/linux/netfilter.h | 14 -------------
net/ipv4/ip_sockglue.c | 5 ++---
net/ipv6/ipv6_sockglue.c | 5 ++---
net/netfilter/nf_sockopt.c | 42 --------------------------------------
4 files changed, 4 insertions(+), 62 deletions(-)
diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h
index eb312e7ca36ee5..711b4d4486f042 100644
--- a/include/linux/netfilter.h
+++ b/include/linux/netfilter.h
@@ -164,17 +164,9 @@ struct nf_sockopt_ops {
int set_optmin;
int set_optmax;
int (*set)(struct sock *sk, int optval, void __user *user, unsigned int len);
-#ifdef CONFIG_COMPAT
- int (*compat_set)(struct sock *sk, int optval,
- void __user *user, unsigned int len);
-#endif
int get_optmin;
int get_optmax;
int (*get)(struct sock *sk, int optval, void __user *user, int *len);
-#ifdef CONFIG_COMPAT
- int (*compat_get)(struct sock *sk, int optval,
- void __user *user, int *len);
-#endif
/* Use the module struct to lock set/get code in place */
struct module *owner;
};
@@ -350,12 +342,6 @@ int nf_setsockopt(struct sock *sk, u_int8_t pf, int optval, char __user *opt,
unsigned int len);
int nf_getsockopt(struct sock *sk, u_int8_t pf, int optval, char __user *opt,
int *len);
-#ifdef CONFIG_COMPAT
-int compat_nf_setsockopt(struct sock *sk, u_int8_t pf, int optval,
- char __user *opt, unsigned int len);
-int compat_nf_getsockopt(struct sock *sk, u_int8_t pf, int optval,
- char __user *opt, int *len);
-#endif
struct flowi;
struct nf_queue_entry;
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index 84ec3703c90916..95f4248c6fc5ed 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -1446,8 +1446,7 @@ int compat_ip_setsockopt(struct sock *sk, int level, int optname,
optname != IP_IPSEC_POLICY &&
optname != IP_XFRM_POLICY &&
!ip_mroute_opt(optname))
- err = compat_nf_setsockopt(sk, PF_INET, optname, optval,
- optlen);
+ err = nf_setsockopt(sk, PF_INET, optname, optval, optlen);
#endif
return err;
}
@@ -1821,7 +1820,7 @@ int compat_ip_getsockopt(struct sock *sk, int level, int optname,
if (get_user(len, optlen))
return -EFAULT;
- err = compat_nf_getsockopt(sk, PF_INET, optname, optval, &len);
+ err = nf_getsockopt(sk, PF_INET, optname, optval, &len);
if (err >= 0)
err = put_user(len, optlen);
return err;
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index 6ab44ec2c369da..6adfbdcb7979bd 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -1030,8 +1030,7 @@ int compat_ipv6_setsockopt(struct sock *sk, int level, int optname,
/* we need to exclude all possible ENOPROTOOPTs except default case */
if (err == -ENOPROTOOPT && optname != IPV6_IPSEC_POLICY &&
optname != IPV6_XFRM_POLICY)
- err = compat_nf_setsockopt(sk, PF_INET6, optname, optval,
- optlen);
+ err = nf_setsockopt(sk, PF_INET6, optname, optval, optlen);
#endif
return err;
}
@@ -1531,7 +1530,7 @@ int compat_ipv6_getsockopt(struct sock *sk, int level, int optname,
if (get_user(len, optlen))
return -EFAULT;
- err = compat_nf_getsockopt(sk, PF_INET6, optname, optval, &len);
+ err = nf_getsockopt(sk, PF_INET6, optname, optval, &len);
if (err >= 0)
err = put_user(len, optlen);
}
diff --git a/net/netfilter/nf_sockopt.c b/net/netfilter/nf_sockopt.c
index 46cb3786e0ec5c..02870993d335c9 100644
--- a/net/netfilter/nf_sockopt.c
+++ b/net/netfilter/nf_sockopt.c
@@ -122,45 +122,3 @@ int nf_getsockopt(struct sock *sk, u_int8_t pf, int val, char __user *opt,
return nf_sockopt(sk, pf, val, opt, len, 1);
}
EXPORT_SYMBOL(nf_getsockopt);
-
-#ifdef CONFIG_COMPAT
-static int compat_nf_sockopt(struct sock *sk, u_int8_t pf, int val,
- char __user *opt, int *len, int get)
-{
- struct nf_sockopt_ops *ops;
- int ret;
-
- ops = nf_sockopt_find(sk, pf, val, get);
- if (IS_ERR(ops))
- return PTR_ERR(ops);
-
- if (get) {
- if (ops->compat_get)
- ret = ops->compat_get(sk, val, opt, len);
- else
- ret = ops->get(sk, val, opt, len);
- } else {
- if (ops->compat_set)
- ret = ops->compat_set(sk, val, opt, *len);
- else
- ret = ops->set(sk, val, opt, *len);
- }
-
- module_put(ops->owner);
- return ret;
-}
-
-int compat_nf_setsockopt(struct sock *sk, u_int8_t pf,
- int val, char __user *opt, unsigned int len)
-{
- return compat_nf_sockopt(sk, pf, val, opt, &len, 0);
-}
-EXPORT_SYMBOL(compat_nf_setsockopt);
-
-int compat_nf_getsockopt(struct sock *sk, u_int8_t pf,
- int val, char __user *opt, int *len)
-{
- return compat_nf_sockopt(sk, pf, val, opt, len, 1);
-}
-EXPORT_SYMBOL(compat_nf_getsockopt);
-#endif
--
2.27.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 12/22] netfilter: remove the compat argument to xt_copy_counters_from_user
2020-07-17 6:23 sockopt cleanups Christoph Hellwig
` (10 preceding siblings ...)
2020-07-17 6:23 ` [PATCH 11/22] netfilter: remove the compat_{get,set} methods Christoph Hellwig
@ 2020-07-17 6:23 ` Christoph Hellwig
2020-07-17 6:23 ` [PATCH 13/22] netfilter: split nf_sockopt Christoph Hellwig
` (10 subsequent siblings)
22 siblings, 0 replies; 27+ messages in thread
From: Christoph Hellwig @ 2020-07-17 6:23 UTC (permalink / raw)
To: David S. Miller
Cc: Alexei Starovoitov, Daniel Borkmann, Chas Williams,
Pablo Neira Ayuso, Jozsef Kadlecsik, Florian Westphal,
Alexey Kuznetsov, Hideaki YOSHIFUJI, linux-kernel, netdev, bpf,
netfilter-devel, linux-sctp, linux-arch, linux-bluetooth, bridge,
linux-can, dccp, linux-wpan, mptcp
Lift the in_compat_syscall() from the callers instead.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
include/linux/netfilter/x_tables.h | 2 +-
net/ipv4/netfilter/arp_tables.c | 3 +--
net/ipv4/netfilter/ip_tables.c | 3 +--
net/ipv6/netfilter/ip6_tables.c | 3 +--
net/netfilter/x_tables.c | 9 ++++-----
5 files changed, 8 insertions(+), 12 deletions(-)
diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h
index 5da88451853b28..b8b943ee7b8b66 100644
--- a/include/linux/netfilter/x_tables.h
+++ b/include/linux/netfilter/x_tables.h
@@ -302,7 +302,7 @@ int xt_data_to_user(void __user *dst, const void *src,
int usersize, int size, int aligned_size);
void *xt_copy_counters_from_user(const void __user *user, unsigned int len,
- struct xt_counters_info *info, bool compat);
+ struct xt_counters_info *info);
struct xt_counters *xt_counters_alloc(unsigned int counters);
struct xt_table *xt_register_table(struct net *net,
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index 15807fb4a65f3e..2c8a4dad39d748 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -1008,8 +1008,7 @@ static int do_add_counters(struct net *net, const void __user *user,
struct arpt_entry *iter;
unsigned int addend;
- paddc = xt_copy_counters_from_user(user, len, &tmp,
- in_compat_syscall());
+ paddc = xt_copy_counters_from_user(user, len, &tmp);
if (IS_ERR(paddc))
return PTR_ERR(paddc);
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index fbfad38f397949..161901dd1cae7f 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -1163,8 +1163,7 @@ do_add_counters(struct net *net, const void __user *user,
struct ipt_entry *iter;
unsigned int addend;
- paddc = xt_copy_counters_from_user(user, len, &tmp,
- in_compat_syscall());
+ paddc = xt_copy_counters_from_user(user, len, &tmp);
if (IS_ERR(paddc))
return PTR_ERR(paddc);
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 96c48e91e6c7f7..fd1f8f93123188 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -1179,8 +1179,7 @@ do_add_counters(struct net *net, const void __user *user, unsigned int len)
struct ip6t_entry *iter;
unsigned int addend;
- paddc = xt_copy_counters_from_user(user, len, &tmp,
- in_compat_syscall());
+ paddc = xt_copy_counters_from_user(user, len, &tmp);
if (IS_ERR(paddc))
return PTR_ERR(paddc);
t = xt_find_table_lock(net, AF_INET6, tmp.name);
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
index 99a468be4a59fb..32bab45af7e415 100644
--- a/net/netfilter/x_tables.c
+++ b/net/netfilter/x_tables.c
@@ -1033,15 +1033,14 @@ EXPORT_SYMBOL_GPL(xt_check_target);
* @user: src pointer to userspace memory
* @len: alleged size of userspace memory
* @info: where to store the xt_counters_info metadata
- * @compat: true if we setsockopt call is done by 32bit task on 64bit kernel
*
* Copies counter meta data from @user and stores it in @info.
*
* vmallocs memory to hold the counters, then copies the counter data
* from @user to the new memory and returns a pointer to it.
*
- * If @compat is true, @info gets converted automatically to the 64bit
- * representation.
+ * If called from a compat syscall, @info gets converted automatically to the
+ * 64bit representation.
*
* The metadata associated with the counters is stored in @info.
*
@@ -1049,13 +1048,13 @@ EXPORT_SYMBOL_GPL(xt_check_target);
* If IS_ERR is false, caller has to vfree the pointer.
*/
void *xt_copy_counters_from_user(const void __user *user, unsigned int len,
- struct xt_counters_info *info, bool compat)
+ struct xt_counters_info *info)
{
void *mem;
u64 size;
#ifdef CONFIG_COMPAT
- if (compat) {
+ if (in_compat_syscall()) {
/* structures only differ in size due to alignment */
struct compat_xt_counters_info compat_tmp;
--
2.27.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 13/22] netfilter: split nf_sockopt
2020-07-17 6:23 sockopt cleanups Christoph Hellwig
` (11 preceding siblings ...)
2020-07-17 6:23 ` [PATCH 12/22] netfilter: remove the compat argument to xt_copy_counters_from_user Christoph Hellwig
@ 2020-07-17 6:23 ` Christoph Hellwig
2020-07-17 6:23 ` [PATCH 14/22] net/ipv4: factor out MCAST_MSFILTER getsockopt helpers Christoph Hellwig
` (9 subsequent siblings)
22 siblings, 0 replies; 27+ messages in thread
From: Christoph Hellwig @ 2020-07-17 6:23 UTC (permalink / raw)
To: David S. Miller
Cc: Alexei Starovoitov, Daniel Borkmann, Chas Williams,
Pablo Neira Ayuso, Jozsef Kadlecsik, Florian Westphal,
Alexey Kuznetsov, Hideaki YOSHIFUJI, linux-kernel, netdev, bpf,
netfilter-devel, linux-sctp, linux-arch, linux-bluetooth, bridge,
linux-can, dccp, linux-wpan, mptcp
Split nf_sockopt into a getsockopt and setsockopt side as they share
very little code.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
net/netfilter/nf_sockopt.c | 30 +++++++++++++-----------------
1 file changed, 13 insertions(+), 17 deletions(-)
diff --git a/net/netfilter/nf_sockopt.c b/net/netfilter/nf_sockopt.c
index 02870993d335c9..90469b1f628a8e 100644
--- a/net/netfilter/nf_sockopt.c
+++ b/net/netfilter/nf_sockopt.c
@@ -89,36 +89,32 @@ static struct nf_sockopt_ops *nf_sockopt_find(struct sock *sk, u_int8_t pf,
return ops;
}
-/* Call get/setsockopt() */
-static int nf_sockopt(struct sock *sk, u_int8_t pf, int val,
- char __user *opt, int *len, int get)
+int nf_setsockopt(struct sock *sk, u_int8_t pf, int val, char __user *opt,
+ unsigned int len)
{
struct nf_sockopt_ops *ops;
int ret;
- ops = nf_sockopt_find(sk, pf, val, get);
+ ops = nf_sockopt_find(sk, pf, val, 0);
if (IS_ERR(ops))
return PTR_ERR(ops);
-
- if (get)
- ret = ops->get(sk, val, opt, len);
- else
- ret = ops->set(sk, val, opt, *len);
-
+ ret = ops->set(sk, val, opt, len);
module_put(ops->owner);
return ret;
}
-
-int nf_setsockopt(struct sock *sk, u_int8_t pf, int val, char __user *opt,
- unsigned int len)
-{
- return nf_sockopt(sk, pf, val, opt, &len, 0);
-}
EXPORT_SYMBOL(nf_setsockopt);
int nf_getsockopt(struct sock *sk, u_int8_t pf, int val, char __user *opt,
int *len)
{
- return nf_sockopt(sk, pf, val, opt, len, 1);
+ struct nf_sockopt_ops *ops;
+ int ret;
+
+ ops = nf_sockopt_find(sk, pf, val, 1);
+ if (IS_ERR(ops))
+ return PTR_ERR(ops);
+ ret = ops->get(sk, val, opt, len);
+ module_put(ops->owner);
+ return ret;
}
EXPORT_SYMBOL(nf_getsockopt);
--
2.27.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 14/22] net/ipv4: factor out MCAST_MSFILTER getsockopt helpers
2020-07-17 6:23 sockopt cleanups Christoph Hellwig
` (12 preceding siblings ...)
2020-07-17 6:23 ` [PATCH 13/22] netfilter: split nf_sockopt Christoph Hellwig
@ 2020-07-17 6:23 ` Christoph Hellwig
2020-07-17 6:23 ` [PATCH 15/22] net/ipv4: factor out MCAST_MSFILTER setsockopt helpers Christoph Hellwig
` (8 subsequent siblings)
22 siblings, 0 replies; 27+ messages in thread
From: Christoph Hellwig @ 2020-07-17 6:23 UTC (permalink / raw)
To: David S. Miller
Cc: Alexei Starovoitov, Daniel Borkmann, Chas Williams,
Pablo Neira Ayuso, Jozsef Kadlecsik, Florian Westphal,
Alexey Kuznetsov, Hideaki YOSHIFUJI, linux-kernel, netdev, bpf,
netfilter-devel, linux-sctp, linux-arch, linux-bluetooth, bridge,
linux-can, dccp, linux-wpan, mptcp
Factor out one helper each for getting the native and compat
version of the MCAST_MSFILTER option.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
net/ipv4/ip_sockglue.c | 131 ++++++++++++++++++++++-------------------
1 file changed, 70 insertions(+), 61 deletions(-)
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index 95f4248c6fc5ed..70d32c9476a2e3 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -1468,6 +1468,74 @@ static bool getsockopt_needs_rtnl(int optname)
return false;
}
+static int ip_get_mcast_msfilter(struct sock *sk, void __user *optval,
+ int __user *optlen, int len)
+{
+ const int size0 = offsetof(struct group_filter, gf_slist);
+ struct group_filter __user *p = optval;
+ struct group_filter gsf;
+ int num;
+ int err;
+
+ if (len < size0)
+ return -EINVAL;
+ if (copy_from_user(&gsf, p, size0))
+ return -EFAULT;
+
+ num = gsf.gf_numsrc;
+ err = ip_mc_gsfget(sk, &gsf, p->gf_slist);
+ if (err)
+ return err;
+ if (gsf.gf_numsrc < num)
+ num = gsf.gf_numsrc;
+ if (put_user(GROUP_FILTER_SIZE(num), optlen) ||
+ copy_to_user(p, &gsf, size0))
+ return -EFAULT;
+ return 0;
+}
+
+#ifdef CONFIG_COMPAT
+static int compat_ip_get_mcast_msfilter(struct sock *sk, void __user *optval,
+ int __user *optlen)
+{
+ const int size0 = offsetof(struct compat_group_filter, gf_slist);
+ struct compat_group_filter __user *p = optval;
+ struct compat_group_filter gf32;
+ struct group_filter gf;
+ int len, err;
+ int num;
+
+ if (get_user(len, optlen))
+ return -EFAULT;
+ if (len < size0)
+ return -EINVAL;
+
+ if (copy_from_user(&gf32, p, size0))
+ return -EFAULT;
+
+ gf.gf_interface = gf32.gf_interface;
+ gf.gf_fmode = gf32.gf_fmode;
+ num = gf.gf_numsrc = gf32.gf_numsrc;
+ gf.gf_group = gf32.gf_group;
+
+ rtnl_lock();
+ lock_sock(sk);
+ err = ip_mc_gsfget(sk, &gf, p->gf_slist);
+ release_sock(sk);
+ rtnl_unlock();
+ if (err)
+ return err;
+ if (gf.gf_numsrc < num)
+ num = gf.gf_numsrc;
+ len = GROUP_FILTER_SIZE(num) - (sizeof(gf) - sizeof(gf32));
+ if (put_user(len, optlen) ||
+ put_user(gf.gf_fmode, &p->gf_fmode) ||
+ put_user(gf.gf_numsrc, &p->gf_numsrc))
+ return -EFAULT;
+ return 0;
+}
+#endif
+
static int do_ip_getsockopt(struct sock *sk, int level, int optname,
char __user *optval, int __user *optlen, unsigned int flags)
{
@@ -1626,31 +1694,8 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname,
goto out;
}
case MCAST_MSFILTER:
- {
- struct group_filter __user *p = (void __user *)optval;
- struct group_filter gsf;
- const int size0 = offsetof(struct group_filter, gf_slist);
- int num;
-
- if (len < size0) {
- err = -EINVAL;
- goto out;
- }
- if (copy_from_user(&gsf, p, size0)) {
- err = -EFAULT;
- goto out;
- }
- num = gsf.gf_numsrc;
- err = ip_mc_gsfget(sk, &gsf, p->gf_slist);
- if (err)
- goto out;
- if (gsf.gf_numsrc < num)
- num = gsf.gf_numsrc;
- if (put_user(GROUP_FILTER_SIZE(num), optlen) ||
- copy_to_user(p, &gsf, size0))
- err = -EFAULT;
+ err = ip_get_mcast_msfilter(sk, optval, optlen, len);
goto out;
- }
case IP_MULTICAST_ALL:
val = inet->mc_all;
break;
@@ -1762,45 +1807,9 @@ int compat_ip_getsockopt(struct sock *sk, int level, int optname,
int err;
if (optname == MCAST_MSFILTER) {
- const int size0 = offsetof(struct compat_group_filter, gf_slist);
- struct compat_group_filter __user *p = (void __user *)optval;
- struct compat_group_filter gf32;
- struct group_filter gf;
- int ulen, err;
- int num;
-
if (level != SOL_IP)
return -EOPNOTSUPP;
-
- if (get_user(ulen, optlen))
- return -EFAULT;
-
- if (ulen < size0)
- return -EINVAL;
-
- if (copy_from_user(&gf32, p, size0))
- return -EFAULT;
-
- gf.gf_interface = gf32.gf_interface;
- gf.gf_fmode = gf32.gf_fmode;
- num = gf.gf_numsrc = gf32.gf_numsrc;
- gf.gf_group = gf32.gf_group;
-
- rtnl_lock();
- lock_sock(sk);
- err = ip_mc_gsfget(sk, &gf, p->gf_slist);
- release_sock(sk);
- rtnl_unlock();
- if (err)
- return err;
- if (gf.gf_numsrc < num)
- num = gf.gf_numsrc;
- ulen = GROUP_FILTER_SIZE(num) - (sizeof(gf) - sizeof(gf32));
- if (put_user(ulen, optlen) ||
- put_user(gf.gf_fmode, &p->gf_fmode) ||
- put_user(gf.gf_numsrc, &p->gf_numsrc))
- return -EFAULT;
- return 0;
+ return compat_ip_get_mcast_msfilter(sk, optval, optlen);
}
err = do_ip_getsockopt(sk, level, optname, optval, optlen,
--
2.27.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 15/22] net/ipv4: factor out MCAST_MSFILTER setsockopt helpers
2020-07-17 6:23 sockopt cleanups Christoph Hellwig
` (13 preceding siblings ...)
2020-07-17 6:23 ` [PATCH 14/22] net/ipv4: factor out MCAST_MSFILTER getsockopt helpers Christoph Hellwig
@ 2020-07-17 6:23 ` Christoph Hellwig
2020-07-17 6:23 ` [PATCH 16/22] net/ipv4: factor out mcast join/leave " Christoph Hellwig
` (7 subsequent siblings)
22 siblings, 0 replies; 27+ messages in thread
From: Christoph Hellwig @ 2020-07-17 6:23 UTC (permalink / raw)
To: David S. Miller
Cc: Alexei Starovoitov, Daniel Borkmann, Chas Williams,
Pablo Neira Ayuso, Jozsef Kadlecsik, Florian Westphal,
Alexey Kuznetsov, Hideaki YOSHIFUJI, linux-kernel, netdev, bpf,
netfilter-devel, linux-sctp, linux-arch, linux-bluetooth, bridge,
linux-can, dccp, linux-wpan, mptcp
Factor out one helper each for setting the native and compat
version of the MCAST_MSFILTER option.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
net/ipv4/ip_sockglue.c | 162 ++++++++++++++++++++++-------------------
1 file changed, 86 insertions(+), 76 deletions(-)
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index 70d32c9476a2e3..b587dee006f882 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -722,6 +722,90 @@ static int do_mcast_group_source(struct sock *sk, int optname,
return ip_mc_source(add, omode, sk, &mreqs, greqs->gsr_interface);
}
+static int ip_set_mcast_msfilter(struct sock *sk, void __user *optval,
+ int optlen)
+{
+ struct group_filter *gsf = NULL;
+ int err;
+
+ if (optlen < GROUP_FILTER_SIZE(0))
+ return -EINVAL;
+ if (optlen > sysctl_optmem_max)
+ return -ENOBUFS;
+
+ gsf = memdup_user(optval, optlen);
+ if (IS_ERR(gsf))
+ return PTR_ERR(gsf);
+
+ /* numsrc >= (4G-140)/128 overflow in 32 bits */
+ err = -ENOBUFS;
+ if (gsf->gf_numsrc >= 0x1ffffff ||
+ gsf->gf_numsrc > sock_net(sk)->ipv4.sysctl_igmp_max_msf)
+ goto out_free_gsf;
+
+ err = -EINVAL;
+ if (GROUP_FILTER_SIZE(gsf->gf_numsrc) > optlen)
+ goto out_free_gsf;
+
+ err = set_mcast_msfilter(sk, gsf->gf_interface, gsf->gf_numsrc,
+ gsf->gf_fmode, &gsf->gf_group, gsf->gf_slist);
+out_free_gsf:
+ kfree(gsf);
+ return err;
+}
+
+#ifdef CONFIG_COMPAT
+static int compat_ip_set_mcast_msfilter(struct sock *sk, void __user *optval,
+ int optlen)
+{
+ const int size0 = offsetof(struct compat_group_filter, gf_slist);
+ struct compat_group_filter *gf32;
+ unsigned int n;
+ void *p;
+ int err;
+
+ if (optlen < size0)
+ return -EINVAL;
+ if (optlen > sysctl_optmem_max - 4)
+ return -ENOBUFS;
+
+ p = kmalloc(optlen + 4, GFP_KERNEL);
+ if (!p)
+ return -ENOMEM;
+ gf32 = p + 4; /* we want ->gf_group and ->gf_slist aligned */
+
+ err = -EFAULT;
+ if (copy_from_user(gf32, optval, optlen))
+ goto out_free_gsf;
+
+ /* numsrc >= (4G-140)/128 overflow in 32 bits */
+ n = gf32->gf_numsrc;
+ err = -ENOBUFS;
+ if (n >= 0x1ffffff)
+ goto out_free_gsf;
+
+ err = -EINVAL;
+ if (offsetof(struct compat_group_filter, gf_slist[n]) > optlen)
+ goto out_free_gsf;
+
+ rtnl_lock();
+ lock_sock(sk);
+
+ /* numsrc >= (4G-140)/128 overflow in 32 bits */
+ err = -ENOBUFS;
+ if (n > sock_net(sk)->ipv4.sysctl_igmp_max_msf)
+ goto out_unlock;
+ err = set_mcast_msfilter(sk, gf32->gf_interface, n, gf32->gf_fmode,
+ &gf32->gf_group, gf32->gf_slist);
+out_unlock:
+ release_sock(sk);
+ rtnl_unlock();
+out_free_gsf:
+ kfree(p);
+ return err;
+}
+#endif
+
static int do_ip_setsockopt(struct sock *sk, int level,
int optname, char __user *optval, unsigned int optlen)
{
@@ -1167,37 +1251,8 @@ static int do_ip_setsockopt(struct sock *sk, int level,
break;
}
case MCAST_MSFILTER:
- {
- struct group_filter *gsf = NULL;
-
- if (optlen < GROUP_FILTER_SIZE(0))
- goto e_inval;
- if (optlen > sysctl_optmem_max) {
- err = -ENOBUFS;
- break;
- }
- gsf = memdup_user(optval, optlen);
- if (IS_ERR(gsf)) {
- err = PTR_ERR(gsf);
- break;
- }
- /* numsrc >= (4G-140)/128 overflow in 32 bits */
- if (gsf->gf_numsrc >= 0x1ffffff ||
- gsf->gf_numsrc > net->ipv4.sysctl_igmp_max_msf) {
- err = -ENOBUFS;
- goto mc_msf_out;
- }
- if (GROUP_FILTER_SIZE(gsf->gf_numsrc) > optlen) {
- err = -EINVAL;
- goto mc_msf_out;
- }
- err = set_mcast_msfilter(sk, gsf->gf_interface,
- gsf->gf_numsrc, gsf->gf_fmode,
- &gsf->gf_group, gsf->gf_slist);
-mc_msf_out:
- kfree(gsf);
+ err = ip_set_mcast_msfilter(sk, optval, optlen);
break;
- }
case IP_MULTICAST_ALL:
if (optlen < 1)
goto e_inval;
@@ -1391,52 +1446,7 @@ int compat_ip_setsockopt(struct sock *sk, int level, int optname,
return err;
}
case MCAST_MSFILTER:
- {
- const int size0 = offsetof(struct compat_group_filter, gf_slist);
- struct compat_group_filter *gf32;
- unsigned int n;
- void *p;
-
- if (optlen < size0)
- return -EINVAL;
- if (optlen > sysctl_optmem_max - 4)
- return -ENOBUFS;
-
- p = kmalloc(optlen + 4, GFP_KERNEL);
- if (!p)
- return -ENOMEM;
- gf32 = p + 4; /* we want ->gf_group and ->gf_slist aligned */
- if (copy_from_user(gf32, optval, optlen)) {
- err = -EFAULT;
- goto mc_msf_out;
- }
-
- n = gf32->gf_numsrc;
- /* numsrc >= (4G-140)/128 overflow in 32 bits */
- if (n >= 0x1ffffff) {
- err = -ENOBUFS;
- goto mc_msf_out;
- }
- if (offsetof(struct compat_group_filter, gf_slist[n]) > optlen) {
- err = -EINVAL;
- goto mc_msf_out;
- }
-
- rtnl_lock();
- lock_sock(sk);
- /* numsrc >= (4G-140)/128 overflow in 32 bits */
- if (n > sock_net(sk)->ipv4.sysctl_igmp_max_msf)
- err = -ENOBUFS;
- else
- err = set_mcast_msfilter(sk, gf32->gf_interface,
- n, gf32->gf_fmode,
- &gf32->gf_group, gf32->gf_slist);
- release_sock(sk);
- rtnl_unlock();
-mc_msf_out:
- kfree(p);
- return err;
- }
+ return compat_ip_set_mcast_msfilter(sk, optval, optlen);
}
err = do_ip_setsockopt(sk, level, optname, optval, optlen);
--
2.27.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 16/22] net/ipv4: factor out mcast join/leave setsockopt helpers
2020-07-17 6:23 sockopt cleanups Christoph Hellwig
` (14 preceding siblings ...)
2020-07-17 6:23 ` [PATCH 15/22] net/ipv4: factor out MCAST_MSFILTER setsockopt helpers Christoph Hellwig
@ 2020-07-17 6:23 ` Christoph Hellwig
2020-07-17 6:23 ` [PATCH 17/22] net/ipv4: remove compat_ip_{get,set}sockopt Christoph Hellwig
` (6 subsequent siblings)
22 siblings, 0 replies; 27+ messages in thread
From: Christoph Hellwig @ 2020-07-17 6:23 UTC (permalink / raw)
To: David S. Miller
Cc: Alexei Starovoitov, Daniel Borkmann, Chas Williams,
Pablo Neira Ayuso, Jozsef Kadlecsik, Florian Westphal,
Alexey Kuznetsov, Hideaki YOSHIFUJI, linux-kernel, netdev, bpf,
netfilter-devel, linux-sctp, linux-arch, linux-bluetooth, bridge,
linux-can, dccp, linux-wpan, mptcp
Factor out one helper each for setting the native and compat
version of the MCAST_MSFILTER option.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
net/ipv4/ip_sockglue.c | 109 +++++++++++++++++++++--------------------
1 file changed, 56 insertions(+), 53 deletions(-)
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index b587dee006f882..73bb88fbe54661 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -806,6 +806,60 @@ static int compat_ip_set_mcast_msfilter(struct sock *sk, void __user *optval,
}
#endif
+static int ip_mcast_join_leave(struct sock *sk, int optname,
+ void __user *optval, int optlen)
+{
+ struct ip_mreqn mreq = { };
+ struct sockaddr_in *psin;
+ struct group_req greq;
+
+ if (optlen < sizeof(struct group_req))
+ return -EINVAL;
+ if (copy_from_user(&greq, optval, sizeof(greq)))
+ return -EFAULT;
+
+ psin = (struct sockaddr_in *)&greq.gr_group;
+ if (psin->sin_family != AF_INET)
+ return -EINVAL;
+ mreq.imr_multiaddr = psin->sin_addr;
+ mreq.imr_ifindex = greq.gr_interface;
+ if (optname == MCAST_JOIN_GROUP)
+ return ip_mc_join_group(sk, &mreq);
+ return ip_mc_leave_group(sk, &mreq);
+}
+
+#ifdef CONFIG_COMPAT
+static int compat_ip_mcast_join_leave(struct sock *sk, int optname,
+ void __user *optval, int optlen)
+{
+ struct compat_group_req greq;
+ struct ip_mreqn mreq = { };
+ struct sockaddr_in *psin;
+ int err;
+
+ if (optlen < sizeof(struct compat_group_req))
+ return -EINVAL;
+ if (copy_from_user(&greq, optval, sizeof(greq)))
+ return -EFAULT;
+
+ psin = (struct sockaddr_in *)&greq.gr_group;
+ if (psin->sin_family != AF_INET)
+ return -EINVAL;
+ mreq.imr_multiaddr = psin->sin_addr;
+ mreq.imr_ifindex = greq.gr_interface;
+
+ rtnl_lock();
+ lock_sock(sk);
+ if (optname == MCAST_JOIN_GROUP)
+ err = ip_mc_join_group(sk, &mreq);
+ else
+ err = ip_mc_leave_group(sk, &mreq);
+ release_sock(sk);
+ rtnl_unlock();
+ return err;
+}
+#endif
+
static int do_ip_setsockopt(struct sock *sk, int level,
int optname, char __user *optval, unsigned int optlen)
{
@@ -1211,29 +1265,8 @@ static int do_ip_setsockopt(struct sock *sk, int level,
}
case MCAST_JOIN_GROUP:
case MCAST_LEAVE_GROUP:
- {
- struct group_req greq;
- struct sockaddr_in *psin;
- struct ip_mreqn mreq;
-
- if (optlen < sizeof(struct group_req))
- goto e_inval;
- err = -EFAULT;
- if (copy_from_user(&greq, optval, sizeof(greq)))
- break;
- psin = (struct sockaddr_in *)&greq.gr_group;
- if (psin->sin_family != AF_INET)
- goto e_inval;
- memset(&mreq, 0, sizeof(mreq));
- mreq.imr_multiaddr = psin->sin_addr;
- mreq.imr_ifindex = greq.gr_interface;
-
- if (optname == MCAST_JOIN_GROUP)
- err = ip_mc_join_group(sk, &mreq);
- else
- err = ip_mc_leave_group(sk, &mreq);
+ err = ip_mcast_join_leave(sk, optname, optval, optlen);
break;
- }
case MCAST_JOIN_SOURCE_GROUP:
case MCAST_LEAVE_SOURCE_GROUP:
case MCAST_BLOCK_SOURCE:
@@ -1389,37 +1422,7 @@ int compat_ip_setsockopt(struct sock *sk, int level, int optname,
switch (optname) {
case MCAST_JOIN_GROUP:
case MCAST_LEAVE_GROUP:
- {
- struct compat_group_req __user *gr32 = (void __user *)optval;
- struct group_req greq;
- struct sockaddr_in *psin = (struct sockaddr_in *)&greq.gr_group;
- struct ip_mreqn mreq;
-
- if (optlen < sizeof(struct compat_group_req))
- return -EINVAL;
-
- if (get_user(greq.gr_interface, &gr32->gr_interface) ||
- copy_from_user(&greq.gr_group, &gr32->gr_group,
- sizeof(greq.gr_group)))
- return -EFAULT;
-
- if (psin->sin_family != AF_INET)
- return -EINVAL;
-
- memset(&mreq, 0, sizeof(mreq));
- mreq.imr_multiaddr = psin->sin_addr;
- mreq.imr_ifindex = greq.gr_interface;
-
- rtnl_lock();
- lock_sock(sk);
- if (optname == MCAST_JOIN_GROUP)
- err = ip_mc_join_group(sk, &mreq);
- else
- err = ip_mc_leave_group(sk, &mreq);
- release_sock(sk);
- rtnl_unlock();
- return err;
- }
+ return compat_ip_mcast_join_leave(sk, optname, optval, optlen);
case MCAST_JOIN_SOURCE_GROUP:
case MCAST_LEAVE_SOURCE_GROUP:
case MCAST_BLOCK_SOURCE:
--
2.27.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 17/22] net/ipv4: remove compat_ip_{get,set}sockopt
2020-07-17 6:23 sockopt cleanups Christoph Hellwig
` (15 preceding siblings ...)
2020-07-17 6:23 ` [PATCH 16/22] net/ipv4: factor out mcast join/leave " Christoph Hellwig
@ 2020-07-17 6:23 ` Christoph Hellwig
2020-07-17 6:23 ` [PATCH 18/22] net/ipv6: factor out MCAST_MSFILTER getsockopt helpers Christoph Hellwig
` (5 subsequent siblings)
22 siblings, 0 replies; 27+ messages in thread
From: Christoph Hellwig @ 2020-07-17 6:23 UTC (permalink / raw)
To: David S. Miller
Cc: Alexei Starovoitov, Daniel Borkmann, Chas Williams,
Pablo Neira Ayuso, Jozsef Kadlecsik, Florian Westphal,
Alexey Kuznetsov, Hideaki YOSHIFUJI, linux-kernel, netdev, bpf,
netfilter-devel, linux-sctp, linux-arch, linux-bluetooth, bridge,
linux-can, dccp, linux-wpan, mptcp
Handle the few cases that need special treatment in-line using
in_compat_syscall().
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
include/net/ip.h | 4 -
net/dccp/ipv4.c | 4 -
net/ipv4/ip_sockglue.c | 214 ++++++++++++-----------------------------
net/ipv4/raw.c | 22 -----
net/ipv4/tcp_ipv4.c | 4 -
net/ipv4/udp.c | 24 -----
net/ipv4/udp_impl.h | 6 --
net/ipv4/udplite.c | 4 -
net/l2tp/l2tp_ip.c | 4 -
net/sctp/protocol.c | 4 -
10 files changed, 61 insertions(+), 229 deletions(-)
diff --git a/include/net/ip.h b/include/net/ip.h
index 862c9545833a95..3d34acc95ca825 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -727,10 +727,6 @@ int ip_setsockopt(struct sock *sk, int level, int optname, char __user *optval,
unsigned int optlen);
int ip_getsockopt(struct sock *sk, int level, int optname, char __user *optval,
int __user *optlen);
-int compat_ip_setsockopt(struct sock *sk, int level, int optname,
- char __user *optval, unsigned int optlen);
-int compat_ip_getsockopt(struct sock *sk, int level, int optname,
- char __user *optval, int __user *optlen);
int ip_ra_control(struct sock *sk, unsigned char on,
void (*destructor)(struct sock *));
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index 316cc5ac0da72b..b91373eb1c7974 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -913,10 +913,6 @@ static const struct inet_connection_sock_af_ops dccp_ipv4_af_ops = {
.getsockopt = ip_getsockopt,
.addr2sockaddr = inet_csk_addr2sockaddr,
.sockaddr_len = sizeof(struct sockaddr_in),
-#ifdef CONFIG_COMPAT
- .compat_setsockopt = compat_ip_setsockopt,
- .compat_getsockopt = compat_ip_getsockopt,
-#endif
};
static int dccp_v4_init_sock(struct sock *sk)
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index 73bb88fbe54661..86b3b9a7cea30d 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -679,20 +679,48 @@ static int set_mcast_msfilter(struct sock *sk, int ifindex,
return -EADDRNOTAVAIL;
}
+static int copy_group_source_from_user(struct group_source_req *greqs,
+ void __user *optval, int optlen)
+{
+ if (in_compat_syscall()) {
+ struct compat_group_source_req gr32;
+
+ if (optlen != sizeof(gr32))
+ return -EINVAL;
+ if (copy_from_user(&gr32, optval, sizeof(gr32)))
+ return -EFAULT;
+ greqs->gsr_interface = gr32.gsr_interface;
+ greqs->gsr_group = gr32.gsr_group;
+ greqs->gsr_source = gr32.gsr_source;
+ } else {
+ if (optlen != sizeof(*greqs))
+ return -EINVAL;
+ if (copy_from_user(greqs, optval, sizeof(*greqs)))
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
static int do_mcast_group_source(struct sock *sk, int optname,
- struct group_source_req *greqs)
+ void __user *optval, int optlen)
{
+ struct group_source_req greqs;
struct ip_mreq_source mreqs;
struct sockaddr_in *psin;
int omode, add, err;
- if (greqs->gsr_group.ss_family != AF_INET ||
- greqs->gsr_source.ss_family != AF_INET)
+ err = copy_group_source_from_user(&greqs, optval, optlen);
+ if (err)
+ return err;
+
+ if (greqs.gsr_group.ss_family != AF_INET ||
+ greqs.gsr_source.ss_family != AF_INET)
return -EADDRNOTAVAIL;
- psin = (struct sockaddr_in *)&greqs->gsr_group;
+ psin = (struct sockaddr_in *)&greqs.gsr_group;
mreqs.imr_multiaddr = psin->sin_addr.s_addr;
- psin = (struct sockaddr_in *)&greqs->gsr_source;
+ psin = (struct sockaddr_in *)&greqs.gsr_source;
mreqs.imr_sourceaddr = psin->sin_addr.s_addr;
mreqs.imr_interface = 0; /* use index for mc_source */
@@ -705,21 +733,21 @@ static int do_mcast_group_source(struct sock *sk, int optname,
} else if (optname == MCAST_JOIN_SOURCE_GROUP) {
struct ip_mreqn mreq;
- psin = (struct sockaddr_in *)&greqs->gsr_group;
+ psin = (struct sockaddr_in *)&greqs.gsr_group;
mreq.imr_multiaddr = psin->sin_addr;
mreq.imr_address.s_addr = 0;
- mreq.imr_ifindex = greqs->gsr_interface;
+ mreq.imr_ifindex = greqs.gsr_interface;
err = ip_mc_join_group_ssm(sk, &mreq, MCAST_INCLUDE);
if (err && err != -EADDRINUSE)
return err;
- greqs->gsr_interface = mreq.imr_ifindex;
+ greqs.gsr_interface = mreq.imr_ifindex;
omode = MCAST_INCLUDE;
add = 1;
} else /* MCAST_LEAVE_SOURCE_GROUP */ {
omode = MCAST_INCLUDE;
add = 0;
}
- return ip_mc_source(add, omode, sk, &mreqs, greqs->gsr_interface);
+ return ip_mc_source(add, omode, sk, &mreqs, greqs.gsr_interface);
}
static int ip_set_mcast_msfilter(struct sock *sk, void __user *optval,
@@ -754,7 +782,6 @@ static int ip_set_mcast_msfilter(struct sock *sk, void __user *optval,
return err;
}
-#ifdef CONFIG_COMPAT
static int compat_ip_set_mcast_msfilter(struct sock *sk, void __user *optval,
int optlen)
{
@@ -788,23 +815,16 @@ static int compat_ip_set_mcast_msfilter(struct sock *sk, void __user *optval,
if (offsetof(struct compat_group_filter, gf_slist[n]) > optlen)
goto out_free_gsf;
- rtnl_lock();
- lock_sock(sk);
-
/* numsrc >= (4G-140)/128 overflow in 32 bits */
err = -ENOBUFS;
if (n > sock_net(sk)->ipv4.sysctl_igmp_max_msf)
- goto out_unlock;
+ goto out_free_gsf;
err = set_mcast_msfilter(sk, gf32->gf_interface, n, gf32->gf_fmode,
&gf32->gf_group, gf32->gf_slist);
-out_unlock:
- release_sock(sk);
- rtnl_unlock();
out_free_gsf:
kfree(p);
return err;
}
-#endif
static int ip_mcast_join_leave(struct sock *sk, int optname,
void __user *optval, int optlen)
@@ -828,14 +848,12 @@ static int ip_mcast_join_leave(struct sock *sk, int optname,
return ip_mc_leave_group(sk, &mreq);
}
-#ifdef CONFIG_COMPAT
static int compat_ip_mcast_join_leave(struct sock *sk, int optname,
void __user *optval, int optlen)
{
struct compat_group_req greq;
struct ip_mreqn mreq = { };
struct sockaddr_in *psin;
- int err;
if (optlen < sizeof(struct compat_group_req))
return -EINVAL;
@@ -848,17 +866,10 @@ static int compat_ip_mcast_join_leave(struct sock *sk, int optname,
mreq.imr_multiaddr = psin->sin_addr;
mreq.imr_ifindex = greq.gr_interface;
- rtnl_lock();
- lock_sock(sk);
if (optname == MCAST_JOIN_GROUP)
- err = ip_mc_join_group(sk, &mreq);
- else
- err = ip_mc_leave_group(sk, &mreq);
- release_sock(sk);
- rtnl_unlock();
- return err;
+ return ip_mc_join_group(sk, &mreq);
+ return ip_mc_leave_group(sk, &mreq);
}
-#endif
static int do_ip_setsockopt(struct sock *sk, int level,
int optname, char __user *optval, unsigned int optlen)
@@ -1265,26 +1276,23 @@ static int do_ip_setsockopt(struct sock *sk, int level,
}
case MCAST_JOIN_GROUP:
case MCAST_LEAVE_GROUP:
- err = ip_mcast_join_leave(sk, optname, optval, optlen);
+ if (in_compat_syscall())
+ err = compat_ip_mcast_join_leave(sk, optname, optval,
+ optlen);
+ else
+ err = ip_mcast_join_leave(sk, optname, optval, optlen);
break;
case MCAST_JOIN_SOURCE_GROUP:
case MCAST_LEAVE_SOURCE_GROUP:
case MCAST_BLOCK_SOURCE:
case MCAST_UNBLOCK_SOURCE:
- {
- struct group_source_req greqs;
-
- if (optlen != sizeof(struct group_source_req))
- goto e_inval;
- if (copy_from_user(&greqs, optval, sizeof(greqs))) {
- err = -EFAULT;
- break;
- }
- err = do_mcast_group_source(sk, optname, &greqs);
+ err = do_mcast_group_source(sk, optname, optval, optlen);
break;
- }
case MCAST_MSFILTER:
- err = ip_set_mcast_msfilter(sk, optval, optlen);
+ if (in_compat_syscall())
+ err = compat_ip_set_mcast_msfilter(sk, optval, optlen);
+ else
+ err = ip_set_mcast_msfilter(sk, optval, optlen);
break;
case IP_MULTICAST_ALL:
if (optlen < 1)
@@ -1410,62 +1418,6 @@ int ip_setsockopt(struct sock *sk, int level,
}
EXPORT_SYMBOL(ip_setsockopt);
-#ifdef CONFIG_COMPAT
-int compat_ip_setsockopt(struct sock *sk, int level, int optname,
- char __user *optval, unsigned int optlen)
-{
- int err;
-
- if (level != SOL_IP)
- return -ENOPROTOOPT;
-
- switch (optname) {
- case MCAST_JOIN_GROUP:
- case MCAST_LEAVE_GROUP:
- return compat_ip_mcast_join_leave(sk, optname, optval, optlen);
- case MCAST_JOIN_SOURCE_GROUP:
- case MCAST_LEAVE_SOURCE_GROUP:
- case MCAST_BLOCK_SOURCE:
- case MCAST_UNBLOCK_SOURCE:
- {
- struct compat_group_source_req __user *gsr32 = (void __user *)optval;
- struct group_source_req greqs;
-
- if (optlen != sizeof(struct compat_group_source_req))
- return -EINVAL;
-
- if (get_user(greqs.gsr_interface, &gsr32->gsr_interface) ||
- copy_from_user(&greqs.gsr_group, &gsr32->gsr_group,
- sizeof(greqs.gsr_group)) ||
- copy_from_user(&greqs.gsr_source, &gsr32->gsr_source,
- sizeof(greqs.gsr_source)))
- return -EFAULT;
-
- rtnl_lock();
- lock_sock(sk);
- err = do_mcast_group_source(sk, optname, &greqs);
- release_sock(sk);
- rtnl_unlock();
- return err;
- }
- case MCAST_MSFILTER:
- return compat_ip_set_mcast_msfilter(sk, optval, optlen);
- }
-
- err = do_ip_setsockopt(sk, level, optname, optval, optlen);
-#ifdef CONFIG_NETFILTER
- /* we need to exclude all possible ENOPROTOOPTs except default case */
- if (err == -ENOPROTOOPT && optname != IP_HDRINCL &&
- optname != IP_IPSEC_POLICY &&
- optname != IP_XFRM_POLICY &&
- !ip_mroute_opt(optname))
- err = nf_setsockopt(sk, PF_INET, optname, optval, optlen);
-#endif
- return err;
-}
-EXPORT_SYMBOL(compat_ip_setsockopt);
-#endif
-
/*
* Get the options. Note for future reference. The GET of IP options gets
* the _received_ ones. The set sets the _sent_ ones.
@@ -1507,22 +1459,18 @@ static int ip_get_mcast_msfilter(struct sock *sk, void __user *optval,
return 0;
}
-#ifdef CONFIG_COMPAT
static int compat_ip_get_mcast_msfilter(struct sock *sk, void __user *optval,
- int __user *optlen)
+ int __user *optlen, int len)
{
const int size0 = offsetof(struct compat_group_filter, gf_slist);
struct compat_group_filter __user *p = optval;
struct compat_group_filter gf32;
struct group_filter gf;
- int len, err;
int num;
+ int err;
- if (get_user(len, optlen))
- return -EFAULT;
if (len < size0)
return -EINVAL;
-
if (copy_from_user(&gf32, p, size0))
return -EFAULT;
@@ -1531,11 +1479,7 @@ static int compat_ip_get_mcast_msfilter(struct sock *sk, void __user *optval,
num = gf.gf_numsrc = gf32.gf_numsrc;
gf.gf_group = gf32.gf_group;
- rtnl_lock();
- lock_sock(sk);
err = ip_mc_gsfget(sk, &gf, p->gf_slist);
- release_sock(sk);
- rtnl_unlock();
if (err)
return err;
if (gf.gf_numsrc < num)
@@ -1547,10 +1491,9 @@ static int compat_ip_get_mcast_msfilter(struct sock *sk, void __user *optval,
return -EFAULT;
return 0;
}
-#endif
static int do_ip_getsockopt(struct sock *sk, int level, int optname,
- char __user *optval, int __user *optlen, unsigned int flags)
+ char __user *optval, int __user *optlen)
{
struct inet_sock *inet = inet_sk(sk);
bool needs_rtnl = getsockopt_needs_rtnl(optname);
@@ -1707,7 +1650,11 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname,
goto out;
}
case MCAST_MSFILTER:
- err = ip_get_mcast_msfilter(sk, optval, optlen, len);
+ if (in_compat_syscall())
+ err = compat_ip_get_mcast_msfilter(sk, optval, optlen,
+ len);
+ else
+ err = ip_get_mcast_msfilter(sk, optval, optlen, len);
goto out;
case IP_MULTICAST_ALL:
val = inet->mc_all;
@@ -1724,7 +1671,7 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname,
msg.msg_control_is_user = true;
msg.msg_control_user = optval;
msg.msg_controllen = len;
- msg.msg_flags = flags;
+ msg.msg_flags = in_compat_syscall() ? MSG_CMSG_COMPAT : 0;
if (inet->cmsg_flags & IP_CMSG_PKTINFO) {
struct in_pktinfo info;
@@ -1788,45 +1735,7 @@ int ip_getsockopt(struct sock *sk, int level,
{
int err;
- err = do_ip_getsockopt(sk, level, optname, optval, optlen, 0);
-#if IS_ENABLED(CONFIG_BPFILTER_UMH)
- if (optname >= BPFILTER_IPT_SO_GET_INFO &&
- optname < BPFILTER_IPT_GET_MAX)
- err = bpfilter_ip_get_sockopt(sk, optname, optval, optlen);
-#endif
-#ifdef CONFIG_NETFILTER
- /* we need to exclude all possible ENOPROTOOPTs except default case */
- if (err == -ENOPROTOOPT && optname != IP_PKTOPTIONS &&
- !ip_mroute_opt(optname)) {
- int len;
-
- if (get_user(len, optlen))
- return -EFAULT;
-
- err = nf_getsockopt(sk, PF_INET, optname, optval, &len);
- if (err >= 0)
- err = put_user(len, optlen);
- return err;
- }
-#endif
- return err;
-}
-EXPORT_SYMBOL(ip_getsockopt);
-
-#ifdef CONFIG_COMPAT
-int compat_ip_getsockopt(struct sock *sk, int level, int optname,
- char __user *optval, int __user *optlen)
-{
- int err;
-
- if (optname == MCAST_MSFILTER) {
- if (level != SOL_IP)
- return -EOPNOTSUPP;
- return compat_ip_get_mcast_msfilter(sk, optval, optlen);
- }
-
- err = do_ip_getsockopt(sk, level, optname, optval, optlen,
- MSG_CMSG_COMPAT);
+ err = do_ip_getsockopt(sk, level, optname, optval, optlen);
#if IS_ENABLED(CONFIG_BPFILTER_UMH)
if (optname >= BPFILTER_IPT_SO_GET_INFO &&
@@ -1850,5 +1759,4 @@ int compat_ip_getsockopt(struct sock *sk, int level, int optname,
#endif
return err;
}
-EXPORT_SYMBOL(compat_ip_getsockopt);
-#endif
+EXPORT_SYMBOL(ip_getsockopt);
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index 47665919048f9d..2a57d633b31e00 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -857,16 +857,6 @@ static int raw_setsockopt(struct sock *sk, int level, int optname,
return do_raw_setsockopt(sk, level, optname, optval, optlen);
}
-#ifdef CONFIG_COMPAT
-static int compat_raw_setsockopt(struct sock *sk, int level, int optname,
- char __user *optval, unsigned int optlen)
-{
- if (level != SOL_RAW)
- return compat_ip_setsockopt(sk, level, optname, optval, optlen);
- return do_raw_setsockopt(sk, level, optname, optval, optlen);
-}
-#endif
-
static int do_raw_getsockopt(struct sock *sk, int level, int optname,
char __user *optval, int __user *optlen)
{
@@ -887,16 +877,6 @@ static int raw_getsockopt(struct sock *sk, int level, int optname,
return do_raw_getsockopt(sk, level, optname, optval, optlen);
}
-#ifdef CONFIG_COMPAT
-static int compat_raw_getsockopt(struct sock *sk, int level, int optname,
- char __user *optval, int __user *optlen)
-{
- if (level != SOL_RAW)
- return compat_ip_getsockopt(sk, level, optname, optval, optlen);
- return do_raw_getsockopt(sk, level, optname, optval, optlen);
-}
-#endif
-
static int raw_ioctl(struct sock *sk, int cmd, unsigned long arg)
{
switch (cmd) {
@@ -980,8 +960,6 @@ struct proto raw_prot = {
.usersize = sizeof_field(struct raw_sock, filter),
.h.raw_hash = &raw_v4_hashinfo,
#ifdef CONFIG_COMPAT
- .compat_setsockopt = compat_raw_setsockopt,
- .compat_getsockopt = compat_raw_getsockopt,
.compat_ioctl = compat_raw_ioctl,
#endif
.diag_destroy = raw_abort,
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 116c11a0aaed62..e5b7ef9a288769 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -2134,10 +2134,6 @@ const struct inet_connection_sock_af_ops ipv4_specific = {
.getsockopt = ip_getsockopt,
.addr2sockaddr = inet_csk_addr2sockaddr,
.sockaddr_len = sizeof(struct sockaddr_in),
-#ifdef CONFIG_COMPAT
- .compat_setsockopt = compat_ip_setsockopt,
- .compat_getsockopt = compat_ip_getsockopt,
-#endif
.mtu_reduced = tcp_v4_mtu_reduced,
};
EXPORT_SYMBOL(ipv4_specific);
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 073d346f515c44..d4be4471c424e3 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -2656,17 +2656,6 @@ int udp_setsockopt(struct sock *sk, int level, int optname,
return ip_setsockopt(sk, level, optname, optval, optlen);
}
-#ifdef CONFIG_COMPAT
-int compat_udp_setsockopt(struct sock *sk, int level, int optname,
- char __user *optval, unsigned int optlen)
-{
- if (level == SOL_UDP || level == SOL_UDPLITE)
- return udp_lib_setsockopt(sk, level, optname, optval, optlen,
- udp_push_pending_frames);
- return compat_ip_setsockopt(sk, level, optname, optval, optlen);
-}
-#endif
-
int udp_lib_getsockopt(struct sock *sk, int level, int optname,
char __user *optval, int __user *optlen)
{
@@ -2732,15 +2721,6 @@ int udp_getsockopt(struct sock *sk, int level, int optname,
return ip_getsockopt(sk, level, optname, optval, optlen);
}
-#ifdef CONFIG_COMPAT
-int compat_udp_getsockopt(struct sock *sk, int level, int optname,
- char __user *optval, int __user *optlen)
-{
- if (level == SOL_UDP || level == SOL_UDPLITE)
- return udp_lib_getsockopt(sk, level, optname, optval, optlen);
- return compat_ip_getsockopt(sk, level, optname, optval, optlen);
-}
-#endif
/**
* udp_poll - wait for a UDP event.
* @file: - file struct
@@ -2812,10 +2792,6 @@ struct proto udp_prot = {
.sysctl_rmem_offset = offsetof(struct net, ipv4.sysctl_udp_rmem_min),
.obj_size = sizeof(struct udp_sock),
.h.udp_table = &udp_table,
-#ifdef CONFIG_COMPAT
- .compat_setsockopt = compat_udp_setsockopt,
- .compat_getsockopt = compat_udp_getsockopt,
-#endif
.diag_destroy = udp_abort,
};
EXPORT_SYMBOL(udp_prot);
diff --git a/net/ipv4/udp_impl.h b/net/ipv4/udp_impl.h
index 6b2fa77eeb1c3e..ab313702c87f30 100644
--- a/net/ipv4/udp_impl.h
+++ b/net/ipv4/udp_impl.h
@@ -17,12 +17,6 @@ int udp_setsockopt(struct sock *sk, int level, int optname,
int udp_getsockopt(struct sock *sk, int level, int optname,
char __user *optval, int __user *optlen);
-#ifdef CONFIG_COMPAT
-int compat_udp_setsockopt(struct sock *sk, int level, int optname,
- char __user *optval, unsigned int optlen);
-int compat_udp_getsockopt(struct sock *sk, int level, int optname,
- char __user *optval, int __user *optlen);
-#endif
int udp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int noblock,
int flags, int *addr_len);
int udp_sendpage(struct sock *sk, struct page *page, int offset, size_t size,
diff --git a/net/ipv4/udplite.c b/net/ipv4/udplite.c
index 5936d66d1ce2f2..bd8773b49e72ed 100644
--- a/net/ipv4/udplite.c
+++ b/net/ipv4/udplite.c
@@ -56,10 +56,6 @@ struct proto udplite_prot = {
.sysctl_mem = sysctl_udp_mem,
.obj_size = sizeof(struct udp_sock),
.h.udp_table = &udplite_table,
-#ifdef CONFIG_COMPAT
- .compat_setsockopt = compat_udp_setsockopt,
- .compat_getsockopt = compat_udp_getsockopt,
-#endif
};
EXPORT_SYMBOL(udplite_prot);
diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c
index f8d7412cfb3d37..2a3fd31fb589dc 100644
--- a/net/l2tp/l2tp_ip.c
+++ b/net/l2tp/l2tp_ip.c
@@ -612,10 +612,6 @@ static struct proto l2tp_ip_prot = {
.hash = l2tp_ip_hash,
.unhash = l2tp_ip_unhash,
.obj_size = sizeof(struct l2tp_ip_sock),
-#ifdef CONFIG_COMPAT
- .compat_setsockopt = compat_ip_setsockopt,
- .compat_getsockopt = compat_ip_getsockopt,
-#endif
};
static const struct proto_ops l2tp_ip_ops = {
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index 8d25cc464efdf3..7ecaf7d575c097 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -1089,10 +1089,6 @@ static struct sctp_af sctp_af_inet = {
.net_header_len = sizeof(struct iphdr),
.sockaddr_len = sizeof(struct sockaddr_in),
.ip_options_len = sctp_v4_ip_options_len,
-#ifdef CONFIG_COMPAT
- .compat_setsockopt = compat_ip_setsockopt,
- .compat_getsockopt = compat_ip_getsockopt,
-#endif
};
struct sctp_pf *sctp_get_pf_specific(sa_family_t family)
--
2.27.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 18/22] net/ipv6: factor out MCAST_MSFILTER getsockopt helpers
2020-07-17 6:23 sockopt cleanups Christoph Hellwig
` (16 preceding siblings ...)
2020-07-17 6:23 ` [PATCH 17/22] net/ipv4: remove compat_ip_{get,set}sockopt Christoph Hellwig
@ 2020-07-17 6:23 ` Christoph Hellwig
2020-07-17 6:23 ` [PATCH 19/22] net/ipv6: factor out MCAST_MSFILTER setsockopt helpers Christoph Hellwig
` (4 subsequent siblings)
22 siblings, 0 replies; 27+ messages in thread
From: Christoph Hellwig @ 2020-07-17 6:23 UTC (permalink / raw)
To: David S. Miller
Cc: Alexei Starovoitov, Daniel Borkmann, Chas Williams,
Pablo Neira Ayuso, Jozsef Kadlecsik, Florian Westphal,
Alexey Kuznetsov, Hideaki YOSHIFUJI, linux-kernel, netdev, bpf,
netfilter-devel, linux-sctp, linux-arch, linux-bluetooth, bridge,
linux-can, dccp, linux-wpan, mptcp
Factor out one helper each for getting the native and compat
version of the MCAST_MSFILTER option.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
net/ipv6/ipv6_sockglue.c | 139 +++++++++++++++++++++------------------
1 file changed, 74 insertions(+), 65 deletions(-)
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index 6adfbdcb7979bd..ef5656f876ac05 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -1071,6 +1071,77 @@ static int ipv6_getsockopt_sticky(struct sock *sk, struct ipv6_txoptions *opt,
return len;
}
+static int ipv6_get_msfilter(struct sock *sk, void __user *optval,
+ int __user *optlen, int len)
+{
+ const int size0 = offsetof(struct group_filter, gf_slist);
+ struct group_filter __user *p = optval;
+ struct group_filter gsf;
+ int num;
+ int err;
+
+ if (len < size0)
+ return -EINVAL;
+ if (copy_from_user(&gsf, p, size0))
+ return -EFAULT;
+ if (gsf.gf_group.ss_family != AF_INET6)
+ return -EADDRNOTAVAIL;
+ num = gsf.gf_numsrc;
+ lock_sock(sk);
+ err = ip6_mc_msfget(sk, &gsf, p->gf_slist);
+ if (!err) {
+ if (num > gsf.gf_numsrc)
+ num = gsf.gf_numsrc;
+ if (put_user(GROUP_FILTER_SIZE(num), optlen) ||
+ copy_to_user(p, &gsf, size0))
+ err = -EFAULT;
+ }
+ release_sock(sk);
+ return err;
+}
+
+#ifdef CONFIG_COMPAT
+static int compat_ipv6_get_msfilter(struct sock *sk, void __user *optval,
+ int __user *optlen)
+{
+ const int size0 = offsetof(struct compat_group_filter, gf_slist);
+ struct compat_group_filter __user *p = optval;
+ struct compat_group_filter gf32;
+ struct group_filter gf;
+ int len, err;
+ int num;
+
+ if (get_user(len, optlen))
+ return -EFAULT;
+ if (len < size0)
+ return -EINVAL;
+
+ if (copy_from_user(&gf32, p, size0))
+ return -EFAULT;
+ gf.gf_interface = gf32.gf_interface;
+ gf.gf_fmode = gf32.gf_fmode;
+ num = gf.gf_numsrc = gf32.gf_numsrc;
+ gf.gf_group = gf32.gf_group;
+
+ if (gf.gf_group.ss_family != AF_INET6)
+ return -EADDRNOTAVAIL;
+
+ lock_sock(sk);
+ err = ip6_mc_msfget(sk, &gf, p->gf_slist);
+ release_sock(sk);
+ if (err)
+ return err;
+ if (num > gf.gf_numsrc)
+ num = gf.gf_numsrc;
+ len = GROUP_FILTER_SIZE(num) - (sizeof(gf)-sizeof(gf32));
+ if (put_user(len, optlen) ||
+ put_user(gf.gf_fmode, &p->gf_fmode) ||
+ put_user(gf.gf_numsrc, &p->gf_numsrc))
+ return -EFAULT;
+ return 0;
+}
+#endif
+
static int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
char __user *optval, int __user *optlen, unsigned int flags)
{
@@ -1094,33 +1165,7 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
val = sk->sk_family;
break;
case MCAST_MSFILTER:
- {
- struct group_filter __user *p = (void __user *)optval;
- struct group_filter gsf;
- const int size0 = offsetof(struct group_filter, gf_slist);
- int num;
- int err;
-
- if (len < size0)
- return -EINVAL;
- if (copy_from_user(&gsf, p, size0))
- return -EFAULT;
- if (gsf.gf_group.ss_family != AF_INET6)
- return -EADDRNOTAVAIL;
- num = gsf.gf_numsrc;
- lock_sock(sk);
- err = ip6_mc_msfget(sk, &gsf, p->gf_slist);
- if (!err) {
- if (num > gsf.gf_numsrc)
- num = gsf.gf_numsrc;
- if (put_user(GROUP_FILTER_SIZE(num), optlen) ||
- copy_to_user(p, &gsf, size0))
- err = -EFAULT;
- }
- release_sock(sk);
- return err;
- }
-
+ return ipv6_get_msfilter(sk, optval, optlen, len);
case IPV6_2292PKTOPTIONS:
{
struct msghdr msg;
@@ -1481,44 +1526,8 @@ int compat_ipv6_getsockopt(struct sock *sk, int level, int optname,
if (level != SOL_IPV6)
return -ENOPROTOOPT;
- if (optname == MCAST_MSFILTER) {
- const int size0 = offsetof(struct compat_group_filter, gf_slist);
- struct compat_group_filter __user *p = (void __user *)optval;
- struct compat_group_filter gf32;
- struct group_filter gf;
- int ulen, err;
- int num;
-
- if (get_user(ulen, optlen))
- return -EFAULT;
-
- if (ulen < size0)
- return -EINVAL;
-
- if (copy_from_user(&gf32, p, size0))
- return -EFAULT;
-
- gf.gf_interface = gf32.gf_interface;
- gf.gf_fmode = gf32.gf_fmode;
- num = gf.gf_numsrc = gf32.gf_numsrc;
- gf.gf_group = gf32.gf_group;
-
- if (gf.gf_group.ss_family != AF_INET6)
- return -EADDRNOTAVAIL;
- lock_sock(sk);
- err = ip6_mc_msfget(sk, &gf, p->gf_slist);
- release_sock(sk);
- if (err)
- return err;
- if (num > gf.gf_numsrc)
- num = gf.gf_numsrc;
- ulen = GROUP_FILTER_SIZE(num) - (sizeof(gf)-sizeof(gf32));
- if (put_user(ulen, optlen) ||
- put_user(gf.gf_fmode, &p->gf_fmode) ||
- put_user(gf.gf_numsrc, &p->gf_numsrc))
- return -EFAULT;
- return 0;
- }
+ if (optname == MCAST_MSFILTER)
+ return compat_ipv6_get_msfilter(sk, optval, optlen);
err = do_ipv6_getsockopt(sk, level, optname, optval, optlen,
MSG_CMSG_COMPAT);
--
2.27.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 19/22] net/ipv6: factor out MCAST_MSFILTER setsockopt helpers
2020-07-17 6:23 sockopt cleanups Christoph Hellwig
` (17 preceding siblings ...)
2020-07-17 6:23 ` [PATCH 18/22] net/ipv6: factor out MCAST_MSFILTER getsockopt helpers Christoph Hellwig
@ 2020-07-17 6:23 ` Christoph Hellwig
2020-07-17 6:23 ` [PATCH 20/22] net/ipv6: factor out mcast join/leave " Christoph Hellwig
` (3 subsequent siblings)
22 siblings, 0 replies; 27+ messages in thread
From: Christoph Hellwig @ 2020-07-17 6:23 UTC (permalink / raw)
To: David S. Miller
Cc: Alexei Starovoitov, Daniel Borkmann, Chas Williams,
Pablo Neira Ayuso, Jozsef Kadlecsik, Florian Westphal,
Alexey Kuznetsov, Hideaki YOSHIFUJI, linux-kernel, netdev, bpf,
netfilter-devel, linux-sctp, linux-arch, linux-bluetooth, bridge,
linux-can, dccp, linux-wpan, mptcp
Factor out one helper each for setting the native and compat
version of the MCAST_MSFILTER option.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
net/ipv6/ipv6_sockglue.c | 159 ++++++++++++++++++++-------------------
1 file changed, 83 insertions(+), 76 deletions(-)
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index ef5656f876ac05..6aa49495d7bc0b 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -171,6 +171,87 @@ static int do_ipv6_mcast_group_source(struct sock *sk, int optname,
return ip6_mc_source(add, omode, sk, greqs);
}
+static int ipv6_set_mcast_msfilter(struct sock *sk, void __user *optval,
+ int optlen)
+{
+ struct group_filter *gsf;
+ int ret;
+
+ if (optlen < GROUP_FILTER_SIZE(0))
+ return -EINVAL;
+ if (optlen > sysctl_optmem_max)
+ return -ENOBUFS;
+
+ gsf = memdup_user(optval, optlen);
+ if (IS_ERR(gsf))
+ return PTR_ERR(gsf);
+
+ /* numsrc >= (4G-140)/128 overflow in 32 bits */
+ ret = -ENOBUFS;
+ if (gsf->gf_numsrc >= 0x1ffffffU ||
+ gsf->gf_numsrc > sysctl_mld_max_msf)
+ goto out_free_gsf;
+
+ ret = -EINVAL;
+ if (GROUP_FILTER_SIZE(gsf->gf_numsrc) > optlen)
+ goto out_free_gsf;
+
+ ret = ip6_mc_msfilter(sk, gsf, gsf->gf_slist);
+out_free_gsf:
+ kfree(gsf);
+ return ret;
+}
+
+#ifdef CONFIG_COMPAT
+static int compat_ipv6_set_mcast_msfilter(struct sock *sk, void __user *optval,
+ int optlen)
+{
+ const int size0 = offsetof(struct compat_group_filter, gf_slist);
+ struct compat_group_filter *gf32;
+ void *p;
+ int ret;
+ int n;
+
+ if (optlen < size0)
+ return -EINVAL;
+ if (optlen > sysctl_optmem_max - 4)
+ return -ENOBUFS;
+
+ p = kmalloc(optlen + 4, GFP_KERNEL);
+ if (!p)
+ return -ENOMEM;
+
+ gf32 = p + 4; /* we want ->gf_group and ->gf_slist aligned */
+ ret = -EFAULT;
+ if (copy_from_user(gf32, optval, optlen))
+ goto out_free_p;
+
+ /* numsrc >= (4G-140)/128 overflow in 32 bits */
+ ret = -ENOBUFS;
+ n = gf32->gf_numsrc;
+ if (n >= 0x1ffffffU || n > sysctl_mld_max_msf)
+ goto out_free_p;
+
+ ret = -EINVAL;
+ if (offsetof(struct compat_group_filter, gf_slist[n]) > optlen)
+ goto out_free_p;
+
+ rtnl_lock();
+ lock_sock(sk);
+ ret = ip6_mc_msfilter(sk, &(struct group_filter){
+ .gf_interface = gf32->gf_interface,
+ .gf_group = gf32->gf_group,
+ .gf_fmode = gf32->gf_fmode,
+ .gf_numsrc = gf32->gf_numsrc}, gf32->gf_slist);
+ release_sock(sk);
+ rtnl_unlock();
+
+out_free_p:
+ kfree(p);
+ return ret;
+}
+#endif
+
static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
char __user *optval, unsigned int optlen)
{
@@ -762,37 +843,8 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
break;
}
case MCAST_MSFILTER:
- {
- struct group_filter *gsf;
-
- if (optlen < GROUP_FILTER_SIZE(0))
- goto e_inval;
- if (optlen > sysctl_optmem_max) {
- retv = -ENOBUFS;
- break;
- }
- gsf = memdup_user(optval, optlen);
- if (IS_ERR(gsf)) {
- retv = PTR_ERR(gsf);
- break;
- }
- /* numsrc >= (4G-140)/128 overflow in 32 bits */
- if (gsf->gf_numsrc >= 0x1ffffffU ||
- gsf->gf_numsrc > sysctl_mld_max_msf) {
- kfree(gsf);
- retv = -ENOBUFS;
- break;
- }
- if (GROUP_FILTER_SIZE(gsf->gf_numsrc) > optlen) {
- kfree(gsf);
- retv = -EINVAL;
- break;
- }
- retv = ip6_mc_msfilter(sk, gsf, gsf->gf_slist);
- kfree(gsf);
-
+ retv = ipv6_set_mcast_msfilter(sk, optval, optlen);
break;
- }
case IPV6_ROUTER_ALERT:
if (optlen < sizeof(int))
goto e_inval;
@@ -977,52 +1029,7 @@ int compat_ipv6_setsockopt(struct sock *sk, int level, int optname,
return err;
}
case MCAST_MSFILTER:
- {
- const int size0 = offsetof(struct compat_group_filter, gf_slist);
- struct compat_group_filter *gf32;
- void *p;
- int n;
-
- if (optlen < size0)
- return -EINVAL;
- if (optlen > sysctl_optmem_max - 4)
- return -ENOBUFS;
-
- p = kmalloc(optlen + 4, GFP_KERNEL);
- if (!p)
- return -ENOMEM;
-
- gf32 = p + 4; /* we want ->gf_group and ->gf_slist aligned */
- if (copy_from_user(gf32, optval, optlen)) {
- err = -EFAULT;
- goto mc_msf_out;
- }
-
- n = gf32->gf_numsrc;
- /* numsrc >= (4G-140)/128 overflow in 32 bits */
- if (n >= 0x1ffffffU ||
- n > sysctl_mld_max_msf) {
- err = -ENOBUFS;
- goto mc_msf_out;
- }
- if (offsetof(struct compat_group_filter, gf_slist[n]) > optlen) {
- err = -EINVAL;
- goto mc_msf_out;
- }
-
- rtnl_lock();
- lock_sock(sk);
- err = ip6_mc_msfilter(sk, &(struct group_filter){
- .gf_interface = gf32->gf_interface,
- .gf_group = gf32->gf_group,
- .gf_fmode = gf32->gf_fmode,
- .gf_numsrc = gf32->gf_numsrc}, gf32->gf_slist);
- release_sock(sk);
- rtnl_unlock();
-mc_msf_out:
- kfree(p);
- return err;
- }
+ return compat_ipv6_set_mcast_msfilter(sk, optval, optlen);
}
err = do_ipv6_setsockopt(sk, level, optname, optval, optlen);
--
2.27.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 20/22] net/ipv6: factor out mcast join/leave setsockopt helpers
2020-07-17 6:23 sockopt cleanups Christoph Hellwig
` (18 preceding siblings ...)
2020-07-17 6:23 ` [PATCH 19/22] net/ipv6: factor out MCAST_MSFILTER setsockopt helpers Christoph Hellwig
@ 2020-07-17 6:23 ` Christoph Hellwig
2020-07-17 6:23 ` [PATCH 21/22] net/ipv6: remove compat_ipv6_{get,set}sockopt Christoph Hellwig
` (2 subsequent siblings)
22 siblings, 0 replies; 27+ messages in thread
From: Christoph Hellwig @ 2020-07-17 6:23 UTC (permalink / raw)
To: David S. Miller
Cc: Alexei Starovoitov, Daniel Borkmann, Chas Williams,
Pablo Neira Ayuso, Jozsef Kadlecsik, Florian Westphal,
Alexey Kuznetsov, Hideaki YOSHIFUJI, linux-kernel, netdev, bpf,
netfilter-devel, linux-sctp, linux-arch, linux-bluetooth, bridge,
linux-can, dccp, linux-wpan, mptcp
Factor out one helper each for setting the native and compat
version of the MCAST_MSFILTER option.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
net/ipv6/ipv6_sockglue.c | 103 ++++++++++++++++++++-------------------
1 file changed, 53 insertions(+), 50 deletions(-)
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index 6aa49495d7bc0b..1ea0cd12beaee9 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -252,6 +252,56 @@ static int compat_ipv6_set_mcast_msfilter(struct sock *sk, void __user *optval,
}
#endif
+static int ipv6_mcast_join_leave(struct sock *sk, int optname,
+ void __user *optval, int optlen)
+{
+ struct sockaddr_in6 *psin6;
+ struct group_req greq;
+
+ if (optlen < sizeof(greq))
+ return -EINVAL;
+ if (copy_from_user(&greq, optval, sizeof(greq)))
+ return -EFAULT;
+
+ if (greq.gr_group.ss_family != AF_INET6)
+ return -EADDRNOTAVAIL;
+ psin6 = (struct sockaddr_in6 *)&greq.gr_group;
+ if (optname == MCAST_JOIN_GROUP)
+ return ipv6_sock_mc_join(sk, greq.gr_interface,
+ &psin6->sin6_addr);
+ return ipv6_sock_mc_drop(sk, greq.gr_interface, &psin6->sin6_addr);
+}
+
+#ifdef CONFIG_COMPAT
+static int compat_ipv6_mcast_join_leave(struct sock *sk, int optname,
+ void __user *optval, int optlen)
+{
+ struct compat_group_req gr32;
+ struct sockaddr_in6 *psin6;
+ int err;
+
+ if (optlen < sizeof(gr32))
+ return -EINVAL;
+ if (copy_from_user(&gr32, optval, sizeof(gr32)))
+ return -EFAULT;
+
+ if (gr32.gr_group.ss_family != AF_INET6)
+ return -EADDRNOTAVAIL;
+ rtnl_lock();
+ lock_sock(sk);
+ psin6 = (struct sockaddr_in6 *)&gr32.gr_group;
+ if (optname == MCAST_JOIN_GROUP)
+ err = ipv6_sock_mc_join(sk, gr32.gr_interface,
+ &psin6->sin6_addr);
+ else
+ err = ipv6_sock_mc_drop(sk, gr32.gr_interface,
+ &psin6->sin6_addr);
+ release_sock(sk);
+ rtnl_unlock();
+ return err;
+}
+#endif
+
static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
char __user *optval, unsigned int optlen)
{
@@ -803,29 +853,8 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
case MCAST_JOIN_GROUP:
case MCAST_LEAVE_GROUP:
- {
- struct group_req greq;
- struct sockaddr_in6 *psin6;
-
- if (optlen < sizeof(struct group_req))
- goto e_inval;
-
- retv = -EFAULT;
- if (copy_from_user(&greq, optval, sizeof(struct group_req)))
- break;
- if (greq.gr_group.ss_family != AF_INET6) {
- retv = -EADDRNOTAVAIL;
- break;
- }
- psin6 = (struct sockaddr_in6 *)&greq.gr_group;
- if (optname == MCAST_JOIN_GROUP)
- retv = ipv6_sock_mc_join(sk, greq.gr_interface,
- &psin6->sin6_addr);
- else
- retv = ipv6_sock_mc_drop(sk, greq.gr_interface,
- &psin6->sin6_addr);
+ retv = ipv6_mcast_join_leave(sk, optname, optval, optlen);
break;
- }
case MCAST_JOIN_SOURCE_GROUP:
case MCAST_LEAVE_SOURCE_GROUP:
case MCAST_BLOCK_SOURCE:
@@ -975,34 +1004,8 @@ int compat_ipv6_setsockopt(struct sock *sk, int level, int optname,
switch (optname) {
case MCAST_JOIN_GROUP:
case MCAST_LEAVE_GROUP:
- {
- struct compat_group_req __user *gr32 = (void __user *)optval;
- struct group_req greq;
- struct sockaddr_in6 *psin6 = (struct sockaddr_in6 *)&greq.gr_group;
-
- if (optlen < sizeof(struct compat_group_req))
- return -EINVAL;
-
- if (get_user(greq.gr_interface, &gr32->gr_interface) ||
- copy_from_user(&greq.gr_group, &gr32->gr_group,
- sizeof(greq.gr_group)))
- return -EFAULT;
-
- if (greq.gr_group.ss_family != AF_INET6)
- return -EADDRNOTAVAIL;
-
- rtnl_lock();
- lock_sock(sk);
- if (optname == MCAST_JOIN_GROUP)
- err = ipv6_sock_mc_join(sk, greq.gr_interface,
- &psin6->sin6_addr);
- else
- err = ipv6_sock_mc_drop(sk, greq.gr_interface,
- &psin6->sin6_addr);
- release_sock(sk);
- rtnl_unlock();
- return err;
- }
+ return compat_ipv6_mcast_join_leave(sk, optname, optval,
+ optlen);
case MCAST_JOIN_SOURCE_GROUP:
case MCAST_LEAVE_SOURCE_GROUP:
case MCAST_BLOCK_SOURCE:
--
2.27.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 21/22] net/ipv6: remove compat_ipv6_{get,set}sockopt
2020-07-17 6:23 sockopt cleanups Christoph Hellwig
` (19 preceding siblings ...)
2020-07-17 6:23 ` [PATCH 20/22] net/ipv6: factor out mcast join/leave " Christoph Hellwig
@ 2020-07-17 6:23 ` Christoph Hellwig
2020-07-17 6:23 ` [PATCH 22/22] net: make ->{get,set}sockopt in proto_ops optional Christoph Hellwig
2020-07-20 1:16 ` sockopt cleanups David Miller
22 siblings, 0 replies; 27+ messages in thread
From: Christoph Hellwig @ 2020-07-17 6:23 UTC (permalink / raw)
To: David S. Miller
Cc: Alexei Starovoitov, Daniel Borkmann, Chas Williams,
Pablo Neira Ayuso, Jozsef Kadlecsik, Florian Westphal,
Alexey Kuznetsov, Hideaki YOSHIFUJI, linux-kernel, netdev, bpf,
netfilter-devel, linux-sctp, linux-arch, linux-bluetooth, bridge,
linux-can, dccp, linux-wpan, mptcp
Handle the few cases that need special treatment in-line using
in_compat_syscall(). This also removes all the now unused
compat_{get,set}sockopt methods.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
include/net/inet_connection_sock.h | 13 --
include/net/ipv6.h | 4 -
include/net/sctp/structs.h | 10 --
include/net/sock.h | 8 --
include/net/tcp.h | 4 -
net/core/sock.c | 10 --
net/dccp/dccp.h | 6 -
net/dccp/ipv4.c | 4 -
net/dccp/ipv6.c | 12 --
net/dccp/proto.c | 26 ----
net/ipv4/inet_connection_sock.c | 28 -----
net/ipv4/tcp.c | 24 ----
net/ipv4/tcp_ipv4.c | 4 -
net/ipv6/ipv6_sockglue.c | 183 ++++++++---------------------
net/ipv6/raw.c | 50 --------
net/ipv6/tcp_ipv6.c | 12 --
net/ipv6/udp.c | 25 ----
net/ipv6/udp_impl.h | 6 -
net/ipv6/udplite.c | 4 -
net/l2tp/l2tp_ip6.c | 4 -
net/sctp/ipv6.c | 4 -
21 files changed, 51 insertions(+), 390 deletions(-)
diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h
index e5b388f5fa2099..157c60cca0ca60 100644
--- a/include/net/inet_connection_sock.h
+++ b/include/net/inet_connection_sock.h
@@ -48,14 +48,6 @@ struct inet_connection_sock_af_ops {
char __user *optval, unsigned int optlen);
int (*getsockopt)(struct sock *sk, int level, int optname,
char __user *optval, int __user *optlen);
-#ifdef CONFIG_COMPAT
- int (*compat_setsockopt)(struct sock *sk,
- int level, int optname,
- char __user *optval, unsigned int optlen);
- int (*compat_getsockopt)(struct sock *sk,
- int level, int optname,
- char __user *optval, int __user *optlen);
-#endif
void (*addr2sockaddr)(struct sock *sk, struct sockaddr *);
void (*mtu_reduced)(struct sock *sk);
};
@@ -311,11 +303,6 @@ void inet_csk_listen_stop(struct sock *sk);
void inet_csk_addr2sockaddr(struct sock *sk, struct sockaddr *uaddr);
-int inet_csk_compat_getsockopt(struct sock *sk, int level, int optname,
- char __user *optval, int __user *optlen);
-int inet_csk_compat_setsockopt(struct sock *sk, int level, int optname,
- char __user *optval, unsigned int optlen);
-
struct dst_entry *inet_csk_update_pmtu(struct sock *sk, u32 mtu);
#define TCP_PINGPONG_THRESH 3
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index 5e65bf2fd32d09..262fc88dbd7e2f 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -1088,10 +1088,6 @@ int ipv6_setsockopt(struct sock *sk, int level, int optname,
char __user *optval, unsigned int optlen);
int ipv6_getsockopt(struct sock *sk, int level, int optname,
char __user *optval, int __user *optlen);
-int compat_ipv6_setsockopt(struct sock *sk, int level, int optname,
- char __user *optval, unsigned int optlen);
-int compat_ipv6_getsockopt(struct sock *sk, int level, int optname,
- char __user *optval, int __user *optlen);
int __ip6_datagram_connect(struct sock *sk, struct sockaddr *addr,
int addr_len);
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 9bbb2f60db9262..233bbf7df5d66c 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -438,16 +438,6 @@ struct sctp_af {
int optname,
char __user *optval,
int __user *optlen);
- int (*compat_setsockopt) (struct sock *sk,
- int level,
- int optname,
- char __user *optval,
- unsigned int optlen);
- int (*compat_getsockopt) (struct sock *sk,
- int level,
- int optname,
- char __user *optval,
- int __user *optlen);
void (*get_dst) (struct sctp_transport *t,
union sctp_addr *saddr,
struct flowi *fl,
diff --git a/include/net/sock.h b/include/net/sock.h
index 1fd7cf5fc7516c..3bd8bc578bf3e5 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -1147,14 +1147,6 @@ struct proto {
int __user *option);
void (*keepalive)(struct sock *sk, int valbool);
#ifdef CONFIG_COMPAT
- int (*compat_setsockopt)(struct sock *sk,
- int level,
- int optname, char __user *optval,
- unsigned int optlen);
- int (*compat_getsockopt)(struct sock *sk,
- int level,
- int optname, char __user *optval,
- int __user *option);
int (*compat_ioctl)(struct sock *sk,
unsigned int cmd, unsigned long arg);
#endif
diff --git a/include/net/tcp.h b/include/net/tcp.h
index d62e24533518a7..9f7f7c0c110451 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -401,10 +401,6 @@ int tcp_getsockopt(struct sock *sk, int level, int optname,
char __user *optval, int __user *optlen);
int tcp_setsockopt(struct sock *sk, int level, int optname,
char __user *optval, unsigned int optlen);
-int compat_tcp_getsockopt(struct sock *sk, int level, int optname,
- char __user *optval, int __user *optlen);
-int compat_tcp_setsockopt(struct sock *sk, int level, int optname,
- char __user *optval, unsigned int optlen);
void tcp_set_keepalive(struct sock *sk, int val);
void tcp_syn_ack_timeout(const struct request_sock *req);
int tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int nonblock,
diff --git a/net/core/sock.c b/net/core/sock.c
index 018404d1762682..48655d5c4cf37a 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -3199,11 +3199,6 @@ int sock_common_getsockopt(struct socket *sock, int level, int optname,
{
struct sock *sk = sock->sk;
-#ifdef CONFIG_COMPAT
- if (in_compat_syscal() && sk->sk_prot->compat_getsockopt)
- return sk->sk_prot->compat_getsockopt(sk, level, optname,
- optval, optlen);
-#endif
return sk->sk_prot->getsockopt(sk, level, optname, optval, optlen);
}
EXPORT_SYMBOL(sock_common_getsockopt);
@@ -3231,11 +3226,6 @@ int sock_common_setsockopt(struct socket *sock, int level, int optname,
{
struct sock *sk = sock->sk;
-#ifdef CONFIG_COMPAT
- if (in_compat_syscall() && sk->sk_prot->compat_setsockopt)
- return sk->sk_prot->compat_setsockopt(sk, level, optname,
- optval, optlen);
-#endif
return sk->sk_prot->setsockopt(sk, level, optname, optval, optlen);
}
EXPORT_SYMBOL(sock_common_setsockopt);
diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h
index 7dce4f6c70252d..434eea91b7679d 100644
--- a/net/dccp/dccp.h
+++ b/net/dccp/dccp.h
@@ -296,12 +296,6 @@ int dccp_getsockopt(struct sock *sk, int level, int optname,
char __user *optval, int __user *optlen);
int dccp_setsockopt(struct sock *sk, int level, int optname,
char __user *optval, unsigned int optlen);
-#ifdef CONFIG_COMPAT
-int compat_dccp_getsockopt(struct sock *sk, int level, int optname,
- char __user *optval, int __user *optlen);
-int compat_dccp_setsockopt(struct sock *sk, int level, int optname,
- char __user *optval, unsigned int optlen);
-#endif
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_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int nonblock,
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index b91373eb1c7974..9c28c825112533 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -959,10 +959,6 @@ static struct proto dccp_v4_prot = {
.rsk_prot = &dccp_request_sock_ops,
.twsk_prot = &dccp_timewait_sock_ops,
.h.hashinfo = &dccp_hashinfo,
-#ifdef CONFIG_COMPAT
- .compat_setsockopt = compat_dccp_setsockopt,
- .compat_getsockopt = compat_dccp_getsockopt,
-#endif
};
static const struct net_protocol dccp_v4_protocol = {
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
index b50f85a72cd5fc..ef4ab28cfde0e3 100644
--- a/net/dccp/ipv6.c
+++ b/net/dccp/ipv6.c
@@ -970,10 +970,6 @@ static const struct inet_connection_sock_af_ops dccp_ipv6_af_ops = {
.getsockopt = ipv6_getsockopt,
.addr2sockaddr = inet6_csk_addr2sockaddr,
.sockaddr_len = sizeof(struct sockaddr_in6),
-#ifdef CONFIG_COMPAT
- .compat_setsockopt = compat_ipv6_setsockopt,
- .compat_getsockopt = compat_ipv6_getsockopt,
-#endif
};
/*
@@ -990,10 +986,6 @@ static const struct inet_connection_sock_af_ops dccp_ipv6_mapped = {
.getsockopt = ipv6_getsockopt,
.addr2sockaddr = inet6_csk_addr2sockaddr,
.sockaddr_len = sizeof(struct sockaddr_in6),
-#ifdef CONFIG_COMPAT
- .compat_setsockopt = compat_ipv6_setsockopt,
- .compat_getsockopt = compat_ipv6_getsockopt,
-#endif
};
/* NOTE: A lot of things set to zero explicitly by call to
@@ -1049,10 +1041,6 @@ static struct proto dccp_v6_prot = {
.rsk_prot = &dccp6_request_sock_ops,
.twsk_prot = &dccp6_timewait_sock_ops,
.h.hashinfo = &dccp_hashinfo,
-#ifdef CONFIG_COMPAT
- .compat_setsockopt = compat_dccp_setsockopt,
- .compat_getsockopt = compat_dccp_getsockopt,
-#endif
};
static const struct inet6_protocol dccp_v6_protocol = {
diff --git a/net/dccp/proto.c b/net/dccp/proto.c
index c13b6609474b65..fd92d3fe321f08 100644
--- a/net/dccp/proto.c
+++ b/net/dccp/proto.c
@@ -575,19 +575,6 @@ int dccp_setsockopt(struct sock *sk, int level, int optname,
EXPORT_SYMBOL_GPL(dccp_setsockopt);
-#ifdef CONFIG_COMPAT
-int compat_dccp_setsockopt(struct sock *sk, int level, int optname,
- char __user *optval, unsigned int optlen)
-{
- if (level != SOL_DCCP)
- return inet_csk_compat_setsockopt(sk, level, optname,
- optval, optlen);
- return do_dccp_setsockopt(sk, level, optname, optval, optlen);
-}
-
-EXPORT_SYMBOL_GPL(compat_dccp_setsockopt);
-#endif
-
static int dccp_getsockopt_service(struct sock *sk, int len,
__be32 __user *optval,
int __user *optlen)
@@ -696,19 +683,6 @@ int dccp_getsockopt(struct sock *sk, int level, int optname,
EXPORT_SYMBOL_GPL(dccp_getsockopt);
-#ifdef CONFIG_COMPAT
-int compat_dccp_getsockopt(struct sock *sk, int level, int optname,
- char __user *optval, int __user *optlen)
-{
- if (level != SOL_DCCP)
- return inet_csk_compat_getsockopt(sk, level, optname,
- optval, optlen);
- return do_dccp_getsockopt(sk, level, optname, optval, optlen);
-}
-
-EXPORT_SYMBOL_GPL(compat_dccp_getsockopt);
-#endif
-
static int dccp_msghdr_parse(struct msghdr *msg, struct sk_buff *skb)
{
struct cmsghdr *cmsg;
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
index 22b0e7336360f3..d1a3913eebe05f 100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -1057,34 +1057,6 @@ void inet_csk_addr2sockaddr(struct sock *sk, struct sockaddr *uaddr)
}
EXPORT_SYMBOL_GPL(inet_csk_addr2sockaddr);
-#ifdef CONFIG_COMPAT
-int inet_csk_compat_getsockopt(struct sock *sk, int level, int optname,
- char __user *optval, int __user *optlen)
-{
- const struct inet_connection_sock *icsk = inet_csk(sk);
-
- if (icsk->icsk_af_ops->compat_getsockopt)
- return icsk->icsk_af_ops->compat_getsockopt(sk, level, optname,
- optval, optlen);
- return icsk->icsk_af_ops->getsockopt(sk, level, optname,
- optval, optlen);
-}
-EXPORT_SYMBOL_GPL(inet_csk_compat_getsockopt);
-
-int inet_csk_compat_setsockopt(struct sock *sk, int level, int optname,
- char __user *optval, unsigned int optlen)
-{
- const struct inet_connection_sock *icsk = inet_csk(sk);
-
- if (icsk->icsk_af_ops->compat_setsockopt)
- return icsk->icsk_af_ops->compat_setsockopt(sk, level, optname,
- optval, optlen);
- return icsk->icsk_af_ops->setsockopt(sk, level, optname,
- optval, optlen);
-}
-EXPORT_SYMBOL_GPL(inet_csk_compat_setsockopt);
-#endif
-
static struct dst_entry *inet_csk_rebuild_route(struct sock *sk, struct flowi *fl)
{
const struct inet_sock *inet = inet_sk(sk);
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 254b6a4cc95bd0..58ede3d62b2e2c 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -3337,18 +3337,6 @@ int tcp_setsockopt(struct sock *sk, int level, int optname, char __user *optval,
}
EXPORT_SYMBOL(tcp_setsockopt);
-#ifdef CONFIG_COMPAT
-int compat_tcp_setsockopt(struct sock *sk, int level, int optname,
- char __user *optval, unsigned int optlen)
-{
- if (level != SOL_TCP)
- return inet_csk_compat_setsockopt(sk, level, optname,
- optval, optlen);
- return do_tcp_setsockopt(sk, level, optname, optval, optlen);
-}
-EXPORT_SYMBOL(compat_tcp_setsockopt);
-#endif
-
static void tcp_get_info_chrono_stats(const struct tcp_sock *tp,
struct tcp_info *info)
{
@@ -3896,18 +3884,6 @@ int tcp_getsockopt(struct sock *sk, int level, int optname, char __user *optval,
}
EXPORT_SYMBOL(tcp_getsockopt);
-#ifdef CONFIG_COMPAT
-int compat_tcp_getsockopt(struct sock *sk, int level, int optname,
- char __user *optval, int __user *optlen)
-{
- if (level != SOL_TCP)
- return inet_csk_compat_getsockopt(sk, level, optname,
- optval, optlen);
- return do_tcp_getsockopt(sk, level, optname, optval, optlen);
-}
-EXPORT_SYMBOL(compat_tcp_getsockopt);
-#endif
-
#ifdef CONFIG_TCP_MD5SIG
static DEFINE_PER_CPU(struct tcp_md5sig_pool, tcp_md5sig_pool);
static DEFINE_MUTEX(tcp_md5sig_mutex);
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index e5b7ef9a288769..cd81b6e04efbfa 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -2769,10 +2769,6 @@ struct proto tcp_prot = {
.rsk_prot = &tcp_request_sock_ops,
.h.hashinfo = &tcp_hashinfo,
.no_autobind = true,
-#ifdef CONFIG_COMPAT
- .compat_setsockopt = compat_tcp_setsockopt,
- .compat_getsockopt = compat_tcp_getsockopt,
-#endif
.diag_destroy = tcp_abort,
};
EXPORT_SYMBOL(tcp_prot);
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index 1ea0cd12beaee9..add8f791229945 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -136,13 +136,42 @@ static bool setsockopt_needs_rtnl(int optname)
return false;
}
+static int copy_group_source_from_user(struct group_source_req *greqs,
+ void __user *optval, int optlen)
+{
+ if (in_compat_syscall()) {
+ struct compat_group_source_req gr32;
+
+ if (optlen < sizeof(gr32))
+ return -EINVAL;
+ if (copy_from_user(&gr32, optval, sizeof(gr32)))
+ return -EFAULT;
+ greqs->gsr_interface = gr32.gsr_interface;
+ greqs->gsr_group = gr32.gsr_group;
+ greqs->gsr_source = gr32.gsr_source;
+ } else {
+ if (optlen < sizeof(*greqs))
+ return -EINVAL;
+ if (copy_from_user(greqs, optval, sizeof(*greqs)))
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
static int do_ipv6_mcast_group_source(struct sock *sk, int optname,
- struct group_source_req *greqs)
+ void __user *optval, int optlen)
{
+ struct group_source_req greqs;
int omode, add;
+ int ret;
+
+ ret = copy_group_source_from_user(&greqs, optval, optlen);
+ if (ret)
+ return ret;
- if (greqs->gsr_group.ss_family != AF_INET6 ||
- greqs->gsr_source.ss_family != AF_INET6)
+ if (greqs.gsr_group.ss_family != AF_INET6 ||
+ greqs.gsr_source.ss_family != AF_INET6)
return -EADDRNOTAVAIL;
if (optname == MCAST_BLOCK_SOURCE) {
@@ -155,8 +184,8 @@ static int do_ipv6_mcast_group_source(struct sock *sk, int optname,
struct sockaddr_in6 *psin6;
int retv;
- psin6 = (struct sockaddr_in6 *)&greqs->gsr_group;
- retv = ipv6_sock_mc_join_ssm(sk, greqs->gsr_interface,
+ psin6 = (struct sockaddr_in6 *)&greqs.gsr_group;
+ retv = ipv6_sock_mc_join_ssm(sk, greqs.gsr_interface,
&psin6->sin6_addr,
MCAST_INCLUDE);
/* prior join w/ different source is ok */
@@ -168,7 +197,7 @@ static int do_ipv6_mcast_group_source(struct sock *sk, int optname,
omode = MCAST_INCLUDE;
add = 0;
}
- return ip6_mc_source(add, omode, sk, greqs);
+ return ip6_mc_source(add, omode, sk, &greqs);
}
static int ipv6_set_mcast_msfilter(struct sock *sk, void __user *optval,
@@ -202,7 +231,6 @@ static int ipv6_set_mcast_msfilter(struct sock *sk, void __user *optval,
return ret;
}
-#ifdef CONFIG_COMPAT
static int compat_ipv6_set_mcast_msfilter(struct sock *sk, void __user *optval,
int optlen)
{
@@ -236,21 +264,16 @@ static int compat_ipv6_set_mcast_msfilter(struct sock *sk, void __user *optval,
if (offsetof(struct compat_group_filter, gf_slist[n]) > optlen)
goto out_free_p;
- rtnl_lock();
- lock_sock(sk);
ret = ip6_mc_msfilter(sk, &(struct group_filter){
.gf_interface = gf32->gf_interface,
.gf_group = gf32->gf_group,
.gf_fmode = gf32->gf_fmode,
.gf_numsrc = gf32->gf_numsrc}, gf32->gf_slist);
- release_sock(sk);
- rtnl_unlock();
out_free_p:
kfree(p);
return ret;
}
-#endif
static int ipv6_mcast_join_leave(struct sock *sk, int optname,
void __user *optval, int optlen)
@@ -272,13 +295,11 @@ static int ipv6_mcast_join_leave(struct sock *sk, int optname,
return ipv6_sock_mc_drop(sk, greq.gr_interface, &psin6->sin6_addr);
}
-#ifdef CONFIG_COMPAT
static int compat_ipv6_mcast_join_leave(struct sock *sk, int optname,
void __user *optval, int optlen)
{
struct compat_group_req gr32;
struct sockaddr_in6 *psin6;
- int err;
if (optlen < sizeof(gr32))
return -EINVAL;
@@ -287,20 +308,12 @@ static int compat_ipv6_mcast_join_leave(struct sock *sk, int optname,
if (gr32.gr_group.ss_family != AF_INET6)
return -EADDRNOTAVAIL;
- rtnl_lock();
- lock_sock(sk);
psin6 = (struct sockaddr_in6 *)&gr32.gr_group;
if (optname == MCAST_JOIN_GROUP)
- err = ipv6_sock_mc_join(sk, gr32.gr_interface,
+ return ipv6_sock_mc_join(sk, gr32.gr_interface,
&psin6->sin6_addr);
- else
- err = ipv6_sock_mc_drop(sk, gr32.gr_interface,
- &psin6->sin6_addr);
- release_sock(sk);
- rtnl_unlock();
- return err;
+ return ipv6_sock_mc_drop(sk, gr32.gr_interface, &psin6->sin6_addr);
}
-#endif
static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
char __user *optval, unsigned int optlen)
@@ -853,26 +866,25 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
case MCAST_JOIN_GROUP:
case MCAST_LEAVE_GROUP:
- retv = ipv6_mcast_join_leave(sk, optname, optval, optlen);
+ if (in_compat_syscall())
+ retv = compat_ipv6_mcast_join_leave(sk, optname, optval,
+ optlen);
+ else
+ retv = ipv6_mcast_join_leave(sk, optname, optval,
+ optlen);
break;
case MCAST_JOIN_SOURCE_GROUP:
case MCAST_LEAVE_SOURCE_GROUP:
case MCAST_BLOCK_SOURCE:
case MCAST_UNBLOCK_SOURCE:
- {
- struct group_source_req greqs;
-
- if (optlen < sizeof(struct group_source_req))
- goto e_inval;
- if (copy_from_user(&greqs, optval, sizeof(greqs))) {
- retv = -EFAULT;
- break;
- }
- retv = do_ipv6_mcast_group_source(sk, optname, &greqs);
+ retv = do_ipv6_mcast_group_source(sk, optname, optval, optlen);
break;
- }
case MCAST_MSFILTER:
- retv = ipv6_set_mcast_msfilter(sk, optval, optlen);
+ if (in_compat_syscall())
+ retv = compat_ipv6_set_mcast_msfilter(sk, optval,
+ optlen);
+ else
+ retv = ipv6_set_mcast_msfilter(sk, optval, optlen);
break;
case IPV6_ROUTER_ALERT:
if (optlen < sizeof(int))
@@ -989,64 +1001,6 @@ int ipv6_setsockopt(struct sock *sk, int level, int optname,
}
EXPORT_SYMBOL(ipv6_setsockopt);
-#ifdef CONFIG_COMPAT
-int compat_ipv6_setsockopt(struct sock *sk, int level, int optname,
- char __user *optval, unsigned int optlen)
-{
- int err;
-
- if (level == SOL_IP && sk->sk_type != SOCK_RAW)
- return udp_prot.setsockopt(sk, level, optname, optval, optlen);
-
- if (level != SOL_IPV6)
- return -ENOPROTOOPT;
-
- switch (optname) {
- case MCAST_JOIN_GROUP:
- case MCAST_LEAVE_GROUP:
- return compat_ipv6_mcast_join_leave(sk, optname, optval,
- optlen);
- case MCAST_JOIN_SOURCE_GROUP:
- case MCAST_LEAVE_SOURCE_GROUP:
- case MCAST_BLOCK_SOURCE:
- case MCAST_UNBLOCK_SOURCE:
- {
- struct compat_group_source_req __user *gsr32 = (void __user *)optval;
- struct group_source_req greqs;
-
- if (optlen < sizeof(struct compat_group_source_req))
- return -EINVAL;
-
- if (get_user(greqs.gsr_interface, &gsr32->gsr_interface) ||
- copy_from_user(&greqs.gsr_group, &gsr32->gsr_group,
- sizeof(greqs.gsr_group)) ||
- copy_from_user(&greqs.gsr_source, &gsr32->gsr_source,
- sizeof(greqs.gsr_source)))
- return -EFAULT;
-
- rtnl_lock();
- lock_sock(sk);
- err = do_ipv6_mcast_group_source(sk, optname, &greqs);
- release_sock(sk);
- rtnl_unlock();
- return err;
- }
- case MCAST_MSFILTER:
- return compat_ipv6_set_mcast_msfilter(sk, optval, optlen);
- }
-
- err = do_ipv6_setsockopt(sk, level, optname, optval, optlen);
-#ifdef CONFIG_NETFILTER
- /* we need to exclude all possible ENOPROTOOPTs except default case */
- if (err == -ENOPROTOOPT && optname != IPV6_IPSEC_POLICY &&
- optname != IPV6_XFRM_POLICY)
- err = nf_setsockopt(sk, PF_INET6, optname, optval, optlen);
-#endif
- return err;
-}
-EXPORT_SYMBOL(compat_ipv6_setsockopt);
-#endif
-
static int ipv6_getsockopt_sticky(struct sock *sk, struct ipv6_txoptions *opt,
int optname, char __user *optval, int len)
{
@@ -1110,7 +1064,6 @@ static int ipv6_get_msfilter(struct sock *sk, void __user *optval,
return err;
}
-#ifdef CONFIG_COMPAT
static int compat_ipv6_get_msfilter(struct sock *sk, void __user *optval,
int __user *optlen)
{
@@ -1150,7 +1103,6 @@ static int compat_ipv6_get_msfilter(struct sock *sk, void __user *optval,
return -EFAULT;
return 0;
}
-#endif
static int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
char __user *optval, int __user *optlen, unsigned int flags)
@@ -1175,6 +1127,8 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
val = sk->sk_family;
break;
case MCAST_MSFILTER:
+ if (in_compat_syscall())
+ return compat_ipv6_get_msfilter(sk, optval, optlen);
return ipv6_get_msfilter(sk, optval, optlen, len);
case IPV6_2292PKTOPTIONS:
{
@@ -1523,38 +1477,3 @@ int ipv6_getsockopt(struct sock *sk, int level, int optname,
return err;
}
EXPORT_SYMBOL(ipv6_getsockopt);
-
-#ifdef CONFIG_COMPAT
-int compat_ipv6_getsockopt(struct sock *sk, int level, int optname,
- char __user *optval, int __user *optlen)
-{
- int err;
-
- if (level == SOL_IP && sk->sk_type != SOCK_RAW)
- return udp_prot.getsockopt(sk, level, optname, optval, optlen);
-
- if (level != SOL_IPV6)
- return -ENOPROTOOPT;
-
- if (optname == MCAST_MSFILTER)
- return compat_ipv6_get_msfilter(sk, optval, optlen);
-
- err = do_ipv6_getsockopt(sk, level, optname, optval, optlen,
- MSG_CMSG_COMPAT);
-#ifdef CONFIG_NETFILTER
- /* we need to exclude all possible ENOPROTOOPTs except default case */
- if (err == -ENOPROTOOPT && optname != IPV6_2292PKTOPTIONS) {
- int len;
-
- if (get_user(len, optlen))
- return -EFAULT;
-
- err = nf_getsockopt(sk, PF_INET6, optname, optval, &len);
- if (err >= 0)
- err = put_user(len, optlen);
- }
-#endif
- return err;
-}
-EXPORT_SYMBOL(compat_ipv6_getsockopt);
-#endif
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index e23c6b46175870..594e01ad670aa6 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -1084,30 +1084,6 @@ static int rawv6_setsockopt(struct sock *sk, int level, int optname,
return do_rawv6_setsockopt(sk, level, optname, optval, optlen);
}
-#ifdef CONFIG_COMPAT
-static int compat_rawv6_setsockopt(struct sock *sk, int level, int optname,
- char __user *optval, unsigned int optlen)
-{
- switch (level) {
- case SOL_RAW:
- break;
- case SOL_ICMPV6:
- if (inet_sk(sk)->inet_num != IPPROTO_ICMPV6)
- return -EOPNOTSUPP;
- return rawv6_seticmpfilter(sk, level, optname, optval, optlen);
- case SOL_IPV6:
- if (optname == IPV6_CHECKSUM ||
- optname == IPV6_HDRINCL)
- break;
- fallthrough;
- default:
- return compat_ipv6_setsockopt(sk, level, optname,
- optval, optlen);
- }
- return do_rawv6_setsockopt(sk, level, optname, optval, optlen);
-}
-#endif
-
static int do_rawv6_getsockopt(struct sock *sk, int level, int optname,
char __user *optval, int __user *optlen)
{
@@ -1169,30 +1145,6 @@ static int rawv6_getsockopt(struct sock *sk, int level, int optname,
return do_rawv6_getsockopt(sk, level, optname, optval, optlen);
}
-#ifdef CONFIG_COMPAT
-static int compat_rawv6_getsockopt(struct sock *sk, int level, int optname,
- char __user *optval, int __user *optlen)
-{
- switch (level) {
- case SOL_RAW:
- break;
- case SOL_ICMPV6:
- if (inet_sk(sk)->inet_num != IPPROTO_ICMPV6)
- return -EOPNOTSUPP;
- return rawv6_geticmpfilter(sk, level, optname, optval, optlen);
- case SOL_IPV6:
- if (optname == IPV6_CHECKSUM ||
- optname == IPV6_HDRINCL)
- break;
- fallthrough;
- default:
- return compat_ipv6_getsockopt(sk, level, optname,
- optval, optlen);
- }
- return do_rawv6_getsockopt(sk, level, optname, optval, optlen);
-}
-#endif
-
static int rawv6_ioctl(struct sock *sk, int cmd, unsigned long arg)
{
switch (cmd) {
@@ -1297,8 +1249,6 @@ struct proto rawv6_prot = {
.usersize = sizeof_field(struct raw6_sock, filter),
.h.raw_hash = &raw_v6_hashinfo,
#ifdef CONFIG_COMPAT
- .compat_setsockopt = compat_rawv6_setsockopt,
- .compat_getsockopt = compat_rawv6_getsockopt,
.compat_ioctl = compat_rawv6_ioctl,
#endif
.diag_destroy = raw_abort,
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 4502db706f7534..c34b7834fd84a8 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -1831,10 +1831,6 @@ const struct inet_connection_sock_af_ops ipv6_specific = {
.getsockopt = ipv6_getsockopt,
.addr2sockaddr = inet6_csk_addr2sockaddr,
.sockaddr_len = sizeof(struct sockaddr_in6),
-#ifdef CONFIG_COMPAT
- .compat_setsockopt = compat_ipv6_setsockopt,
- .compat_getsockopt = compat_ipv6_getsockopt,
-#endif
.mtu_reduced = tcp_v6_mtu_reduced,
};
@@ -1861,10 +1857,6 @@ static const struct inet_connection_sock_af_ops ipv6_mapped = {
.getsockopt = ipv6_getsockopt,
.addr2sockaddr = inet6_csk_addr2sockaddr,
.sockaddr_len = sizeof(struct sockaddr_in6),
-#ifdef CONFIG_COMPAT
- .compat_setsockopt = compat_ipv6_setsockopt,
- .compat_getsockopt = compat_ipv6_getsockopt,
-#endif
.mtu_reduced = tcp_v4_mtu_reduced,
};
@@ -2122,10 +2114,6 @@ struct proto tcpv6_prot = {
.rsk_prot = &tcp6_request_sock_ops,
.h.hashinfo = &tcp_hashinfo,
.no_autobind = true,
-#ifdef CONFIG_COMPAT
- .compat_setsockopt = compat_tcp_setsockopt,
- .compat_getsockopt = compat_tcp_getsockopt,
-#endif
.diag_destroy = tcp_abort,
};
EXPORT_SYMBOL_GPL(tcpv6_prot);
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 38c0d9350c6b8f..5aff0856a05b44 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -1570,17 +1570,6 @@ int udpv6_setsockopt(struct sock *sk, int level, int optname,
return ipv6_setsockopt(sk, level, optname, optval, optlen);
}
-#ifdef CONFIG_COMPAT
-int compat_udpv6_setsockopt(struct sock *sk, int level, int optname,
- char __user *optval, unsigned int optlen)
-{
- if (level == SOL_UDP || level == SOL_UDPLITE)
- return udp_lib_setsockopt(sk, level, optname, optval, optlen,
- udp_v6_push_pending_frames);
- return compat_ipv6_setsockopt(sk, level, optname, optval, optlen);
-}
-#endif
-
int udpv6_getsockopt(struct sock *sk, int level, int optname,
char __user *optval, int __user *optlen)
{
@@ -1589,16 +1578,6 @@ int udpv6_getsockopt(struct sock *sk, int level, int optname,
return ipv6_getsockopt(sk, level, optname, optval, optlen);
}
-#ifdef CONFIG_COMPAT
-int compat_udpv6_getsockopt(struct sock *sk, int level, int optname,
- char __user *optval, int __user *optlen)
-{
- if (level == SOL_UDP || level == SOL_UDPLITE)
- return udp_lib_getsockopt(sk, level, optname, optval, optlen);
- return compat_ipv6_getsockopt(sk, level, optname, optval, optlen);
-}
-#endif
-
/* thinking of making this const? Don't.
* early_demux can change based on sysctl.
*/
@@ -1681,10 +1660,6 @@ struct proto udpv6_prot = {
.sysctl_rmem_offset = offsetof(struct net, ipv4.sysctl_udp_rmem_min),
.obj_size = sizeof(struct udp6_sock),
.h.udp_table = &udp_table,
-#ifdef CONFIG_COMPAT
- .compat_setsockopt = compat_udpv6_setsockopt,
- .compat_getsockopt = compat_udpv6_getsockopt,
-#endif
.diag_destroy = udp_abort,
};
diff --git a/net/ipv6/udp_impl.h b/net/ipv6/udp_impl.h
index 20e324b6f3584e..30dfb6f1b7622a 100644
--- a/net/ipv6/udp_impl.h
+++ b/net/ipv6/udp_impl.h
@@ -19,12 +19,6 @@ int udpv6_getsockopt(struct sock *sk, int level, int optname,
char __user *optval, int __user *optlen);
int udpv6_setsockopt(struct sock *sk, int level, int optname,
char __user *optval, unsigned int optlen);
-#ifdef CONFIG_COMPAT
-int compat_udpv6_setsockopt(struct sock *sk, int level, int optname,
- char __user *optval, unsigned int optlen);
-int compat_udpv6_getsockopt(struct sock *sk, int level, int optname,
- char __user *optval, int __user *optlen);
-#endif
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 flags, int *addr_len);
diff --git a/net/ipv6/udplite.c b/net/ipv6/udplite.c
index bf7a7acd39b1d5..fbb700d3f437ee 100644
--- a/net/ipv6/udplite.c
+++ b/net/ipv6/udplite.c
@@ -52,10 +52,6 @@ struct proto udplitev6_prot = {
.sysctl_mem = sysctl_udp_mem,
.obj_size = sizeof(struct udp6_sock),
.h.udp_table = &udplite_table,
-#ifdef CONFIG_COMPAT
- .compat_setsockopt = compat_udpv6_setsockopt,
- .compat_getsockopt = compat_udpv6_getsockopt,
-#endif
};
static struct inet_protosw udplite6_protosw = {
diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c
index 2cdc0b7a7a43c3..4799bec87b332f 100644
--- a/net/l2tp/l2tp_ip6.c
+++ b/net/l2tp/l2tp_ip6.c
@@ -745,10 +745,6 @@ static struct proto l2tp_ip6_prot = {
.hash = l2tp_ip6_hash,
.unhash = l2tp_ip6_unhash,
.obj_size = sizeof(struct l2tp_ip6_sock),
-#ifdef CONFIG_COMPAT
- .compat_setsockopt = compat_ipv6_setsockopt,
- .compat_getsockopt = compat_ipv6_getsockopt,
-#endif
};
static const struct proto_ops l2tp_ip6_ops = {
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index ebda31b7747d08..aea2a982984d02 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -1087,10 +1087,6 @@ static struct sctp_af sctp_af_inet6 = {
.net_header_len = sizeof(struct ipv6hdr),
.sockaddr_len = sizeof(struct sockaddr_in6),
.ip_options_len = sctp_v6_ip_options_len,
-#ifdef CONFIG_COMPAT
- .compat_setsockopt = compat_ipv6_setsockopt,
- .compat_getsockopt = compat_ipv6_getsockopt,
-#endif
};
static struct sctp_pf sctp_pf_inet6 = {
--
2.27.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 22/22] net: make ->{get,set}sockopt in proto_ops optional
2020-07-17 6:23 sockopt cleanups Christoph Hellwig
` (20 preceding siblings ...)
2020-07-17 6:23 ` [PATCH 21/22] net/ipv6: remove compat_ipv6_{get,set}sockopt Christoph Hellwig
@ 2020-07-17 6:23 ` Christoph Hellwig
2020-07-17 8:01 ` Marc Kleine-Budde
2020-07-20 1:16 ` sockopt cleanups David Miller
22 siblings, 1 reply; 27+ messages in thread
From: Christoph Hellwig @ 2020-07-17 6:23 UTC (permalink / raw)
To: David S. Miller
Cc: Alexei Starovoitov, Daniel Borkmann, Chas Williams,
Pablo Neira Ayuso, Jozsef Kadlecsik, Florian Westphal,
Alexey Kuznetsov, Hideaki YOSHIFUJI, linux-kernel, netdev, bpf,
netfilter-devel, linux-sctp, linux-arch, linux-bluetooth, bridge,
linux-can, dccp, linux-wpan, mptcp
Just check for a NULL method instead of wiring up
sock_no_{get,set}sockopt.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
crypto/af_alg.c | 1 -
crypto/algif_aead.c | 4 ----
crypto/algif_hash.c | 4 ----
crypto/algif_rng.c | 2 --
crypto/algif_skcipher.c | 4 ----
drivers/isdn/mISDN/socket.c | 2 --
drivers/net/ppp/pppoe.c | 2 --
drivers/net/ppp/pptp.c | 2 --
include/net/sock.h | 2 --
net/appletalk/ddp.c | 2 --
net/bluetooth/bnep/sock.c | 2 --
net/bluetooth/cmtp/sock.c | 2 --
net/bluetooth/hidp/sock.c | 2 --
net/caif/caif_socket.c | 2 --
net/can/bcm.c | 2 --
net/core/sock.c | 14 --------------
net/key/af_key.c | 2 --
net/nfc/llcp_sock.c | 2 --
net/nfc/rawsock.c | 4 ----
net/packet/af_packet.c | 2 --
net/phonet/socket.c | 2 --
net/qrtr/qrtr.c | 2 --
net/smc/af_smc.c | 9 +++++++--
net/socket.c | 4 ++++
net/unix/af_unix.c | 6 ------
net/vmw_vsock/af_vsock.c | 2 --
26 files changed, 11 insertions(+), 73 deletions(-)
diff --git a/crypto/af_alg.c b/crypto/af_alg.c
index 28fc323e3fe304..29f71428520b4b 100644
--- a/crypto/af_alg.c
+++ b/crypto/af_alg.c
@@ -335,7 +335,6 @@ static const struct proto_ops alg_proto_ops = {
.ioctl = sock_no_ioctl,
.listen = sock_no_listen,
.shutdown = sock_no_shutdown,
- .getsockopt = sock_no_getsockopt,
.mmap = sock_no_mmap,
.sendpage = sock_no_sendpage,
.sendmsg = sock_no_sendmsg,
diff --git a/crypto/algif_aead.c b/crypto/algif_aead.c
index 0ae000a61c7f5b..527d09a694627b 100644
--- a/crypto/algif_aead.c
+++ b/crypto/algif_aead.c
@@ -361,11 +361,9 @@ static struct proto_ops algif_aead_ops = {
.ioctl = sock_no_ioctl,
.listen = sock_no_listen,
.shutdown = sock_no_shutdown,
- .getsockopt = sock_no_getsockopt,
.mmap = sock_no_mmap,
.bind = sock_no_bind,
.accept = sock_no_accept,
- .setsockopt = sock_no_setsockopt,
.release = af_alg_release,
.sendmsg = aead_sendmsg,
@@ -454,11 +452,9 @@ static struct proto_ops algif_aead_ops_nokey = {
.ioctl = sock_no_ioctl,
.listen = sock_no_listen,
.shutdown = sock_no_shutdown,
- .getsockopt = sock_no_getsockopt,
.mmap = sock_no_mmap,
.bind = sock_no_bind,
.accept = sock_no_accept,
- .setsockopt = sock_no_setsockopt,
.release = af_alg_release,
.sendmsg = aead_sendmsg_nokey,
diff --git a/crypto/algif_hash.c b/crypto/algif_hash.c
index e71727c25a7db7..50f7b22f1b4825 100644
--- a/crypto/algif_hash.c
+++ b/crypto/algif_hash.c
@@ -279,10 +279,8 @@ static struct proto_ops algif_hash_ops = {
.ioctl = sock_no_ioctl,
.listen = sock_no_listen,
.shutdown = sock_no_shutdown,
- .getsockopt = sock_no_getsockopt,
.mmap = sock_no_mmap,
.bind = sock_no_bind,
- .setsockopt = sock_no_setsockopt,
.release = af_alg_release,
.sendmsg = hash_sendmsg,
@@ -383,10 +381,8 @@ static struct proto_ops algif_hash_ops_nokey = {
.ioctl = sock_no_ioctl,
.listen = sock_no_listen,
.shutdown = sock_no_shutdown,
- .getsockopt = sock_no_getsockopt,
.mmap = sock_no_mmap,
.bind = sock_no_bind,
- .setsockopt = sock_no_setsockopt,
.release = af_alg_release,
.sendmsg = hash_sendmsg_nokey,
diff --git a/crypto/algif_rng.c b/crypto/algif_rng.c
index 087c0ad09d382b..6300e0566dc560 100644
--- a/crypto/algif_rng.c
+++ b/crypto/algif_rng.c
@@ -101,11 +101,9 @@ static struct proto_ops algif_rng_ops = {
.ioctl = sock_no_ioctl,
.listen = sock_no_listen,
.shutdown = sock_no_shutdown,
- .getsockopt = sock_no_getsockopt,
.mmap = sock_no_mmap,
.bind = sock_no_bind,
.accept = sock_no_accept,
- .setsockopt = sock_no_setsockopt,
.sendmsg = sock_no_sendmsg,
.sendpage = sock_no_sendpage,
diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c
index ec5567c87a6df4..c487887f46711e 100644
--- a/crypto/algif_skcipher.c
+++ b/crypto/algif_skcipher.c
@@ -188,11 +188,9 @@ static struct proto_ops algif_skcipher_ops = {
.ioctl = sock_no_ioctl,
.listen = sock_no_listen,
.shutdown = sock_no_shutdown,
- .getsockopt = sock_no_getsockopt,
.mmap = sock_no_mmap,
.bind = sock_no_bind,
.accept = sock_no_accept,
- .setsockopt = sock_no_setsockopt,
.release = af_alg_release,
.sendmsg = skcipher_sendmsg,
@@ -281,11 +279,9 @@ static struct proto_ops algif_skcipher_ops_nokey = {
.ioctl = sock_no_ioctl,
.listen = sock_no_listen,
.shutdown = sock_no_shutdown,
- .getsockopt = sock_no_getsockopt,
.mmap = sock_no_mmap,
.bind = sock_no_bind,
.accept = sock_no_accept,
- .setsockopt = sock_no_setsockopt,
.release = af_alg_release,
.sendmsg = skcipher_sendmsg_nokey,
diff --git a/drivers/isdn/mISDN/socket.c b/drivers/isdn/mISDN/socket.c
index dff4132b3702c6..1b2b91479107bc 100644
--- a/drivers/isdn/mISDN/socket.c
+++ b/drivers/isdn/mISDN/socket.c
@@ -738,8 +738,6 @@ static const struct proto_ops base_sock_ops = {
.recvmsg = sock_no_recvmsg,
.listen = sock_no_listen,
.shutdown = sock_no_shutdown,
- .setsockopt = sock_no_setsockopt,
- .getsockopt = sock_no_getsockopt,
.connect = sock_no_connect,
.socketpair = sock_no_socketpair,
.accept = sock_no_accept,
diff --git a/drivers/net/ppp/pppoe.c b/drivers/net/ppp/pppoe.c
index beedaad082551b..d7f50b835050d1 100644
--- a/drivers/net/ppp/pppoe.c
+++ b/drivers/net/ppp/pppoe.c
@@ -1110,8 +1110,6 @@ static const struct proto_ops pppoe_ops = {
.poll = datagram_poll,
.listen = sock_no_listen,
.shutdown = sock_no_shutdown,
- .setsockopt = sock_no_setsockopt,
- .getsockopt = sock_no_getsockopt,
.sendmsg = pppoe_sendmsg,
.recvmsg = pppoe_recvmsg,
.mmap = sock_no_mmap,
diff --git a/drivers/net/ppp/pptp.c b/drivers/net/ppp/pptp.c
index acccb747aedad6..ee5058445d06e2 100644
--- a/drivers/net/ppp/pptp.c
+++ b/drivers/net/ppp/pptp.c
@@ -618,8 +618,6 @@ static const struct proto_ops pptp_ops = {
.getname = pptp_getname,
.listen = sock_no_listen,
.shutdown = sock_no_shutdown,
- .setsockopt = sock_no_setsockopt,
- .getsockopt = sock_no_getsockopt,
.sendmsg = sock_no_sendmsg,
.recvmsg = sock_no_recvmsg,
.mmap = sock_no_mmap,
diff --git a/include/net/sock.h b/include/net/sock.h
index 3bd8bc578bf3e5..62e18fc8ac9f96 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -1714,8 +1714,6 @@ int sock_no_getname(struct socket *, struct sockaddr *, int);
int sock_no_ioctl(struct socket *, unsigned int, unsigned long);
int sock_no_listen(struct socket *, int);
int sock_no_shutdown(struct socket *, int);
-int sock_no_getsockopt(struct socket *, int , int, char __user *, int __user *);
-int sock_no_setsockopt(struct socket *, int, int, char __user *, unsigned int);
int sock_no_sendmsg(struct socket *, struct msghdr *, size_t);
int sock_no_sendmsg_locked(struct sock *sk, struct msghdr *msg, size_t len);
int sock_no_recvmsg(struct socket *, struct msghdr *, size_t, int);
diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c
index 15787e8c0629a0..1d48708c5a2eb5 100644
--- a/net/appletalk/ddp.c
+++ b/net/appletalk/ddp.c
@@ -1917,8 +1917,6 @@ static const struct proto_ops atalk_dgram_ops = {
#endif
.listen = sock_no_listen,
.shutdown = sock_no_shutdown,
- .setsockopt = sock_no_setsockopt,
- .getsockopt = sock_no_getsockopt,
.sendmsg = atalk_sendmsg,
.recvmsg = atalk_recvmsg,
.mmap = sock_no_mmap,
diff --git a/net/bluetooth/bnep/sock.c b/net/bluetooth/bnep/sock.c
index cfd83c5521aecc..d515571b2afba9 100644
--- a/net/bluetooth/bnep/sock.c
+++ b/net/bluetooth/bnep/sock.c
@@ -182,8 +182,6 @@ static const struct proto_ops bnep_sock_ops = {
.recvmsg = sock_no_recvmsg,
.listen = sock_no_listen,
.shutdown = sock_no_shutdown,
- .setsockopt = sock_no_setsockopt,
- .getsockopt = sock_no_getsockopt,
.connect = sock_no_connect,
.socketpair = sock_no_socketpair,
.accept = sock_no_accept,
diff --git a/net/bluetooth/cmtp/sock.c b/net/bluetooth/cmtp/sock.c
index defdd4871919f3..96d49d9fae9643 100644
--- a/net/bluetooth/cmtp/sock.c
+++ b/net/bluetooth/cmtp/sock.c
@@ -185,8 +185,6 @@ static const struct proto_ops cmtp_sock_ops = {
.recvmsg = sock_no_recvmsg,
.listen = sock_no_listen,
.shutdown = sock_no_shutdown,
- .setsockopt = sock_no_setsockopt,
- .getsockopt = sock_no_getsockopt,
.connect = sock_no_connect,
.socketpair = sock_no_socketpair,
.accept = sock_no_accept,
diff --git a/net/bluetooth/hidp/sock.c b/net/bluetooth/hidp/sock.c
index 03be6a4baef30e..595fb3c9d6c361 100644
--- a/net/bluetooth/hidp/sock.c
+++ b/net/bluetooth/hidp/sock.c
@@ -233,8 +233,6 @@ static const struct proto_ops hidp_sock_ops = {
.recvmsg = sock_no_recvmsg,
.listen = sock_no_listen,
.shutdown = sock_no_shutdown,
- .setsockopt = sock_no_setsockopt,
- .getsockopt = sock_no_getsockopt,
.connect = sock_no_connect,
.socketpair = sock_no_socketpair,
.accept = sock_no_accept,
diff --git a/net/caif/caif_socket.c b/net/caif/caif_socket.c
index ef14da50a98191..b94ecd931002e7 100644
--- a/net/caif/caif_socket.c
+++ b/net/caif/caif_socket.c
@@ -981,7 +981,6 @@ static const struct proto_ops caif_seqpacket_ops = {
.listen = sock_no_listen,
.shutdown = sock_no_shutdown,
.setsockopt = setsockopt,
- .getsockopt = sock_no_getsockopt,
.sendmsg = caif_seqpkt_sendmsg,
.recvmsg = caif_seqpkt_recvmsg,
.mmap = sock_no_mmap,
@@ -1002,7 +1001,6 @@ static const struct proto_ops caif_stream_ops = {
.listen = sock_no_listen,
.shutdown = sock_no_shutdown,
.setsockopt = setsockopt,
- .getsockopt = sock_no_getsockopt,
.sendmsg = caif_stream_sendmsg,
.recvmsg = caif_stream_recvmsg,
.mmap = sock_no_mmap,
diff --git a/net/can/bcm.c b/net/can/bcm.c
index c96fa0f33db39c..d14ea12affb112 100644
--- a/net/can/bcm.c
+++ b/net/can/bcm.c
@@ -1648,8 +1648,6 @@ static const struct proto_ops bcm_ops = {
.gettstamp = sock_gettstamp,
.listen = sock_no_listen,
.shutdown = sock_no_shutdown,
- .setsockopt = sock_no_setsockopt,
- .getsockopt = sock_no_getsockopt,
.sendmsg = bcm_sendmsg,
.recvmsg = bcm_recvmsg,
.mmap = sock_no_mmap,
diff --git a/net/core/sock.c b/net/core/sock.c
index 48655d5c4cf37a..d828bfe1c47dfa 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -2783,20 +2783,6 @@ int sock_no_shutdown(struct socket *sock, int how)
}
EXPORT_SYMBOL(sock_no_shutdown);
-int sock_no_setsockopt(struct socket *sock, int level, int optname,
- char __user *optval, unsigned int optlen)
-{
- return -EOPNOTSUPP;
-}
-EXPORT_SYMBOL(sock_no_setsockopt);
-
-int sock_no_getsockopt(struct socket *sock, int level, int optname,
- char __user *optval, int __user *optlen)
-{
- return -EOPNOTSUPP;
-}
-EXPORT_SYMBOL(sock_no_getsockopt);
-
int sock_no_sendmsg(struct socket *sock, struct msghdr *m, size_t len)
{
return -EOPNOTSUPP;
diff --git a/net/key/af_key.c b/net/key/af_key.c
index b67ed3a8486c25..f13626c1a98592 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -3734,8 +3734,6 @@ static const struct proto_ops pfkey_ops = {
.ioctl = sock_no_ioctl,
.listen = sock_no_listen,
.shutdown = sock_no_shutdown,
- .setsockopt = sock_no_setsockopt,
- .getsockopt = sock_no_getsockopt,
.mmap = sock_no_mmap,
.sendpage = sock_no_sendpage,
diff --git a/net/nfc/llcp_sock.c b/net/nfc/llcp_sock.c
index 28604414dec1b7..6da1e2334bb697 100644
--- a/net/nfc/llcp_sock.c
+++ b/net/nfc/llcp_sock.c
@@ -921,8 +921,6 @@ static const struct proto_ops llcp_rawsock_ops = {
.ioctl = sock_no_ioctl,
.listen = sock_no_listen,
.shutdown = sock_no_shutdown,
- .setsockopt = sock_no_setsockopt,
- .getsockopt = sock_no_getsockopt,
.sendmsg = sock_no_sendmsg,
.recvmsg = llcp_sock_recvmsg,
.mmap = sock_no_mmap,
diff --git a/net/nfc/rawsock.c b/net/nfc/rawsock.c
index ba5ffd3badd324..b2061b6746eaa6 100644
--- a/net/nfc/rawsock.c
+++ b/net/nfc/rawsock.c
@@ -276,8 +276,6 @@ static const struct proto_ops rawsock_ops = {
.ioctl = sock_no_ioctl,
.listen = sock_no_listen,
.shutdown = sock_no_shutdown,
- .setsockopt = sock_no_setsockopt,
- .getsockopt = sock_no_getsockopt,
.sendmsg = rawsock_sendmsg,
.recvmsg = rawsock_recvmsg,
.mmap = sock_no_mmap,
@@ -296,8 +294,6 @@ static const struct proto_ops rawsock_raw_ops = {
.ioctl = sock_no_ioctl,
.listen = sock_no_listen,
.shutdown = sock_no_shutdown,
- .setsockopt = sock_no_setsockopt,
- .getsockopt = sock_no_getsockopt,
.sendmsg = sock_no_sendmsg,
.recvmsg = rawsock_recvmsg,
.mmap = sock_no_mmap,
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 35aee9e980536d..c240fb5de3f014 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -4503,8 +4503,6 @@ static const struct proto_ops packet_ops_spkt = {
.gettstamp = sock_gettstamp,
.listen = sock_no_listen,
.shutdown = sock_no_shutdown,
- .setsockopt = sock_no_setsockopt,
- .getsockopt = sock_no_getsockopt,
.sendmsg = packet_sendmsg_spkt,
.recvmsg = packet_recvmsg,
.mmap = sock_no_mmap,
diff --git a/net/phonet/socket.c b/net/phonet/socket.c
index 87c60f83c18061..2599235d592e0b 100644
--- a/net/phonet/socket.c
+++ b/net/phonet/socket.c
@@ -439,8 +439,6 @@ const struct proto_ops phonet_dgram_ops = {
.ioctl = pn_socket_ioctl,
.listen = sock_no_listen,
.shutdown = sock_no_shutdown,
- .setsockopt = sock_no_setsockopt,
- .getsockopt = sock_no_getsockopt,
.sendmsg = pn_socket_sendmsg,
.recvmsg = sock_common_recvmsg,
.mmap = sock_no_mmap,
diff --git a/net/qrtr/qrtr.c b/net/qrtr/qrtr.c
index 24a8c3c6da0dca..0cb4adfc6641da 100644
--- a/net/qrtr/qrtr.c
+++ b/net/qrtr/qrtr.c
@@ -1208,8 +1208,6 @@ static const struct proto_ops qrtr_proto_ops = {
.gettstamp = sock_gettstamp,
.poll = datagram_poll,
.shutdown = sock_no_shutdown,
- .setsockopt = sock_no_setsockopt,
- .getsockopt = sock_no_getsockopt,
.release = qrtr_release,
.mmap = sock_no_mmap,
.sendpage = sock_no_sendpage,
diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c
index 9033215438384b..9711c9e0e515bf 100644
--- a/net/smc/af_smc.c
+++ b/net/smc/af_smc.c
@@ -1742,8 +1742,11 @@ static int smc_setsockopt(struct socket *sock, int level, int optname,
/* generic setsockopts reaching us here always apply to the
* CLC socket
*/
- rc = smc->clcsock->ops->setsockopt(smc->clcsock, level, optname,
- optval, optlen);
+ if (unlikely(!smc->clcsock->ops->setsockopt))
+ rc = -EOPNOTSUPP;
+ else
+ rc = smc->clcsock->ops->setsockopt(smc->clcsock, level, optname,
+ optval, optlen);
if (smc->clcsock->sk->sk_err) {
sk->sk_err = smc->clcsock->sk->sk_err;
sk->sk_error_report(sk);
@@ -1808,6 +1811,8 @@ static int smc_getsockopt(struct socket *sock, int level, int optname,
smc = smc_sk(sock->sk);
/* socket options apply to the CLC socket */
+ if (unlikely(!smc->clcsock->ops->getsockopt))
+ return -EOPNOTSUPP;
return smc->clcsock->ops->getsockopt(smc->clcsock, level, optname,
optval, optlen);
}
diff --git a/net/socket.c b/net/socket.c
index dec345982abbb6..93846568c2fb7a 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -2131,6 +2131,8 @@ int __sys_setsockopt(int fd, int level, int optname, char __user *optval,
if (level == SOL_SOCKET && !sock_use_custom_sol_socket(sock))
err = sock_setsockopt(sock, level, optname, optval, optlen);
+ else if (unlikely(!sock->ops->setsockopt))
+ err = -EOPNOTSUPP;
else
err = sock->ops->setsockopt(sock, level, optname, optval,
optlen);
@@ -2175,6 +2177,8 @@ int __sys_getsockopt(int fd, int level, int optname, char __user *optval,
if (level == SOL_SOCKET)
err = sock_getsockopt(sock, level, optname, optval, optlen);
+ else if (unlikely(!sock->ops->getsockopt))
+ err = -EOPNOTSUPP;
else
err = sock->ops->getsockopt(sock, level, optname, optval,
optlen);
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 3385a7a0b23133..181ea6fb56a617 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -714,8 +714,6 @@ static const struct proto_ops unix_stream_ops = {
#endif
.listen = unix_listen,
.shutdown = unix_shutdown,
- .setsockopt = sock_no_setsockopt,
- .getsockopt = sock_no_getsockopt,
.sendmsg = unix_stream_sendmsg,
.recvmsg = unix_stream_recvmsg,
.mmap = sock_no_mmap,
@@ -741,8 +739,6 @@ static const struct proto_ops unix_dgram_ops = {
#endif
.listen = sock_no_listen,
.shutdown = unix_shutdown,
- .setsockopt = sock_no_setsockopt,
- .getsockopt = sock_no_getsockopt,
.sendmsg = unix_dgram_sendmsg,
.recvmsg = unix_dgram_recvmsg,
.mmap = sock_no_mmap,
@@ -767,8 +763,6 @@ static const struct proto_ops unix_seqpacket_ops = {
#endif
.listen = unix_listen,
.shutdown = unix_shutdown,
- .setsockopt = sock_no_setsockopt,
- .getsockopt = sock_no_getsockopt,
.sendmsg = unix_seqpacket_sendmsg,
.recvmsg = unix_seqpacket_recvmsg,
.mmap = sock_no_mmap,
diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
index 626bf9044418cc..df204c6761c453 100644
--- a/net/vmw_vsock/af_vsock.c
+++ b/net/vmw_vsock/af_vsock.c
@@ -1202,8 +1202,6 @@ static const struct proto_ops vsock_dgram_ops = {
.ioctl = sock_no_ioctl,
.listen = sock_no_listen,
.shutdown = vsock_shutdown,
- .setsockopt = sock_no_setsockopt,
- .getsockopt = sock_no_getsockopt,
.sendmsg = vsock_dgram_sendmsg,
.recvmsg = vsock_dgram_recvmsg,
.mmap = sock_no_mmap,
--
2.27.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* Re: [PATCH 22/22] net: make ->{get,set}sockopt in proto_ops optional
2020-07-17 6:23 ` [PATCH 22/22] net: make ->{get,set}sockopt in proto_ops optional Christoph Hellwig
@ 2020-07-17 8:01 ` Marc Kleine-Budde
0 siblings, 0 replies; 27+ messages in thread
From: Marc Kleine-Budde @ 2020-07-17 8:01 UTC (permalink / raw)
To: Christoph Hellwig, David S. Miller
Cc: Alexei Starovoitov, Daniel Borkmann, Chas Williams,
Pablo Neira Ayuso, Jozsef Kadlecsik, Florian Westphal,
Alexey Kuznetsov, Hideaki YOSHIFUJI, linux-kernel, netdev, bpf,
netfilter-devel, linux-sctp, linux-arch, linux-bluetooth, bridge,
linux-can, dccp, linux-wpan, mptcp
On 7/17/20 8:23 AM, Christoph Hellwig wrote:
> Just check for a NULL method instead of wiring up
> sock_no_{get,set}sockopt.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
> net/can/bcm.c | 2 --
> net/core/sock.c | 14 --------------
For the CAN part:
Acked-by: Marc Kleine-Budde <mkl@pengutronix.de>
Marc
--
Pengutronix e.K. | Marc Kleine-Budde |
Embedded Linux | https://www.pengutronix.de |
Vertretung West/Dortmund | Phone: +49-231-2826-924 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: sockopt cleanups
2020-07-17 6:23 sockopt cleanups Christoph Hellwig
` (21 preceding siblings ...)
2020-07-17 6:23 ` [PATCH 22/22] net: make ->{get,set}sockopt in proto_ops optional Christoph Hellwig
@ 2020-07-20 1:16 ` David Miller
22 siblings, 0 replies; 27+ messages in thread
From: David Miller @ 2020-07-20 1:16 UTC (permalink / raw)
To: hch
Cc: ast, daniel, 3chas3, pablo, kadlec, fw, kuznet, yoshfuji,
linux-kernel, netdev, bpf, netfilter-devel, linux-sctp,
linux-arch, linux-bluetooth, bridge, linux-can, dccp, linux-wpan,
mptcp
From: Christoph Hellwig <hch@lst.de>
Date: Fri, 17 Jul 2020 08:23:09 +0200
> this series cleans up various lose ends in the sockopt code, most
> importantly removing the compat_{get,set}sockopt infrastructure in favor
> of just using in_compat_syscall() in the few places that care.
Series applied to net-next, thanks.
^ permalink raw reply [flat|nested] 27+ messages in thread