Skip to content

Commit c889a99

Browse files
jrifedavem330
authored andcommitted
net: prevent address rewrite in kernel_bind()
Similar to the change in commit 0bdf399("net: Avoid address overwrite in kernel_connect"), BPF hooks run on bind may rewrite the address passed to kernel_bind(). This change 1) Makes a copy of the bind address in kernel_bind() to insulate callers. 2) Replaces direct calls to sock->ops->bind() in net with kernel_bind() Link: https://lore.kernel.org/netdev/20230912013332.2048422-1-jrife@google.com/ Fixes: 4fbac77 ("bpf: Hooks for sys_bind") Cc: stable@vger.kernel.org Reviewed-by: Willem de Bruijn <willemb@google.com> Signed-off-by: Jordan Rife <jrife@google.com> Reviewed-by: Simon Horman <horms@kernel.org> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 86a7e0b commit c889a99

File tree

4 files changed

+10
-5
lines changed

4 files changed

+10
-5
lines changed

net/netfilter/ipvs/ip_vs_sync.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1439,7 +1439,7 @@ static int bind_mcastif_addr(struct socket *sock, struct net_device *dev)
14391439
sin.sin_addr.s_addr = addr;
14401440
sin.sin_port = 0;
14411441

1442-
return sock->ops->bind(sock, (struct sockaddr*)&sin, sizeof(sin));
1442+
return kernel_bind(sock, (struct sockaddr *)&sin, sizeof(sin));
14431443
}
14441444

14451445
static void get_mcast_sockaddr(union ipvs_sockaddr *sa, int *salen,
@@ -1546,7 +1546,7 @@ static int make_receive_sock(struct netns_ipvs *ipvs, int id,
15461546

15471547
get_mcast_sockaddr(&mcast_addr, &salen, &ipvs->bcfg, id);
15481548
sock->sk->sk_bound_dev_if = dev->ifindex;
1549-
result = sock->ops->bind(sock, (struct sockaddr *)&mcast_addr, salen);
1549+
result = kernel_bind(sock, (struct sockaddr *)&mcast_addr, salen);
15501550
if (result < 0) {
15511551
pr_err("Error binding to the multicast addr\n");
15521552
goto error;

net/rds/tcp_connect.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ int rds_tcp_conn_path_connect(struct rds_conn_path *cp)
145145
addrlen = sizeof(sin);
146146
}
147147

148-
ret = sock->ops->bind(sock, addr, addrlen);
148+
ret = kernel_bind(sock, addr, addrlen);
149149
if (ret) {
150150
rdsdebug("bind failed with %d at address %pI6c\n",
151151
ret, &conn->c_laddr);

net/rds/tcp_listen.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,7 @@ struct socket *rds_tcp_listen_init(struct net *net, bool isv6)
306306
addr_len = sizeof(*sin);
307307
}
308308

309-
ret = sock->ops->bind(sock, (struct sockaddr *)&ss, addr_len);
309+
ret = kernel_bind(sock, (struct sockaddr *)&ss, addr_len);
310310
if (ret < 0) {
311311
rdsdebug("could not bind %s listener socket: %d\n",
312312
isv6 ? "IPv6" : "IPv4", ret);

net/socket.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3516,7 +3516,12 @@ static long compat_sock_ioctl(struct file *file, unsigned int cmd,
35163516

35173517
int kernel_bind(struct socket *sock, struct sockaddr *addr, int addrlen)
35183518
{
3519-
return READ_ONCE(sock->ops)->bind(sock, addr, addrlen);
3519+
struct sockaddr_storage address;
3520+
3521+
memcpy(&address, addr, addrlen);
3522+
3523+
return READ_ONCE(sock->ops)->bind(sock, (struct sockaddr *)&address,
3524+
addrlen);
35203525
}
35213526
EXPORT_SYMBOL(kernel_bind);
35223527

0 commit comments

Comments
 (0)