Skip to content

Commit c0d3508

Browse files
committed
Merge tag 'landlock-6.14-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/mic/linux
Pull landlock fixes from Mickaël Salaün: "Fixes to TCP socket identification, documentation, and tests" * tag 'landlock-6.14-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/mic/linux: selftests/landlock: Add binaries to .gitignore selftests/landlock: Test that MPTCP actions are not restricted selftests/landlock: Test TCP accesses with protocol=IPPROTO_TCP landlock: Fix non-TCP sockets restriction landlock: Minor typo and grammar fixes in IPC scoping documentation landlock: Fix grammar error selftests/landlock: Enable the new CONFIG_AF_UNIX_OOB
2 parents d62fdaf + 78332fd commit c0d3508

File tree

8 files changed

+127
-22
lines changed

8 files changed

+127
-22
lines changed

Documentation/userspace-api/landlock.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Landlock: unprivileged access control
88
=====================================
99

1010
:Author: Mickaël Salaün
11-
:Date: October 2024
11+
:Date: January 2025
1212

1313
The goal of Landlock is to enable restriction of ambient rights (e.g. global
1414
filesystem or network access) for a set of processes. Because Landlock
@@ -329,11 +329,11 @@ non-sandboxed process, we can specify this restriction with
329329
A sandboxed process can connect to a non-sandboxed process when its domain is
330330
not scoped. If a process's domain is scoped, it can only connect to sockets
331331
created by processes in the same scope.
332-
Moreover, If a process is scoped to send signal to a non-scoped process, it can
332+
Moreover, if a process is scoped to send signal to a non-scoped process, it can
333333
only send signals to processes in the same scope.
334334

335335
A connected datagram socket behaves like a stream socket when its domain is
336-
scoped, meaning if the domain is scoped after the socket is connected , it can
336+
scoped, meaning if the domain is scoped after the socket is connected, it can
337337
still :manpage:`send(2)` data just like a stream socket. However, in the same
338338
scenario, a non-connected datagram socket cannot send data (with
339339
:manpage:`sendto(2)`) outside its scope.

