Skip to content

Commit d3c4815

Browse files
Christoph Hellwigdavem330
authored andcommitted
net: remove sockptr_advance
sockptr_advance never properly worked. Replace it with _offset variants of copy_from_sockptr and copy_to_sockptr. Fixes: ba423fd ("net: add a new sockptr_t type") Reported-by: Jason A. Donenfeld <[email protected]> Reported-by: Ido Schimmel <[email protected]> Signed-off-by: Christoph Hellwig <[email protected]> Acked-by: Jason A. Donenfeld <[email protected]> Tested-by: Ido Schimmel <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 035bfd0 commit d3c4815

File tree

10 files changed

+49
-48
lines changed

10 files changed

+49
-48
lines changed

drivers/crypto/chelsio/chtls/chtls_main.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -525,9 +525,9 @@ static int do_chtls_setsockopt(struct sock *sk, int optname,
525525
/* Obtain version and type from previous copy */
526526
crypto_info[0] = tmp_crypto_info;
527527
/* Now copy the following data */
528-
sockptr_advance(optval, sizeof(*crypto_info));
529-
rc = copy_from_sockptr((char *)crypto_info + sizeof(*crypto_info),
530-
optval,
528+
rc = copy_from_sockptr_offset((char *)crypto_info +
529+
sizeof(*crypto_info),
530+
optval, sizeof(*crypto_info),
531531
sizeof(struct tls12_crypto_info_aes_gcm_128)
532532
- sizeof(*crypto_info));
533533

@@ -542,9 +542,9 @@ static int do_chtls_setsockopt(struct sock *sk, int optname,
542542
}
543543
case TLS_CIPHER_AES_GCM_256: {
544544
crypto_info[0] = tmp_crypto_info;
545-
sockptr_advance(optval, sizeof(*crypto_info));
546-
rc = copy_from_sockptr((char *)crypto_info + sizeof(*crypto_info),
547-
optval,
545+
rc = copy_from_sockptr_offset((char *)crypto_info +
546+
sizeof(*crypto_info),
547+
optval, sizeof(*crypto_info),
548548
sizeof(struct tls12_crypto_info_aes_gcm_256)
549549
- sizeof(*crypto_info));
550550

include/linux/sockptr.h

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -69,19 +69,26 @@ static inline bool sockptr_is_null(sockptr_t sockptr)
6969
return !sockptr.user;
7070
}
7171

72-
static inline int copy_from_sockptr(void *dst, sockptr_t src, size_t size)
72+
static inline int copy_from_sockptr_offset(void *dst, sockptr_t src,
73+
size_t offset, size_t size)
7374
{
7475
if (!sockptr_is_kernel(src))
75-
return copy_from_user(dst, src.user, size);
76-
memcpy(dst, src.kernel, size);
76+
return copy_from_user(dst, src.user + offset, size);
77+
memcpy(dst, src.kernel + offset, size);
7778
return 0;
7879
}
7980

80-
static inline int copy_to_sockptr(sockptr_t dst, const void *src, size_t size)
81+
static inline int copy_from_sockptr(void *dst, sockptr_t src, size_t size)
82+
{
83+
return copy_from_sockptr_offset(dst, src, 0, size);
84+
}
85+
86+
static inline int copy_to_sockptr_offset(sockptr_t dst, size_t offset,
87+
const void *src, size_t size)
8188
{
8289
if (!sockptr_is_kernel(dst))
83-
return copy_to_user(dst.user, src, size);
84-
memcpy(dst.kernel, src, size);
90+
return copy_to_user(dst.user + offset, src, size);
91+
memcpy(dst.kernel + offset, src, size);
8592
return 0;
8693
}
8794

@@ -112,14 +119,6 @@ static inline void *memdup_sockptr_nul(sockptr_t src, size_t len)
112119
return p;
113120
}
114121

115-
static inline void sockptr_advance(sockptr_t sockptr, size_t len)
116-
{
117-
if (sockptr_is_kernel(sockptr))
118-
sockptr.kernel += len;
119-
else
120-
sockptr.user += len;
121-
}
122-
123122
static inline long strncpy_from_sockptr(char *dst, sockptr_t src, size_t count)
124123
{
125124
if (sockptr_is_kernel(src)) {

net/dccp/proto.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -426,9 +426,8 @@ static int dccp_setsockopt_service(struct sock *sk, const __be32 service,
426426
return -ENOMEM;
427427

428428
sl->dccpsl_nr = optlen / sizeof(u32) - 1;
429-
sockptr_advance(optval, sizeof(service));
430-
if (copy_from_sockptr(sl->dccpsl_list, optval,
431-
optlen - sizeof(service)) ||
429+
if (copy_from_sockptr_offset(sl->dccpsl_list, optval,
430+
sizeof(service), optlen - sizeof(service)) ||
432431
dccp_list_has_service(sl, DCCP_SERVICE_INVALID_VALUE)) {
433432
kfree(sl);
434433
return -EFAULT;

net/ipv4/netfilter/arp_tables.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -971,8 +971,8 @@ static int do_replace(struct net *net, sockptr_t arg, unsigned int len)
971971
return -ENOMEM;
972972

973973
loc_cpu_entry = newinfo->entries;
974-
sockptr_advance(arg, sizeof(tmp));
975-
if (copy_from_sockptr(loc_cpu_entry, arg, tmp.size) != 0) {
974+
if (copy_from_sockptr_offset(loc_cpu_entry, arg, sizeof(tmp),
975+
tmp.size) != 0) {
976976
ret = -EFAULT;
977977
goto free_newinfo;
978978
}
@@ -1267,8 +1267,8 @@ static int compat_do_replace(struct net *net, sockptr_t arg, unsigned int len)
12671267
return -ENOMEM;
12681268

12691269
loc_cpu_entry = newinfo->entries;
1270-
sockptr_advance(arg, sizeof(tmp));
1271-
if (copy_from_sockptr(loc_cpu_entry, arg, tmp.size) != 0) {
1270+
if (copy_from_sockptr_offset(loc_cpu_entry, arg, sizeof(tmp),
1271+
tmp.size) != 0) {
12721272
ret = -EFAULT;
12731273
goto free_newinfo;
12741274
}

net/ipv4/netfilter/ip_tables.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1126,8 +1126,8 @@ do_replace(struct net *net, sockptr_t arg, unsigned int len)
11261126
return -ENOMEM;
11271127

11281128
loc_cpu_entry = newinfo->entries;
1129-
sockptr_advance(arg, sizeof(tmp));
1130-
if (copy_from_sockptr(loc_cpu_entry, arg, tmp.size) != 0) {
1129+
if (copy_from_sockptr_offset(loc_cpu_entry, arg, sizeof(tmp),
1130+
tmp.size) != 0) {
11311131
ret = -EFAULT;
11321132
goto free_newinfo;
11331133
}
@@ -1508,8 +1508,8 @@ compat_do_replace(struct net *net, sockptr_t arg, unsigned int len)
15081508
return -ENOMEM;
15091509

15101510
loc_cpu_entry = newinfo->entries;
1511-
sockptr_advance(arg, sizeof(tmp));
1512-
if (copy_from_sockptr(loc_cpu_entry, arg, tmp.size) != 0) {
1511+
if (copy_from_sockptr_offset(loc_cpu_entry, arg, sizeof(tmp),
1512+
tmp.size) != 0) {
15131513
ret = -EFAULT;
15141514
goto free_newinfo;
15151515
}

net/ipv4/tcp.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2801,12 +2801,13 @@ static int tcp_repair_options_est(struct sock *sk, sockptr_t optbuf,
28012801
{
28022802
struct tcp_sock *tp = tcp_sk(sk);
28032803
struct tcp_repair_opt opt;
2804+
size_t offset = 0;
28042805

28052806
while (len >= sizeof(opt)) {
2806-
if (copy_from_sockptr(&opt, optbuf, sizeof(opt)))
2807+
if (copy_from_sockptr_offset(&opt, optbuf, offset, sizeof(opt)))
28072808
return -EFAULT;
28082809

2809-
sockptr_advance(optbuf, sizeof(opt));
2810+
offset += sizeof(opt);
28102811
len -= sizeof(opt);
28112812

28122813
switch (opt.opt_code) {

net/ipv6/ip6_flowlabel.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -401,8 +401,8 @@ fl_create(struct net *net, struct sock *sk, struct in6_flowlabel_req *freq,
401401
memset(fl->opt, 0, sizeof(*fl->opt));
402402
fl->opt->tot_len = sizeof(*fl->opt) + olen;
403403
err = -EFAULT;
404-
sockptr_advance(optval, CMSG_ALIGN(sizeof(*freq)));
405-
if (copy_from_sockptr(fl->opt + 1, optval, olen))
404+
if (copy_from_sockptr_offset(fl->opt + 1, optval,
405+
CMSG_ALIGN(sizeof(*freq)), olen))
406406
goto done;
407407

408408
msg.msg_controllen = olen;
@@ -703,9 +703,10 @@ static int ipv6_flowlabel_get(struct sock *sk, struct in6_flowlabel_req *freq,
703703
goto recheck;
704704

705705
if (!freq->flr_label) {
706-
sockptr_advance(optval,
707-
offsetof(struct in6_flowlabel_req, flr_label));
708-
if (copy_to_sockptr(optval, &fl->label, sizeof(fl->label))) {
706+
size_t offset = offsetof(struct in6_flowlabel_req, flr_label);
707+
708+
if (copy_to_sockptr_offset(optval, offset, &fl->label,
709+
sizeof(fl->label))) {
709710
/* Intentionally ignore fault. */
710711
}
711712
}

net/ipv6/netfilter/ip6_tables.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1143,8 +1143,8 @@ do_replace(struct net *net, sockptr_t arg, unsigned int len)
11431143
return -ENOMEM;
11441144

11451145
loc_cpu_entry = newinfo->entries;
1146-
sockptr_advance(arg, sizeof(tmp));
1147-
if (copy_from_sockptr(loc_cpu_entry, arg, tmp.size) != 0) {
1146+
if (copy_from_sockptr_offset(loc_cpu_entry, arg, sizeof(tmp),
1147+
tmp.size) != 0) {
11481148
ret = -EFAULT;
11491149
goto free_newinfo;
11501150
}
@@ -1517,8 +1517,8 @@ compat_do_replace(struct net *net, sockptr_t arg, unsigned int len)
15171517
return -ENOMEM;
15181518

15191519
loc_cpu_entry = newinfo->entries;
1520-
sockptr_advance(arg, sizeof(tmp));
1521-
if (copy_from_sockptr(loc_cpu_entry, arg, tmp.size) != 0) {
1520+
if (copy_from_sockptr_offset(loc_cpu_entry, arg, sizeof(tmp),
1521+
tmp.size) != 0) {
15221522
ret = -EFAULT;
15231523
goto free_newinfo;
15241524
}

net/netfilter/x_tables.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1050,6 +1050,7 @@ EXPORT_SYMBOL_GPL(xt_check_target);
10501050
void *xt_copy_counters(sockptr_t arg, unsigned int len,
10511051
struct xt_counters_info *info)
10521052
{
1053+
size_t offset;
10531054
void *mem;
10541055
u64 size;
10551056

@@ -1067,7 +1068,7 @@ void *xt_copy_counters(sockptr_t arg, unsigned int len,
10671068

10681069
memcpy(info->name, compat_tmp.name, sizeof(info->name) - 1);
10691070
info->num_counters = compat_tmp.num_counters;
1070-
sockptr_advance(arg, sizeof(compat_tmp));
1071+
offset = sizeof(compat_tmp);
10711072
} else
10721073
#endif
10731074
{
@@ -1078,7 +1079,7 @@ void *xt_copy_counters(sockptr_t arg, unsigned int len,
10781079
if (copy_from_sockptr(info, arg, sizeof(*info)) != 0)
10791080
return ERR_PTR(-EFAULT);
10801081

1081-
sockptr_advance(arg, sizeof(*info));
1082+
offset = sizeof(*info);
10821083
}
10831084
info->name[sizeof(info->name) - 1] = '\0';
10841085

@@ -1092,7 +1093,7 @@ void *xt_copy_counters(sockptr_t arg, unsigned int len,
10921093
if (!mem)
10931094
return ERR_PTR(-ENOMEM);
10941095

1095-
if (copy_from_sockptr(mem, arg, len) == 0)
1096+
if (copy_from_sockptr_offset(mem, arg, offset, len) == 0)
10961097
return mem;
10971098

10981099
vfree(mem);

net/tls/tls_main.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -522,9 +522,9 @@ static int do_tls_setsockopt_conf(struct sock *sk, sockptr_t optval,
522522
goto err_crypto_info;
523523
}
524524

525-
sockptr_advance(optval, sizeof(*crypto_info));
526-
rc = copy_from_sockptr(crypto_info + 1, optval,
527-
optlen - sizeof(*crypto_info));
525+
rc = copy_from_sockptr_offset(crypto_info + 1, optval,
526+
sizeof(*crypto_info),
527+
optlen - sizeof(*crypto_info));
528528
if (rc) {
529529
rc = -EFAULT;
530530
goto err_crypto_info;

0 commit comments

Comments
 (0)