Commit 89aec171 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'net-introduce-struct-sockaddr_unsized'

Kees Cook says:

====================
net: Introduce struct sockaddr_unsized

The historically fixed-size struct sockaddr is part of UAPI and embedded
in many existing structures. The kernel uses struct sockaddr extensively
within the kernel to represent arbitrarily sized sockaddr structures,
which caused problems with the compiler's ability to determine object
sizes correctly. The "temporary" solution was to make sockaddr explicitly
use a flexible array, but this causes problems for embedding struct
sockaddr in structures, where once again the compiler has to guess about
the size of such objects, and causes thousands of warnings under the
coming -Wflex-array-member-not-at-end warning.

Switching to sockaddr_storage internally everywhere wastes a lot of memory,
so we are left with needing two changes:
- introduction of an explicitly arbitrarily sized sockaddr struct
- switch struct sockaddr back to being fixed size

Doing the latter step requires all "arbitrarily sized" uses of struct
sockaddr to be replaced with the new struct from the first step.

So, introduce the new struct and do enough conversions that we can
switch sockaddr back to a fixed-size sa_data.
====================

Link: https://patch.msgid.link/20251104002608.do.383-kees@kernel.org


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents bd0fa860 2b5e9f9b
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -145,7 +145,7 @@ void af_alg_release_parent(struct sock *sk)
}
EXPORT_SYMBOL_GPL(af_alg_release_parent);

static int alg_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
static int alg_bind(struct socket *sock, struct sockaddr_unsized *uaddr, int addr_len)
{
	const u32 allowed = CRYPTO_ALG_KERN_DRIVER_ONLY;
	struct sock *sk = sock->sk;
+3 −3
Original line number Diff line number Diff line
@@ -450,7 +450,7 @@ static struct socket *drbd_try_connect(struct drbd_connection *connection)
	*  a free one dynamically.
	*/
	what = "bind before connect";
	err = sock->ops->bind(sock, (struct sockaddr *) &src_in6, my_addr_len);
	err = sock->ops->bind(sock, (struct sockaddr_unsized *) &src_in6, my_addr_len);
	if (err < 0)
		goto out;

@@ -458,7 +458,7 @@ static struct socket *drbd_try_connect(struct drbd_connection *connection)
	 * stay C_WF_CONNECTION, don't go Disconnecting! */
	disconnect_on_error = 0;
	what = "connect";
	err = sock->ops->connect(sock, (struct sockaddr *) &peer_in6, peer_addr_len, 0);
	err = sock->ops->connect(sock, (struct sockaddr_unsized *) &peer_in6, peer_addr_len, 0);

out:
	if (err < 0) {
@@ -537,7 +537,7 @@ static int prepare_listen_socket(struct drbd_connection *connection, struct acce
	drbd_setbufsize(s_listen, sndbuf_size, rcvbuf_size);

	what = "bind before listen";
	err = s_listen->ops->bind(s_listen, (struct sockaddr *)&my_addr, my_addr_len);
	err = s_listen->ops->bind(s_listen, (struct sockaddr_unsized *)&my_addr, my_addr_len);
	if (err < 0)
		goto out;

+3 −3
Original line number Diff line number Diff line
@@ -993,10 +993,10 @@ static int kernel_bindconnect(struct socket *s, struct sockaddr *laddr,
	int ret;

	sock_set_reuseaddr(s->sk);
	ret = s->ops->bind(s, laddr, laddrlen);
	ret = s->ops->bind(s, (struct sockaddr_unsized *)laddr, laddrlen);
	if (ret)
		return ret;
	ret = s->ops->connect(s, raddr, raddrlen, flags);
	ret = s->ops->connect(s, (struct sockaddr_unsized *)raddr, raddrlen, flags);
	return ret < 0 ? ret : 0;
}

@@ -1315,7 +1315,7 @@ int erdma_create_listen(struct iw_cm_id *id, int backlog)
	if (ipv4_is_zeronet(laddr->sin_addr.s_addr))
		s->sk->sk_bound_dev_if = dev->netdev->ifindex;

	ret = s->ops->bind(s, (struct sockaddr *)laddr,
	ret = s->ops->bind(s, (struct sockaddr_unsized *)laddr,
			   sizeof(struct sockaddr_in));
	if (ret)
		goto error;
+4 −4
Original line number Diff line number Diff line
@@ -1340,11 +1340,11 @@ static int kernel_bindconnect(struct socket *s, struct sockaddr *laddr,
			return rv;
	}

	rv = s->ops->bind(s, laddr, size);
	rv = s->ops->bind(s, (struct sockaddr_unsized *)laddr, size);
	if (rv < 0)
		return rv;

	rv = s->ops->connect(s, raddr, size, flags);
	rv = s->ops->connect(s, (struct sockaddr_unsized *)raddr, size, flags);

	return rv < 0 ? rv : 0;
}
@@ -1789,7 +1789,7 @@ int siw_create_listen(struct iw_cm_id *id, int backlog)
				goto error;
			}
		}
		rv = s->ops->bind(s, (struct sockaddr *)laddr,
		rv = s->ops->bind(s, (struct sockaddr_unsized *)laddr,
				  sizeof(struct sockaddr_in));
	} else {
		struct sockaddr_in6 *laddr = &to_sockaddr_in6(id->local_addr);
@@ -1813,7 +1813,7 @@ int siw_create_listen(struct iw_cm_id *id, int backlog)
				goto error;
			}
		}
		rv = s->ops->bind(s, (struct sockaddr *)laddr,
		rv = s->ops->bind(s, (struct sockaddr_unsized *)laddr,
				  sizeof(struct sockaddr_in6));
	}
	if (rv) {
+1 −1
Original line number Diff line number Diff line
@@ -676,7 +676,7 @@ l1oip_socket_thread(void *data)
	hc->sin_remote.sin_port = htons((unsigned short)hc->remoteport);

	/* bind to incoming port */
	if (socket->ops->bind(socket, (struct sockaddr *)&hc->sin_local,
	if (socket->ops->bind(socket, (struct sockaddr_unsized *)&hc->sin_local,
			      sizeof(hc->sin_local))) {
		printk(KERN_ERR "%s: Failed to bind socket to port %d.\n",
		       __func__, hc->localport);
Loading