[PATCH 3/7] net/tcp: Limit TCP_AO_REPAIR to non-listen sockets

Dmitry Safonov posted 7 patches 2 years ago
There is a newer version of this series
[PATCH 3/7] net/tcp: Limit TCP_AO_REPAIR to non-listen sockets
Posted by Dmitry Safonov 2 years ago
Listen socket is not an established TCP connection, so
setsockopt(TCP_AO_REPAIR) doesn't have any impact.

Restrict this uAPI for listen sockets.

Fixes: faadfaba5e01 ("net/tcp: Add TCP_AO_REPAIR")
Signed-off-by: Dmitry Safonov <dima@arista.com>
---
 net/ipv4/tcp.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 53bcc17c91e4..2836515ab3d7 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -3594,6 +3594,10 @@ int do_tcp_setsockopt(struct sock *sk, int level, int optname,
 		break;
 
 	case TCP_AO_REPAIR:
+		if (sk->sk_state == TCP_LISTEN) {
+			err = -ENOSTR;
+			break;
+		}
 		err = tcp_ao_set_repair(sk, optval, optlen);
 		break;
 #ifdef CONFIG_TCP_AO
@@ -4293,6 +4297,8 @@ int do_tcp_getsockopt(struct sock *sk, int level,
 	}
 #endif
 	case TCP_AO_REPAIR:
+		if (sk->sk_state == TCP_LISTEN)
+			return -ENOSTR;
 		return tcp_ao_get_repair(sk, optval, optlen);
 	case TCP_AO_GET_KEYS:
 	case TCP_AO_INFO: {
-- 
2.42.0
Re: [PATCH 3/7] net/tcp: Limit TCP_AO_REPAIR to non-listen sockets
Posted by Eric Dumazet 2 years ago
On Tue, Nov 21, 2023 at 3:01 AM Dmitry Safonov <dima@arista.com> wrote:
>
> Listen socket is not an established TCP connection, so
> setsockopt(TCP_AO_REPAIR) doesn't have any impact.
>
> Restrict this uAPI for listen sockets.
>
> Fixes: faadfaba5e01 ("net/tcp: Add TCP_AO_REPAIR")
> Signed-off-by: Dmitry Safonov <dima@arista.com>
> ---
>  net/ipv4/tcp.c | 6 ++++++
>  1 file changed, 6 insertions(+)
>
> diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
> index 53bcc17c91e4..2836515ab3d7 100644
> --- a/net/ipv4/tcp.c
> +++ b/net/ipv4/tcp.c
> @@ -3594,6 +3594,10 @@ int do_tcp_setsockopt(struct sock *sk, int level, int optname,
>                 break;
>
>         case TCP_AO_REPAIR:
> +               if (sk->sk_state == TCP_LISTEN) {
> +                       err = -ENOSTR;

ENOSTR is not used a single time in linux.

I suggest you use tcp_can_repair_sock() helper (and return -EPERM as
other TCP_REPAIR options)

> +                       break;
> +               }
>                 err = tcp_ao_set_repair(sk, optval, optlen);
>                 break;
>  #ifdef CONFIG_TCP_AO
> @@ -4293,6 +4297,8 @@ int do_tcp_getsockopt(struct sock *sk, int level,
>         }
>  #endif
>         case TCP_AO_REPAIR:
> +               if (sk->sk_state == TCP_LISTEN)
> +                       return -ENOSTR;
>                 return tcp_ao_get_repair(sk, optval, optlen);
>         case TCP_AO_GET_KEYS:
>         case TCP_AO_INFO: {
> --
> 2.42.0
>
Re: [PATCH 3/7] net/tcp: Limit TCP_AO_REPAIR to non-listen sockets
Posted by Dmitry Safonov 2 years ago
On 11/21/23 08:21, Eric Dumazet wrote:
> On Tue, Nov 21, 2023 at 3:01 AM Dmitry Safonov <dima@arista.com> wrote:
>>
>> Listen socket is not an established TCP connection, so
>> setsockopt(TCP_AO_REPAIR) doesn't have any impact.
>>
>> Restrict this uAPI for listen sockets.
>>
>> Fixes: faadfaba5e01 ("net/tcp: Add TCP_AO_REPAIR")
>> Signed-off-by: Dmitry Safonov <dima@arista.com>
>> ---
>>  net/ipv4/tcp.c | 6 ++++++
>>  1 file changed, 6 insertions(+)
>>
>> diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
>> index 53bcc17c91e4..2836515ab3d7 100644
>> --- a/net/ipv4/tcp.c
>> +++ b/net/ipv4/tcp.c
>> @@ -3594,6 +3594,10 @@ int do_tcp_setsockopt(struct sock *sk, int level, int optname,
>>                 break;
>>
>>         case TCP_AO_REPAIR:
>> +               if (sk->sk_state == TCP_LISTEN) {
>> +                       err = -ENOSTR;
> 
> ENOSTR is not used a single time in linux.
> 
> I suggest you use tcp_can_repair_sock() helper (and return -EPERM as
> other TCP_REPAIR options)

Sounds good to me. Unsure why I didn't use tcp_can_repair_sock() in the
first place. Will do in v2.

> 
>> +                       break;
>> +               }
>>                 err = tcp_ao_set_repair(sk, optval, optlen);
>>                 break;
>>  #ifdef CONFIG_TCP_AO
>> @@ -4293,6 +4297,8 @@ int do_tcp_getsockopt(struct sock *sk, int level,
>>         }
>>  #endif
>>         case TCP_AO_REPAIR:
>> +               if (sk->sk_state == TCP_LISTEN)
>> +                       return -ENOSTR;
>>                 return tcp_ao_get_repair(sk, optval, optlen);
>>         case TCP_AO_GET_KEYS:
>>         case TCP_AO_INFO: {
>> --
>> 2.42.0
>>

Thanks,
             Dmitry