lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening linux-cve-announce PHC | |
Open Source and information security mailing list archives
| ||
|
Message-ID: <20230811073621.2874702-6-edumazet@google.com> Date: Fri, 11 Aug 2023 07:36:11 +0000 From: Eric Dumazet <edumazet@...gle.com> To: "David S . Miller" <davem@...emloft.net>, Jakub Kicinski <kuba@...nel.org>, Paolo Abeni <pabeni@...hat.com> Cc: Simon Horman <simon.horman@...igine.com>, Soheil Hassas Yeganeh <soheil@...gle.com>, netdev@...r.kernel.org, eric.dumazet@...il.com, Eric Dumazet <edumazet@...gle.com> Subject: [PATCH v2 net-next 05/15] inet: move inet->freebind to inet->inet_flags IP_FREEBIND socket option can now be set/read without locking the socket. Signed-off-by: Eric Dumazet <edumazet@...gle.com> Acked-by: Soheil Hassas Yeganeh <soheil@...gle.com> --- include/net/inet_sock.h | 5 +++-- include/net/ipv6.h | 3 ++- net/ipv4/inet_diag.c | 2 +- net/ipv4/ip_sockglue.c | 21 +++++++++------------ net/ipv6/ipv6_sockglue.c | 4 ++-- net/mptcp/sockopt.c | 8 +++++--- net/sctp/protocol.c | 2 +- 7 files changed, 23 insertions(+), 22 deletions(-) diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h index c01f1f64a8617582c68079048f74e0db606e1834..d6ba963534b4a5aa5dc6f88b94dd36f260be765b 100644 --- a/include/net/inet_sock.h +++ b/include/net/inet_sock.h @@ -231,7 +231,6 @@ struct inet_sock { __u8 mc_ttl; __u8 pmtudisc; __u8 is_icsk:1, - freebind:1, hdrincl:1, mc_loop:1, transparent:1, @@ -271,6 +270,7 @@ enum { INET_FLAGS_RECVERR = 9, INET_FLAGS_RECVERR_RFC4884 = 10, + INET_FLAGS_FREEBIND = 11, }; /* cmsg flags for inet */ @@ -423,7 +423,8 @@ static inline bool inet_can_nonlocal_bind(struct net *net, struct inet_sock *inet) { return READ_ONCE(net->ipv4.sysctl_ip_nonlocal_bind) || - inet->freebind || inet->transparent; + test_bit(INET_FLAGS_FREEBIND, &inet->inet_flags) || + inet->transparent; } static inline bool inet_addr_valid_or_nonlocal(struct net *net, diff --git a/include/net/ipv6.h b/include/net/ipv6.h index 2acc4c808d45d1c1bb1c5076e79842e136203e4c..5f513503e7d568c189a7b14439612f4e27ba539b 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h @@ -937,7 +937,8 @@ static inline bool ipv6_can_nonlocal_bind(struct net *net, struct inet_sock *inet) { return net->ipv6.sysctl.ip_nonlocal_bind || - inet->freebind || inet->transparent; + test_bit(INET_FLAGS_FREEBIND, &inet->inet_flags) || + inet->transparent; } /* Sysctl settings for net ipv6.auto_flowlabels */ diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c index 6255d6fdbc80d82904583a8fc6c439a25e875a0b..5a96f4f28eca6ae6e84cb3761531309e8da0be09 100644 --- a/net/ipv4/inet_diag.c +++ b/net/ipv4/inet_diag.c @@ -184,7 +184,7 @@ int inet_diag_msg_attrs_fill(struct sock *sk, struct sk_buff *skb, memset(&inet_sockopt, 0, sizeof(inet_sockopt)); inet_sockopt.recverr = inet_test_bit(RECVERR, sk); inet_sockopt.is_icsk = inet->is_icsk; - inet_sockopt.freebind = inet->freebind; + inet_sockopt.freebind = inet_test_bit(FREEBIND, sk); inet_sockopt.hdrincl = inet->hdrincl; inet_sockopt.mc_loop = inet->mc_loop; inet_sockopt.transparent = inet->transparent; diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index f75f44ad7b11ac169b343b3c26d744cdc81d747c..6af84310631288c07f26c19734c5abc0fd82dc23 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c @@ -608,9 +608,7 @@ EXPORT_SYMBOL(ip_sock_set_tos); void ip_sock_set_freebind(struct sock *sk) { - lock_sock(sk); - inet_sk(sk)->freebind = true; - release_sock(sk); + inet_set_bit(FREEBIND, sk); } EXPORT_SYMBOL(ip_sock_set_freebind); @@ -985,6 +983,11 @@ int do_ip_setsockopt(struct sock *sk, int level, int optname, return -EINVAL; inet_assign_bit(RECVERR_RFC4884, sk, val); return 0; + case IP_FREEBIND: + if (optlen < 1) + return -EINVAL; + inet_assign_bit(FREEBIND, sk, val); + return 0; } err = 0; @@ -1310,12 +1313,6 @@ int do_ip_setsockopt(struct sock *sk, int level, int optname, inet->mc_all = val; break; - case IP_FREEBIND: - if (optlen < 1) - goto e_inval; - inet->freebind = !!val; - break; - case IP_IPSEC_POLICY: case IP_XFRM_POLICY: err = -EPERM; @@ -1578,6 +1575,9 @@ int do_ip_getsockopt(struct sock *sk, int level, int optname, case IP_RECVERR_RFC4884: val = inet_test_bit(RECVERR_RFC4884, sk); goto copyval; + case IP_FREEBIND: + val = inet_test_bit(FREEBIND, sk); + goto copyval; } if (needs_rtnl) @@ -1737,9 +1737,6 @@ int do_ip_getsockopt(struct sock *sk, int level, int optname, len -= msg.msg_controllen; return copy_to_sockptr(optlen, &len, sizeof(int)); } - case IP_FREEBIND: - val = inet->freebind; - break; case IP_TRANSPARENT: val = inet->transparent; break; diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index ca377159967c8aa9c18a80f9b189f4ef41398d01..3eb38436f8d431ca37200869bfe57ec33b46bf8b 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c @@ -641,7 +641,7 @@ int do_ipv6_setsockopt(struct sock *sk, int level, int optname, if (optlen < sizeof(int)) goto e_inval; /* we also don't have a separate freebind bit for IPV6 */ - inet_sk(sk)->freebind = valbool; + inet_assign_bit(FREEBIND, sk, valbool); retv = 0; break; @@ -1334,7 +1334,7 @@ int do_ipv6_getsockopt(struct sock *sk, int level, int optname, break; case IPV6_FREEBIND: - val = inet_sk(sk)->freebind; + val = inet_test_bit(FREEBIND, sk); break; case IPV6_RECVORIGDSTADDR: diff --git a/net/mptcp/sockopt.c b/net/mptcp/sockopt.c index a3f1fe810cc961bf689fe8edda49d227a3170f91..1f3331f9f7c85f3b2a1e8dc03cf80be73af4ed0d 100644 --- a/net/mptcp/sockopt.c +++ b/net/mptcp/sockopt.c @@ -419,7 +419,8 @@ static int mptcp_setsockopt_v6(struct mptcp_sock *msk, int optname, inet_sk(sk)->transparent = inet_sk(ssock->sk)->transparent; break; case IPV6_FREEBIND: - inet_sk(sk)->freebind = inet_sk(ssock->sk)->freebind; + inet_assign_bit(FREEBIND, sk, + inet_test_bit(FREEBIND, ssock->sk)); break; } @@ -704,7 +705,8 @@ static int mptcp_setsockopt_sol_ip_set_transparent(struct mptcp_sock *msk, int o switch (optname) { case IP_FREEBIND: - issk->freebind = inet_sk(sk)->freebind; + inet_assign_bit(FREEBIND, ssock->sk, + inet_test_bit(FREEBIND, sk)); break; case IP_TRANSPARENT: issk->transparent = inet_sk(sk)->transparent; @@ -1442,7 +1444,7 @@ static void sync_socket_options(struct mptcp_sock *msk, struct sock *ssk) __tcp_sock_set_nodelay(ssk, !!msk->nodelay); inet_sk(ssk)->transparent = inet_sk(sk)->transparent; - inet_sk(ssk)->freebind = inet_sk(sk)->freebind; + inet_assign_bit(FREEBIND, ssk, inet_test_bit(FREEBIND, sk)); } static void __mptcp_sockopt_sync(struct mptcp_sock *msk, struct sock *ssk) diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index 33c0895e101c08d042f16adad7d6ea5ff2bc05c0..2185f44198deb002bc8ed7f1b0f3fe02d6bb9f09 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c @@ -360,7 +360,7 @@ static int sctp_v4_available(union sctp_addr *addr, struct sctp_sock *sp) ret = inet_addr_type_table(net, addr->v4.sin_addr.s_addr, tb_id); if (addr->v4.sin_addr.s_addr != htonl(INADDR_ANY) && ret != RTN_LOCAL && - !sp->inet.freebind && + !inet_test_bit(FREEBIND, sk) && !READ_ONCE(net->ipv4.sysctl_ip_nonlocal_bind)) return 0; -- 2.41.0.640.ga95def55d0-goog
Powered by blists - more mailing lists