include/uapi/linux/landlock.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,9 @@ struct landlock_net_port_attr {
268268
* ~~~~~~~~~~~~~~~~
269269
*
270270
* These flags enable to restrict a sandboxed process to a set of network
271-
* actions. This is supported since the Landlock ABI version 4.
271+
* actions.
272+
*
273+
* This is supported since Landlock ABI version 4.
272274
*
273275
* The following access rights apply to TCP port numbers:
274276
*
@@ -291,11 +293,13 @@ struct landlock_net_port_attr {
291293
* Setting a flag for a ruleset will isolate the Landlock domain to forbid
292294
* connections to resources outside the domain.
293295
*
296+
* This is supported since Landlock ABI version 6.
297+
*
294298
* Scopes:
295299
*
296300
* - %LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET: Restrict a sandboxed process from
297301
* connecting to an abstract UNIX socket created by a process outside the
298-
* related Landlock domain (e.g. a parent domain or a non-sandboxed process).
302+
* related Landlock domain (e.g., a parent domain or a non-sandboxed process).
299303
* - %LANDLOCK_SCOPE_SIGNAL: Restrict a sandboxed process from sending a signal
300304
* to another process outside the domain.
301305
*/

security/landlock/net.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,7 @@ static int current_check_access_socket(struct socket *const sock,
6363
if (WARN_ON_ONCE(dom->num_layers < 1))
6464
return -EACCES;
6565

66-
/* Checks if it's a (potential) TCP socket. */
67-
if (sock->type != SOCK_STREAM)
66+
if (!sk_is_tcp(sock->sk))
6867
return 0;
6968

7069
/* Checks for minimal header length to safely read sa_family. */

security/landlock/ruleset.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ create_rule(const struct landlock_id id,
124124
return ERR_PTR(-ENOMEM);
125125
RB_CLEAR_NODE(&new_rule->node);
126126
if (is_object_pointer(id.type)) {
127-
/* This should be catched by insert_rule(). */
127+
/* This should have been caught by insert_rule(). */
128128
WARN_ON_ONCE(!id.key.object);
129129
landlock_get_object(id.key.object);
130130
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
/*_test
2+
/sandbox-and-launch
23
/true
4+
/wait-pipe

tools/testing/selftests/landlock/common.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ enforce_ruleset(struct __test_metadata *const _metadata, const int ruleset_fd)
207207
struct protocol_variant {
208208
int domain;
209209
int type;
210+
int protocol;
210211
};
211212

212213
struct service_fixture {

tools/testing/selftests/landlock/config

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1+
CONFIG_AF_UNIX_OOB=y
12
CONFIG_CGROUPS=y
23
CONFIG_CGROUP_SCHED=y
34
CONFIG_INET=y
45
CONFIG_IPV6=y
56
CONFIG_KEYS=y
7+
CONFIG_MPTCP=y
8+
CONFIG_MPTCP_IPV6=y
69
CONFIG_NET=y
710
CONFIG_NET_NS=y
811
CONFIG_OVERLAY_FS=y

tools/testing/selftests/landlock/net_test.c

Lines changed: 110 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -85,18 +85,18 @@ static void setup_loopback(struct __test_metadata *const _metadata)
8585
clear_ambient_cap(_metadata, CAP_NET_ADMIN);
8686
}
8787

88+
static bool prot_is_tcp(const struct protocol_variant *const prot)
89+
{
90+
return (prot->domain == AF_INET || prot->domain == AF_INET6) &&
91+
prot->type == SOCK_STREAM &&
92+
(prot->protocol == IPPROTO_TCP || prot->protocol == IPPROTO_IP);
93+
}
94+
8895
static bool is_restricted(const struct protocol_variant *const prot,
8996
const enum sandbox_type sandbox)
9097
{
91-
switch (prot->domain) {
92-
case AF_INET:
93-
case AF_INET6:
94-
switch (prot->type) {
95-
case SOCK_STREAM:
96-
return sandbox == TCP_SANDBOX;
97-
}
98-
break;
99-
}
98+
if (sandbox == TCP_SANDBOX)
99+
return prot_is_tcp(prot);
100100
return false;
101101
}
102102

@@ -105,7 +105,7 @@ static int socket_variant(const struct service_fixture *const srv)
105105
int ret;
106106

107107
ret = socket(srv->protocol.domain, srv->protocol.type | SOCK_CLOEXEC,
108-
0);
108+
srv->protocol.protocol);
109109
if (ret < 0)
110110
return -errno;
111111
return ret;
@@ -290,22 +290,70 @@ FIXTURE_TEARDOWN(protocol)
290290
}
291291

292292
/* clang-format off */
293-
FIXTURE_VARIANT_ADD(protocol, no_sandbox_with_ipv4_tcp) {
293+
FIXTURE_VARIANT_ADD(protocol, no_sandbox_with_ipv4_tcp1) {
294294
/* clang-format on */
295295
.sandbox = NO_SANDBOX,
296296
.prot = {
297297
.domain = AF_INET,
298298
.type = SOCK_STREAM,
299+
/* IPPROTO_IP == 0 */
300+
.protocol = IPPROTO_IP,
299301
},
300302
};
301303

302304
/* clang-format off */
303-
FIXTURE_VARIANT_ADD(protocol, no_sandbox_with_ipv6_tcp) {
305+
FIXTURE_VARIANT_ADD(protocol, no_sandbox_with_ipv4_tcp2) {
306+
/* clang-format on */
307+
.sandbox = NO_SANDBOX,
308+
.prot = {
309+
.domain = AF_INET,
310+
.type = SOCK_STREAM,
311+
.protocol = IPPROTO_TCP,
312+
},
313+
};
314+
315+
/* clang-format off */
316+
FIXTURE_VARIANT_ADD(protocol, no_sandbox_with_ipv4_mptcp) {
317+
/* clang-format on */
318+
.sandbox = NO_SANDBOX,
319+
.prot = {
320+
.domain = AF_INET,
321+
.type = SOCK_STREAM,
322+
.protocol = IPPROTO_MPTCP,
323+
},
324+
};
325+
326+
/* clang-format off */
327+
FIXTURE_VARIANT_ADD(protocol, no_sandbox_with_ipv6_tcp1) {
328+
/* clang-format on */
329+
.sandbox = NO_SANDBOX,
330+
.prot = {
331+
.domain = AF_INET6,
332+
.type = SOCK_STREAM,
333+
/* IPPROTO_IP == 0 */
334+
.protocol = IPPROTO_IP,
335+
},
336+
};
337+
338+
/* clang-format off */
339+
FIXTURE_VARIANT_ADD(protocol, no_sandbox_with_ipv6_tcp2) {
304340
/* clang-format on */
305341
.sandbox = NO_SANDBOX,
306342
.prot = {
307343
.domain = AF_INET6,
308344
.type = SOCK_STREAM,
345+
.protocol = IPPROTO_TCP,
346+
},
347+
};
348+
349+
/* clang-format off */
350+
FIXTURE_VARIANT_ADD(protocol, no_sandbox_with_ipv6_mptcp) {
351+
/* clang-format on */
352+
.sandbox = NO_SANDBOX,
353+
.prot = {
354+
.domain = AF_INET6,
355+
.type = SOCK_STREAM,
356+
.protocol = IPPROTO_MPTCP,
309357
},
310358
};
311359

@@ -350,22 +398,70 @@ FIXTURE_VARIANT_ADD(protocol, no_sandbox_with_unix_datagram) {
350398
};
351399

352400
/* clang-format off */
353-
FIXTURE_VARIANT_ADD(protocol, tcp_sandbox_with_ipv4_tcp) {
401+
FIXTURE_VARIANT_ADD(protocol, tcp_sandbox_with_ipv4_tcp1) {
402+
/* clang-format on */
403+
.sandbox = TCP_SANDBOX,
404+
.prot = {
405+
.domain = AF_INET,
406+
.type = SOCK_STREAM,
407+
/* IPPROTO_IP == 0 */
408+
.protocol = IPPROTO_IP,
409+
},
410+
};
411+
412+
/* clang-format off */
413+
FIXTURE_VARIANT_ADD(protocol, tcp_sandbox_with_ipv4_tcp2) {
414+
/* clang-format on */
415+
.sandbox = TCP_SANDBOX,
416+
.prot = {
417+
.domain = AF_INET,
418+
.type = SOCK_STREAM,
419+
.protocol = IPPROTO_TCP,
420+
},
421+
};
422+
423+
/* clang-format off */
424+
FIXTURE_VARIANT_ADD(protocol, tcp_sandbox_with_ipv4_mptcp) {
354425
/* clang-format on */
355426
.sandbox = TCP_SANDBOX,
356427
.prot = {
357428
.domain = AF_INET,
358429
.type = SOCK_STREAM,
430+
.protocol = IPPROTO_MPTCP,
431+
},
432+
};
433+
434+
/* clang-format off */
435+
FIXTURE_VARIANT_ADD(protocol, tcp_sandbox_with_ipv6_tcp1) {
436+
/* clang-format on */
437+
.sandbox = TCP_SANDBOX,
438+
.prot = {
439+
.domain = AF_INET6,
440+
.type = SOCK_STREAM,
441+
/* IPPROTO_IP == 0 */
442+
.protocol = IPPROTO_IP,
443+
},
444+
};
445+
446+
/* clang-format off */
447+
FIXTURE_VARIANT_ADD(protocol, tcp_sandbox_with_ipv6_tcp2) {
448+
/* clang-format on */
449+
.sandbox = TCP_SANDBOX,
450+
.prot = {
451+
.domain = AF_INET6,
452+
.type = SOCK_STREAM,
453+
.protocol = IPPROTO_TCP,
359454
},
360455
};
361456

362457
/* clang-format off */
363-
FIXTURE_VARIANT_ADD(protocol, tcp_sandbox_with_ipv6_tcp) {
458+
FIXTURE_VARIANT_ADD(protocol, tcp_sandbox_with_ipv6_mptcp) {
364459
/* clang-format on */
365460
.sandbox = TCP_SANDBOX,
366461
.prot = {
367462
.domain = AF_INET6,
368463
.type = SOCK_STREAM,
464+
.protocol = IPPROTO_MPTCP,
369465
},
370466
};
371467

0 commit comments

Comments
 (0)