Skip to content

Commit c2f1263

Browse files
Christoph Hellwigdavem330
authored andcommitted
netfilter: switch nf_setsockopt to sockptr_t
Pass a sockptr_t to prepare for set_fs-less handling of the kernel pointer from bpf-cgroup. Signed-off-by: Christoph Hellwig <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent ab214d1 commit c2f1263

File tree

10 files changed

+68
-66
lines changed

10 files changed

+68
-66
lines changed

include/linux/netfilter.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <linux/static_key.h>
1414
#include <linux/netfilter_defs.h>
1515
#include <linux/netdevice.h>
16+
#include <linux/sockptr.h>
1617
#include <net/net_namespace.h>
1718

1819
static inline int NF_DROP_GETERR(int verdict)
@@ -163,7 +164,8 @@ struct nf_sockopt_ops {
163164
/* Non-inclusive ranges: use 0/0/NULL to never get called. */
164165
int set_optmin;
165166
int set_optmax;
166-
int (*set)(struct sock *sk, int optval, void __user *user, unsigned int len);
167+
int (*set)(struct sock *sk, int optval, sockptr_t arg,
168+
unsigned int len);
167169
int get_optmin;
168170
int get_optmax;
169171
int (*get)(struct sock *sk, int optval, void __user *user, int *len);
@@ -338,7 +340,7 @@ NF_HOOK_LIST(uint8_t pf, unsigned int hook, struct net *net, struct sock *sk,
338340
}
339341

340342
/* Call setsockopt() */
341-
int nf_setsockopt(struct sock *sk, u_int8_t pf, int optval, char __user *opt,
343+
int nf_setsockopt(struct sock *sk, u_int8_t pf, int optval, sockptr_t opt,
342344
unsigned int len);
343345
int nf_getsockopt(struct sock *sk, u_int8_t pf, int optval, char __user *opt,
344346
int *len);

net/bridge/netfilter/ebtables.c

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1063,14 +1063,13 @@ static int do_replace_finish(struct net *net, struct ebt_replace *repl,
10631063
}
10641064

10651065
/* replace the table */
1066-
static int do_replace(struct net *net, const void __user *user,
1067-
unsigned int len)
1066+
static int do_replace(struct net *net, sockptr_t arg, unsigned int len)
10681067
{
10691068
int ret, countersize;
10701069
struct ebt_table_info *newinfo;
10711070
struct ebt_replace tmp;
10721071

1073-
if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
1072+
if (copy_from_sockptr(&tmp, arg, sizeof(tmp)) != 0)
10741073
return -EFAULT;
10751074

10761075
if (len != sizeof(tmp) + tmp.entries_size)
@@ -1286,12 +1285,11 @@ static int do_update_counters(struct net *net, const char *name,
12861285
return ret;
12871286
}
12881287

1289-
static int update_counters(struct net *net, const void __user *user,
1290-
unsigned int len)
1288+
static int update_counters(struct net *net, sockptr_t arg, unsigned int len)
12911289
{
12921290
struct ebt_replace hlp;
12931291

1294-
if (copy_from_user(&hlp, user, sizeof(hlp)))
1292+
if (copy_from_sockptr(&hlp, arg, sizeof(hlp)))
12951293
return -EFAULT;
12961294

12971295
if (len != sizeof(hlp) + hlp.num_counters * sizeof(struct ebt_counter))
@@ -2079,15 +2077,15 @@ static int compat_copy_entries(unsigned char *data, unsigned int size_user,
20792077

20802078

20812079
static int compat_copy_ebt_replace_from_user(struct ebt_replace *repl,
2082-
void __user *user, unsigned int len)
2080+
sockptr_t arg, unsigned int len)
20832081
{
20842082
struct compat_ebt_replace tmp;
20852083
int i;
20862084

20872085
if (len < sizeof(tmp))
20882086
return -EINVAL;
20892087

2090-
if (copy_from_user(&tmp, user, sizeof(tmp)))
2088+
if (copy_from_sockptr(&tmp, arg, sizeof(tmp)))
20912089
return -EFAULT;
20922090

20932091
if (len != sizeof(tmp) + tmp.entries_size)
@@ -2114,19 +2112,18 @@ static int compat_copy_ebt_replace_from_user(struct ebt_replace *repl,
21142112
return 0;
21152113
}
21162114

2117-
static int compat_do_replace(struct net *net, void __user *user,
2118-
unsigned int len)
2115+
static int compat_do_replace(struct net *net, sockptr_t arg, unsigned int len)
21192116
{
21202117
int ret, i, countersize, size64;
21212118
struct ebt_table_info *newinfo;
21222119
struct ebt_replace tmp;
21232120
struct ebt_entries_buf_state state;
21242121
void *entries_tmp;
21252122

2126-
ret = compat_copy_ebt_replace_from_user(&tmp, user, len);
2123+
ret = compat_copy_ebt_replace_from_user(&tmp, arg, len);
21272124
if (ret) {
21282125
/* try real handler in case userland supplied needed padding */
2129-
if (ret == -EINVAL && do_replace(net, user, len) == 0)
2126+
if (ret == -EINVAL && do_replace(net, arg, len) == 0)
21302127
ret = 0;
21312128
return ret;
21322129
}
@@ -2217,17 +2214,17 @@ static int compat_do_replace(struct net *net, void __user *user,
22172214
goto free_entries;
22182215
}
22192216

2220-
static int compat_update_counters(struct net *net, void __user *user,
2217+
static int compat_update_counters(struct net *net, sockptr_t arg,
22212218
unsigned int len)
22222219
{
22232220
struct compat_ebt_replace hlp;
22242221

2225-
if (copy_from_user(&hlp, user, sizeof(hlp)))
2222+
if (copy_from_sockptr(&hlp, arg, sizeof(hlp)))
22262223
return -EFAULT;
22272224

22282225
/* try real handler in case userland supplied needed padding */
22292226
if (len != sizeof(hlp) + hlp.num_counters * sizeof(struct ebt_counter))
2230-
return update_counters(net, user, len);
2227+
return update_counters(net, arg, len);
22312228

22322229
return do_update_counters(net, hlp.name, compat_ptr(hlp.counters),
22332230
hlp.num_counters, len);
@@ -2368,7 +2365,7 @@ static int do_ebt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
23682365
return ret;
23692366
}
23702367

2371-
static int do_ebt_set_ctl(struct sock *sk, int cmd, void __user *user,
2368+
static int do_ebt_set_ctl(struct sock *sk, int cmd, sockptr_t arg,
23722369
unsigned int len)
23732370
{
23742371
struct net *net = sock_net(sk);
@@ -2381,18 +2378,18 @@ static int do_ebt_set_ctl(struct sock *sk, int cmd, void __user *user,
23812378
case EBT_SO_SET_ENTRIES:
23822379
#ifdef CONFIG_COMPAT
23832380
if (in_compat_syscall())
2384-
ret = compat_do_replace(net, user, len);
2381+
ret = compat_do_replace(net, arg, len);
23852382
else
23862383
#endif
2387-
ret = do_replace(net, user, len);
2384+
ret = do_replace(net, arg, len);
23882385
break;
23892386
case EBT_SO_SET_COUNTERS:
23902387
#ifdef CONFIG_COMPAT
23912388
if (in_compat_syscall())
2392-
ret = compat_update_counters(net, user, len);
2389+
ret = compat_update_counters(net, arg, len);
23932390
else
23942391
#endif
2395-
ret = update_counters(net, user, len);
2392+
ret = update_counters(net, arg, len);
23962393
break;
23972394
default:
23982395
ret = -EINVAL;

net/decnet/af_decnet.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1332,7 +1332,8 @@ static int dn_setsockopt(struct socket *sock, int level, int optname, char __use
13321332
/* we need to exclude all possible ENOPROTOOPTs except default case */
13331333
if (err == -ENOPROTOOPT && optname != DSO_LINKINFO &&
13341334
optname != DSO_STREAM && optname != DSO_SEQPACKET)
1335-
err = nf_setsockopt(sk, PF_DECnet, optname, optval, optlen);
1335+
err = nf_setsockopt(sk, PF_DECnet, optname,
1336+
USER_SOCKPTR(optval), optlen);
13361337
#endif
13371338

13381339
return err;

net/ipv4/ip_sockglue.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1422,7 +1422,8 @@ int ip_setsockopt(struct sock *sk, int level,
14221422
optname != IP_IPSEC_POLICY &&
14231423
optname != IP_XFRM_POLICY &&
14241424
!ip_mroute_opt(optname))
1425-
err = nf_setsockopt(sk, PF_INET, optname, optval, optlen);
1425+
err = nf_setsockopt(sk, PF_INET, optname, USER_SOCKPTR(optval),
1426+
optlen);
14261427
#endif
14271428
return err;
14281429
}

net/ipv4/netfilter/arp_tables.c

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// SPDX-License-Identifier: GPL-2.0-only
1+
22
/*
33
* Packet matching code for ARP packets.
44
*
@@ -947,16 +947,15 @@ static int __do_replace(struct net *net, const char *name,
947947
return ret;
948948
}
949949

950-
static int do_replace(struct net *net, const void __user *user,
951-
unsigned int len)
950+
static int do_replace(struct net *net, sockptr_t arg, unsigned int len)
952951
{
953952
int ret;
954953
struct arpt_replace tmp;
955954
struct xt_table_info *newinfo;
956955
void *loc_cpu_entry;
957956
struct arpt_entry *iter;
958957

959-
if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
958+
if (copy_from_sockptr(&tmp, arg, sizeof(tmp)) != 0)
960959
return -EFAULT;
961960

962961
/* overflow check */
@@ -972,8 +971,8 @@ static int do_replace(struct net *net, const void __user *user,
972971
return -ENOMEM;
973972

974973
loc_cpu_entry = newinfo->entries;
975-
if (copy_from_user(loc_cpu_entry, user + sizeof(tmp),
976-
tmp.size) != 0) {
974+
sockptr_advance(arg, sizeof(tmp));
975+
if (copy_from_sockptr(loc_cpu_entry, arg, tmp.size) != 0) {
977976
ret = -EFAULT;
978977
goto free_newinfo;
979978
}
@@ -1244,16 +1243,15 @@ static int translate_compat_table(struct net *net,
12441243
return ret;
12451244
}
12461245

1247-
static int compat_do_replace(struct net *net, void __user *user,
1248-
unsigned int len)
1246+
static int compat_do_replace(struct net *net, sockptr_t arg, unsigned int len)
12491247
{
12501248
int ret;
12511249
struct compat_arpt_replace tmp;
12521250
struct xt_table_info *newinfo;
12531251
void *loc_cpu_entry;
12541252
struct arpt_entry *iter;
12551253

1256-
if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
1254+
if (copy_from_sockptr(&tmp, arg, sizeof(tmp)) != 0)
12571255
return -EFAULT;
12581256

12591257
/* overflow check */
@@ -1269,7 +1267,8 @@ static int compat_do_replace(struct net *net, void __user *user,
12691267
return -ENOMEM;
12701268

12711269
loc_cpu_entry = newinfo->entries;
1272-
if (copy_from_user(loc_cpu_entry, user + sizeof(tmp), tmp.size) != 0) {
1270+
sockptr_advance(arg, sizeof(tmp));
1271+
if (copy_from_sockptr(loc_cpu_entry, arg, tmp.size) != 0) {
12731272
ret = -EFAULT;
12741273
goto free_newinfo;
12751274
}
@@ -1401,7 +1400,8 @@ static int compat_get_entries(struct net *net,
14011400
}
14021401
#endif
14031402

1404-
static int do_arpt_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
1403+
static int do_arpt_set_ctl(struct sock *sk, int cmd, sockptr_t arg,
1404+
unsigned int len)
14051405
{
14061406
int ret;
14071407

@@ -1412,14 +1412,14 @@ static int do_arpt_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned
14121412
case ARPT_SO_SET_REPLACE:
14131413
#ifdef CONFIG_COMPAT
14141414
if (in_compat_syscall())
1415-
ret = compat_do_replace(sock_net(sk), user, len);
1415+
ret = compat_do_replace(sock_net(sk), arg, len);
14161416
else
14171417
#endif
1418-
ret = do_replace(sock_net(sk), user, len);
1418+
ret = do_replace(sock_net(sk), arg, len);
14191419
break;
14201420

14211421
case ARPT_SO_SET_ADD_COUNTERS:
1422-
ret = do_add_counters(sock_net(sk), USER_SOCKPTR(user), len);
1422+
ret = do_add_counters(sock_net(sk), arg, len);
14231423
break;
14241424

14251425
default:

net/ipv4/netfilter/ip_tables.c

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1102,15 +1102,15 @@ __do_replace(struct net *net, const char *name, unsigned int valid_hooks,
11021102
}
11031103

11041104
static int
1105-
do_replace(struct net *net, const void __user *user, unsigned int len)
1105+
do_replace(struct net *net, sockptr_t arg, unsigned int len)
11061106
{
11071107
int ret;
11081108
struct ipt_replace tmp;
11091109
struct xt_table_info *newinfo;
11101110
void *loc_cpu_entry;
11111111
struct ipt_entry *iter;
11121112

1113-
if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
1113+
if (copy_from_sockptr(&tmp, arg, sizeof(tmp)) != 0)
11141114
return -EFAULT;
11151115

11161116
/* overflow check */
@@ -1126,8 +1126,8 @@ do_replace(struct net *net, const void __user *user, unsigned int len)
11261126
return -ENOMEM;
11271127

11281128
loc_cpu_entry = newinfo->entries;
1129-
if (copy_from_user(loc_cpu_entry, user + sizeof(tmp),
1130-
tmp.size) != 0) {
1129+
sockptr_advance(arg, sizeof(tmp));
1130+
if (copy_from_sockptr(loc_cpu_entry, arg, tmp.size) != 0) {
11311131
ret = -EFAULT;
11321132
goto free_newinfo;
11331133
}
@@ -1484,15 +1484,15 @@ translate_compat_table(struct net *net,
14841484
}
14851485

14861486
static int
1487-
compat_do_replace(struct net *net, void __user *user, unsigned int len)
1487+
compat_do_replace(struct net *net, sockptr_t arg, unsigned int len)
14881488
{
14891489
int ret;
14901490
struct compat_ipt_replace tmp;
14911491
struct xt_table_info *newinfo;
14921492
void *loc_cpu_entry;
14931493
struct ipt_entry *iter;
14941494

1495-
if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
1495+
if (copy_from_sockptr(&tmp, arg, sizeof(tmp)) != 0)
14961496
return -EFAULT;
14971497

14981498
/* overflow check */
@@ -1508,8 +1508,8 @@ compat_do_replace(struct net *net, void __user *user, unsigned int len)
15081508
return -ENOMEM;
15091509

15101510
loc_cpu_entry = newinfo->entries;
1511-
if (copy_from_user(loc_cpu_entry, user + sizeof(tmp),
1512-
tmp.size) != 0) {
1511+
sockptr_advance(arg, sizeof(tmp));
1512+
if (copy_from_sockptr(loc_cpu_entry, arg, tmp.size) != 0) {
15131513
ret = -EFAULT;
15141514
goto free_newinfo;
15151515
}
@@ -1610,7 +1610,7 @@ compat_get_entries(struct net *net, struct compat_ipt_get_entries __user *uptr,
16101610
#endif
16111611

16121612
static int
1613-
do_ipt_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
1613+
do_ipt_set_ctl(struct sock *sk, int cmd, sockptr_t arg, unsigned int len)
16141614
{
16151615
int ret;
16161616

@@ -1621,14 +1621,14 @@ do_ipt_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
16211621
case IPT_SO_SET_REPLACE:
16221622
#ifdef CONFIG_COMPAT
16231623
if (in_compat_syscall())
1624-
ret = compat_do_replace(sock_net(sk), user, len);
1624+
ret = compat_do_replace(sock_net(sk), arg, len);
16251625
else
16261626
#endif
1627-
ret = do_replace(sock_net(sk), user, len);
1627+
ret = do_replace(sock_net(sk), arg, len);
16281628
break;
16291629

16301630
case IPT_SO_SET_ADD_COUNTERS:
1631-
ret = do_add_counters(sock_net(sk), USER_SOCKPTR(user), len);
1631+
ret = do_add_counters(sock_net(sk), arg, len);
16321632
break;
16331633

16341634
default:

net/ipv6/ipv6_sockglue.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -996,7 +996,8 @@ int ipv6_setsockopt(struct sock *sk, int level, int optname,
996996
/* we need to exclude all possible ENOPROTOOPTs except default case */
997997
if (err == -ENOPROTOOPT && optname != IPV6_IPSEC_POLICY &&
998998
optname != IPV6_XFRM_POLICY)
999-
err = nf_setsockopt(sk, PF_INET6, optname, optval, optlen);
999+
err = nf_setsockopt(sk, PF_INET6, optname, USER_SOCKPTR(optval),
1000+
optlen);
10001001
#endif
10011002
return err;
10021003
}

0 commit comments

Comments
 (0)