const int addrlen,
access_mask_t access_request)
{
+ unsigned short sock_family;
__be16 port;
struct layer_access_masks layer_masks = {};
const struct landlock_rule *rule;
if (addrlen < offsetofend(typeof(*address), sa_family))
return -EINVAL;
+ /*
+ * The socket is not locked, so sk_family can change concurrently due to
+ * e.g. setsockopt(IPV6_ADDRFORM).
+ */
+ sock_family = READ_ONCE(sock->sk->sk_family);
+
switch (address->sa_family) {
case AF_UNSPEC:
if (access_request == LANDLOCK_ACCESS_NET_CONNECT_TCP) {
* these checks, but it is safer to return a proper
* error and test consistency thanks to kselftest.
*/
- if (sock->sk->__sk_common.skc_family == AF_INET) {
+ if (sock_family == AF_INET) {
const struct sockaddr_in *const sockaddr =
(struct sockaddr_in *)address;
* check, but it is safer to return a proper error and test
* consistency thanks to kselftest.
*/
- if (address->sa_family != sock->sk->__sk_common.skc_family &&
+ if (address->sa_family != sock_family &&
address->sa_family != AF_UNSPEC)
return -EINVAL;