[RFC PATCH v1 1/2] landlock: Fix non-TCP sockets restriction
Mikhail Ivanov
ivanov.mikhail1 at huawei-partners.com
Fri Oct 4 18:16:56 UTC 2024
On 10/4/2024 1:13 PM, Mickaël Salaün wrote:
> On Fri, Oct 04, 2024 at 12:30:02AM +0300, Mikhail Ivanov wrote:
>> On 10/3/2024 8:45 PM, Mickaël Salaün wrote:
>>> Please also add Matthieu in Cc for the network patch series.
>>>
>>> On Thu, Oct 03, 2024 at 10:39:31PM +0800, Mikhail Ivanov wrote:
>>>> Do not check TCP access right if socket protocol is not IPPROTO_TCP.
>>>> LANDLOCK_ACCESS_NET_BIND_TCP and LANDLOCK_ACCESS_NET_CONNECT_TCP
>>>> should not restrict bind(2) and connect(2) for non-TCP protocols
>>>> (SCTP, MPTCP, SMC).
>>>>
>>>> Closes: https://github.com/landlock-lsm/linux/issues/40
>>>> Fixes: fff69fb03dde ("landlock: Support network rules with TCP bind and connect")
>>>> Signed-off-by: Mikhail Ivanov <ivanov.mikhail1 at huawei-partners.com>
>>>> ---
>>>> security/landlock/net.c | 2 +-
>>>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>>>
>>>> diff --git a/security/landlock/net.c b/security/landlock/net.c
>>>> index bc3d943a7118..6f59dd98bb13 100644
>>>> --- a/security/landlock/net.c
>>>> +++ b/security/landlock/net.c
>>>> @@ -68,7 +68,7 @@ static int current_check_access_socket(struct socket *const sock,
>>>> return -EACCES;
>>>> /* Checks if it's a (potential) TCP socket. */
>>>
>>> We can extend this comment to explain that we don't use sk_is_tcp()
>>> because we need to handle the AF_UNSPEC case.
>>
>> Indeed, I'll do this.
I've noticed that we still should check sk->sk_family = AF_INET{,6}
here (so sk_is_tcp() is suitable). AF_UNSPEC can be only related to
addresses and we should not provide any checks (for address) if socket
is unrestrictable (i.e. it's not TCP). It's not useful and might lead to
error incosistency for non-TCP sockets.
Btw, I suppose we can improve error consistency by bringing more checks
from INET/TCP stack. For example it may be useful to return EISCONN
instead of EACCES while connect(2) is called on a connected socket.
This should be done really carefully and only for some useful cases.
Anyway it's not related to the current patch (since it's not a bug).
>>
>>>
>>>> - if (sock->type != SOCK_STREAM)
>>>> + if (sock->type != SOCK_STREAM || sock->sk->sk_protocol != IPPROTO_TCP)
>>>
>>> I think we should check sock->sk->sk_type instead of sock->type (even if
>>> it should be the same). To make it simpler, we should only use sk in
>>> current_check_access_socket():
>>> struct sock *sk = sock->sk;
>>
>> Agreed.
>>
>>>
>>> Could you please also do s/__sk_common\.skc_/sk_/g ?
>>
>> Ofc
>>
>> Btw, there is probably incorrect read of skc_family in this function
>> [1]. I'll add READ_ONCE for sk->sk_family.
>>
>> [1] https://lore.kernel.org/all/20240202095404.183274-1-edumazet@google.com/
>
> I think it should not be a bug with the current code (IPv6 -> IPV4, and
> socket vs. sock) but we should indeed use READ_ONCE() (and add this link
> to the commit message).
ok
>
>>
>>>
>>>> return 0;
>>>> /* Checks for minimal header length to safely read sa_family. */
>>>> --
>>>> 2.34.1
>>>>
>>>>
>>
More information about the Linux-security-module-archive
mailing list