landlock.7: Explain best-effort fallback in example
v6 cover landlock.7: Explain best-effort fallback in example
Hello!
Same patch as before, but the first two commits are already merged. :) The only addition is a little remark in the example code to point out that these values are hardcoded for brevity.
In the long run I would like to put these constants in a kernel uapi header. In the meanwhile, I think it's good to point it out explicitly in the man page that this is just done like that to keep the example short.
–Günther
Günther Noack (1):
landlock.7: Explain the best-effort fallback mechanism in the example
man7/landlock.7 | 70 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 66 insertions(+), 4 deletions(-)
base-commit: 6e502b913302d5ba4b70a2f3e6b3ff38748d2d0f
Signature · 1 line
2.40.0
PATCH v6 1/1 landlock.7: Explain the best-effort fallback mechanism in the example
--- man7/landlock.7 | 70 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 66 insertions(+), 4 deletions(-)
man7/landlock.7 +66 -4
@@ -394,11 +394,14 @@ accessible through these system call families: Future Landlock evolutions will enable to restrict them. .SH EXAMPLES We first need to create the ruleset that will contain our rules. +.PP For this example, the ruleset will contain rules that only allow read actions, but write actions will be denied. The ruleset then needs to handle both of these kinds of actions. -See below for the description of filesystem actions. +See the +.B DESCRIPTION +section for the description of filesystem actions. .PP .in +4n .EX
@@ -421,7 +424,62 @@ attr.handled_access_fs = LANDLOCK_ACCESS_FS_MAKE_SYM | LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_TRUNCATE; +.EE +.in +.PP +To be compatible with older Linux versions, +we detect the available Landlock ABI version, +and only use the available subset of access rights: +.PP +.in +4n +.EX +/* + * Table of available file system access rights by ABI version, + * numbers hardcoded to keep the example short. + */ +__u64 landlock_fs_access_rights[] = { + (1ULL << 13) \- 1, /* ABI v1 */ + (1ULL << 14) \- 1, /* ABI v2: add "refer" */ + (1ULL << 15) \- 1, /* ABI v3: add "truncate" */ +}; + +int abi = landlock_create_ruleset(NULL, 0, + LANDLOCK_CREATE_RULESET_VERSION); +if (abi <= 0) { + perror("Giving up \- No Landlock support"); + exit(EXIT_FAILURE); +} +if (abi > 3) + abi = 3; +/* Only use the available rights in the ruleset. */ +attr.handled_access_fs &= landlock_fs_access_rights[abi \- 1]; +.EE +.in +.PP +The available access rights for each ABI version are listed in the +.B VERSIONS +section. +.PP +If our program needed to create hard links +or rename files between different directories +.RB ( LANDLOCK_ACCESS_FS_REFER ), +we would require the following change to the backwards compatibility logic: +Directory reparenting is not possible +in a process restricted with Landlock ABI version 1. +Therefore, +if the program needed to do file reparenting, +and if only Landlock ABI version 1 was available, +we could not restrict the process. +.PP +Now that the ruleset attributes are determined, +we create the Landlock ruleset +and acquire a file descriptor as a handle to it, +using +.BR landlock_create_ruleset (2): +.PP +.in +4n +.EX ruleset_fd = landlock_create_ruleset(&attr, sizeof(attr), 0); if (ruleset_fd == \-1) { perror("Failed to create a ruleset");
@@ -430,9 +488,13 @@ if (ruleset_fd == \-1) { .EE .in .PP -We can now add a new rule to this ruleset thanks to the returned file -descriptor referring to this ruleset. -The rule will only allow reading the file hierarchy +We can now add a new rule to the ruleset through the ruleset's file descriptor. +The requested access rights must be a subset of the access rights +which were specified in +.I attr.handled_access_fs +at ruleset creation time. +.PP +In this example, the rule will only allow reading the file hierarchy .IR /usr . Without another rule, write actions would then be denied by the ruleset. To add
Signature · 1 line
2.40.0
Re: [PATCH v6 1/1] landlock.7: Explain the best-effort fallback mechanism in the example
Hi Günther,
Quoted 42 lines · Günther Noack
Signed-off-by Günther Noack <[email protected]>--- man7/landlock.7 | 70 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 66 insertions(+), 4 deletions(-)man7/landlock.7 +17
-1@@ -394,11 +394,14 @@ accessible through these system call families: Future Landlock evolutions will enable to restrict them. .SH EXAMPLES We first need to create the ruleset that will contain our rules. +.PP For this example, the ruleset will contain rules that only allow read actions, but write actions will be denied. The ruleset then needs to handle both of these kinds of actions. -See below for the description of filesystem actions. +See the +.B DESCRIPTION +section for the description of filesystem actions. .PP .in +4n .EX@@ -421,7 +424,62 @@ attr.handled_access_fs = LANDLOCK_ACCESS_FS_MAKE_SYM | LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_TRUNCATE; +.EE +.in +.PP +To be compatible with older Linux versions, +we detect the available Landlock ABI version, +and only use the available subset of access rights: +.PP +.in +4n +.EX +/* + * Table of available file system access rights by ABI version, + * numbers hardcoded to keep the example short. + */
man7/landlock.7 attr.handled_access_fs = · line 449
Quoted 10 lines
man7/landlock.7 +10
-0+__u64 landlock_fs_access_rights[] = { + (1ULL << 13) \- 1, /* ABI v1 */ + (1ULL << 14) \- 1, /* ABI v2: add "refer" */ + (1ULL << 15) \- 1, /* ABI v3: add "truncate" */ +}; + +int abi = landlock_create_ruleset(NULL, 0, + LANDLOCK_CREATE_RULESET_VERSION); +if (abi <= 0) { + perror("Giving up \- No Landlock support");
Using perror(3) will already print "Operation not supported", since errno is ENOTSUP. Maybe this string is redundant? How about the following?
perror("landlock_create_ruleset"); // EOPNOTSUPP
BTW, now I checked that while in Linux ENOTSUP and EOPNOTSUPP are equivalent, in POSIX the latter has a connotation that it's about sockets. Should we document ENOTSUP in landlock_create_ruleset(2) instead of EOPNOTSUPP?
man7/landlock.7 attr.handled_access_fs = · line 453
Quoted 4 lines
man7/landlock.7 +4
-0+ exit(EXIT_FAILURE); +} +if (abi > 3) + abi = 3;
This makes the example a line shorter (see MIN(3)):
abi = MIN(abi, 3);
Cheers,
Alex
Quoted 49 lines
man7/landlock.7 +35
-3+/* Only use the available rights in the ruleset. */ +attr.handled_access_fs &= landlock_fs_access_rights[abi \- 1]; +.EE +.in +.PP +The available access rights for each ABI version are listed in the +.B VERSIONS +section. +.PP +If our program needed to create hard links +or rename files between different directories +.RB ( LANDLOCK_ACCESS_FS_REFER ), +we would require the following change to the backwards compatibility logic: +Directory reparenting is not possible +in a process restricted with Landlock ABI version 1. +Therefore, +if the program needed to do file reparenting, +and if only Landlock ABI version 1 was available, +we could not restrict the process. +.PP +Now that the ruleset attributes are determined, +we create the Landlock ruleset +and acquire a file descriptor as a handle to it, +using +.BR landlock_create_ruleset (2): +.PP +.in +4n +.EX ruleset_fd = landlock_create_ruleset(&attr, sizeof(attr), 0); if (ruleset_fd == \-1) { perror("Failed to create a ruleset");@@ -430,9 +488,13 @@ if (ruleset_fd == \-1) { .EE .in .PP -We can now add a new rule to this ruleset thanks to the returned file -descriptor referring to this ruleset. -The rule will only allow reading the file hierarchy +We can now add a new rule to the ruleset through the ruleset's file descriptor. +The requested access rights must be a subset of the access rights +which were specified in +.I attr.handled_access_fs +at ruleset creation time. +.PP +In this example, the rule will only allow reading the file hierarchy .IR /usr . Without another rule, write actions would then be denied by the ruleset. To add
Signature · 2 lines
<http://www.alejandro-colomar.es/> GPG key fingerprint: A9348594CE31283A826FBDD8D57633D441E25BB5
Re: [PATCH v6 1/1] landlock.7: Explain the best-effort fallback mechanism in the example
Hello Alejandro!
Quoted 30 lines · Alejandro Colomar
Quoted 14 lines · Günther Noack
Signed-off-by Günther Noack <[email protected]>--- man7/landlock.7 | 70 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 66 insertions(+), 4 deletions(-)man7/landlock.7 +4
-0+/* + * Table of available file system access rights by ABI version, + * numbers hardcoded to keep the example short. + */man7/landlock.7 attr.handled_access_fs = · line 449
Quoted 10 lines
man7/landlock.7 +10
-0+__u64 landlock_fs_access_rights[] = { + (1ULL << 13) \- 1, /* ABI v1 */ + (1ULL << 14) \- 1, /* ABI v2: add "refer" */ + (1ULL << 15) \- 1, /* ABI v3: add "truncate" */ +}; + +int abi = landlock_create_ruleset(NULL, 0, + LANDLOCK_CREATE_RULESET_VERSION); +if (abi <= 0) { + perror("Giving up \- No Landlock support");Using perror(3) will already print "Operation not supported", since errno is ENOTSUP. Maybe this string is redundant? How about the following?
Quoted 1 line
perror("landlock_create_ruleset"); // EOPNOTSUPP
The fallback code assumes that we don't know the kernel that we run on, so in practice we also have to handle ENOSYS.
See https://docs.kernel.org/userspace-api/landlock.html#landlock-abi-versions
I'd suggest to just make it more explicit here that it can be two different error codes:
if (abi <= 0) {
/* ENOTSUP or ENOSYS */
perror("Giving up \- No Landlock support");
}Does that sound reasonable?
Quoted 4 lines
BTW, now I checked that while in Linux ENOTSUP and EOPNOTSUPP are equivalent, in POSIX the latter has a connotation that it's about sockets. Should we document ENOTSUP in
landlock_create_ruleset(2)instead of EOPNOTSUPP?
EOPNOTSUP is also used in Landlock's kernel documentation, we'd maybe have to update it there as well.
I'll have a look at what is more common.
Quoted 8 lines
man7/landlock.7 attr.handled_access_fs = · line 453
Quoted 4 lines
man7/landlock.7 +4
-0+ exit(EXIT_FAILURE); +} +if (abi > 3) + abi = 3;This makes the example a line shorter (see MIN(3)):
abi =
MIN(abi, 3);
Thanks, good point! I'll add that.
–Günther
Re: [PATCH v6 1/1] landlock.7: Explain the best-effort fallback mechanism in the example
Hello Günther!
Quoted 19 lines · Günther Noack
Hello Alejandro!
Quoted 8 lines
man7/landlock.7 attr.handled_access_fs = · line 449
Quoted 2 lines
man7/landlock.7 +2
-0+if (abi <= 0) { + perror("Giving up \- No Landlock support");Using perror(3) will already print "Operation not supported", since errno is ENOTSUP. Maybe this string is redundant? How about the following?
perror("landlock_create_ruleset"); // EOPNOTSUPPThe fallback code assumes that we don't know the kernel that we run on, so in practice we also have to handle ENOSYS.
See https://docs.kernel.org/userspace-api/landlock.html#landlock-abi-versions
I'd suggest to just make it more explicit here that it can be two different error codes:
Quoted 6 lines
if (abi <= 0) { /* ENOTSUP or ENOSYS */ perror("Giving up \- No Landlock support"); }Does that sound reasonable?
Sounds reasonable (with a call to exit(3) too).
BTW, now I see ENOSYS is not documented in syscall(2) (there's actually no ERRORS section there). Should we add it?
Quoted 10 lines
Quoted 6 lines
BTW, now I checked that while in Linux ENOTSUP and EOPNOTSUPP are equivalent, in POSIX the latter has a connotation that it's about sockets. Should we document ENOTSUP in
landlock_create_ruleset(2)instead of EOPNOTSUPP?EOPNOTSUP is also used in Landlock's kernel documentation, we'd maybe have to update it there as well.
I'll have a look at what is more common.
Thanks. In the man pages I see both often, so maybe we need to fix consistency there too.
Cheers,
Alex
Signature · 2 lines
<http://www.alejandro-colomar.es/> GPG key fingerprint: A9348594CE31283A826FBDD8D57633D441E25BB5
Re: [PATCH v6 1/1] landlock.7: Explain the best-effort fallback mechanism in the example
Quoted 27 lines · Alejandro Colomar
Hello Günther!
Quoted 24 lines · Günther Noack
Hello Alejandro!
Quoted 8 lines
man7/landlock.7 attr.handled_access_fs = · line 449
Quoted 2 lines
man7/landlock.7 +2
-0+if (abi <= 0) { + perror("Giving up \- No Landlock support");Using perror(3) will already print "Operation not supported", since errno is ENOTSUP. Maybe this string is redundant? How about the following?
perror("landlock_create_ruleset"); // EOPNOTSUPPThe fallback code assumes that we don't know the kernel that we run on, so in practice we also have to handle ENOSYS.
See https://docs.kernel.org/userspace-api/landlock.html#landlock-abi-versions
I'd suggest to just make it more explicit here that it can be two different error codes:
if (abi <= 0) { /* ENOTSUP or ENOSYS */ perror("Giving up \- No Landlock support"); }
Quoted 11 lines
Quoted 1 line
Does that sound reasonable?
Sounds reasonable (with a call to exit(3) too).
BTW, now I see ENOSYS is not documented in syscall(2) (there's actually no ERRORS section there). Should we add it?
Quoted 4 lines
Quoted 4 lines
BTW, now I checked that while in Linux ENOTSUP and EOPNOTSUPP are equivalent, in POSIX the latter has a connotation that it's about
For Linux:
#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
#define ENOTSUPP 524 /* Operation is not supported */
EOPNOTSUPP is not only used for network error, but to identify generic unsupported operations, while ENOTSUPP was initially dedicated to NFS error (but now also slipped to other areas)
Quoted 8 lines
Quoted 5 lines
Quoted 2 lines
sockets. Should we document ENOTSUP in
landlock_create_ruleset(2)instead of EOPNOTSUPP? >>EOPNOTSUP is also used in Landlock's kernel documentation, we'd maybe have to update it there as well.
I'll have a look at what is more common.Thanks. In the man pages I see both often, so maybe we need to fix consistency there too.
No, ENOTSUP*P* is not used by Landlock.
Re: [PATCH v6 1/1] landlock.7: Explain the best-effort fallback mechanism in the example
Hi Mickaël,
Quoted 6 lines · Mickaël Salaün
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
BTW, now I checked that while in Linux ENOTSUP and EOPNOTSUPP are equivalent, in POSIX the latter has a connotation that it's about
For Linux:
#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
#define ENOTSUPP 524 /* Operation is not supported */
$ errno 95 EOPNOTSUPP 95 Operation not supported $ errno 524 $ echo $? 1
$ grepc -k ENOTSUP /usr/include/ /usr/include/x86_64-linux-gnu/bits/errno.h:30:# define ENOTSUP EOPNOTSUPP $ grepc -k ENOTSUPP /usr/include/ $ grepc -k EOPNOTSUPP /usr/include/ /usr/include/asm-generic/errno.h:78:#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
Is ENOTSUPP a kernel thing? User space we doesn't seem to agree with that :). I'm on Debian Sid.
Indeed, it seems a kernel thing:
$ man -Kaw ENOTSUPP /usr/local/man/man1/checkpatch.1
That page is one I wrote extracting info from checkpatch.rst. It seems checkpatch.pl warns about use of ENOTSUPP.
Quoted 7 lines
EOPNOTSUPP is not only used for network error, but to identify generic unsupported operations, while ENOTSUPP was initially dedicated to NFS error (but now also slipped to other areas)
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
sockets. Should we document ENOTSUP in
landlock_create_ruleset(2)instead of EOPNOTSUPP? >>
Quoted 8 lines
Quoted 6 lines
Quoted 3 lines
EOPNOTSUP is also used in Landlock's kernel documentation, we'd maybe have to update it there as well.
I'll have a look at what is more common.Thanks. In the man pages I see both often, so maybe we need to fix consistency there too.
No, ENOTSUP*P* is not used by Landlock.
But should it? I mean ENOTSUP, not ENOTSUPP.
Cheers,
Alex
Signature · 2 lines
<http://www.alejandro-colomar.es/> GPG key fingerprint: A9348594CE31283A826FBDD8D57633D441E25BB5
Re: [PATCH v6 1/1] landlock.7: Explain the best-effort fallback mechanism in the example
Quoted 24 lines · Alejandro Colomar
Hi Mickaël,
Quoted 6 lines · Mickaël Salaün
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
BTW, now I checked that while in Linux ENOTSUP and EOPNOTSUPP are equivalent, in POSIX the latter has a connotation that it's about
For Linux:
#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
#define ENOTSUPP 524 /* Operation is not supported */$ errno 95 EOPNOTSUPP 95 Operation not supported $ errno 524 $ echo $? 1$ grepc -k ENOTSUP /usr/include/ /usr/include/x86_64-linux-gnu/bits/errno.h:30:# define ENOTSUP EOPNOTSUPP $ grepc -k ENOTSUPP /usr/include/ $ grepc -k EOPNOTSUPP /usr/include/ /usr/include/asm-generic/errno.h:78:#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
Quoted 2 lines
Is ENOTSUPP a kernel thing? User space we doesn't seem to agree with that :). I'm on Debian Sid.
Indeed, ENOTSUPP is a kernel error type, only EOPNOTSUPP should be used to return error to user space. ENOTSUPP is not used by the kernel, it is only defined by the libc:
# ifndef ENOTSUP # define ENOTSUP EOPNOTSUPP # endif
Quoted 23 lines
Indeed, it seems a kernel thing:
$ man -Kaw ENOTSUPP /usr/local/man/man1/checkpatch.1That page is one I wrote extracting info from
checkpatch.rst. It seems checkpatch.pl warns about use of ENOTSUPP.Quoted 11 lines
EOPNOTSUPP is not only used for network error, but to identify generic unsupported operations, while ENOTSUPP was initially dedicated to NFS error (but now also slipped to other areas)
Quoted 6 lines
Quoted 5 lines
Quoted 2 lines
sockets. Should we document ENOTSUP in
landlock_create_ruleset(2)instead of EOPNOTSUPP? >>EOPNOTSUP is also used in Landlock's kernel documentation, we'd maybe have to update it there as well.
I'll have a look at what is more common.
Quoted 6 lines
Quoted 4 lines
Quoted 2 lines
Thanks. In the man pages I see both often, so maybe we need to fix consistency there too.
No, ENOTSUP*P* is not used by Landlock.
But should it? I mean ENOTSUP, not ENOTSUPP.
ENOTSUP doesn't exist in the kernel source, so it is legitimate that Landlock and any other kernel interfaces use EOPNOTSUPP. ENOTSUP should then not replace EOPNOTSUPP for Landlock nor any other kernel interfaces.
Re: [PATCH v6 1/1] landlock.7: Explain the best-effort fallback mechanism in the example
Hi Mickaël,
Quoted 9 lines · Mickaël Salaün
Indeed, ENOTSUPP is a kernel error type, only EOPNOTSUPP should be used to return error to user space. ENOTSUPP is not used by the kernel, it is only defined by the libc:
# ifndef ENOTSUP # define ENOTSUP EOPNOTSUPP # endif
[...]
Quoted 4 lines
ENOTSUP doesn't exist in the kernel source, so it is legitimate that Landlock and any other kernel interfaces use EOPNOTSUPP. ENOTSUP should then not replace EOPNOTSUPP for Landlock nor any other kernel interfaces.
That sounds reasonable. It's a bit confusing that many man pages document ENOTSUP (user-space). I'll take this into account for when I see some patch that touches one of those ENOTSUPs, and ask why, and maybe remove them all in favor of EOPNOTSUPP.
Thanks,
Alex
Signature · 2 lines
<http://www.alejandro-colomar.es/> GPG key fingerprint: A9348594CE31283A826FBDD8D57633D441E25BB5
Re: [PATCH v6 1/1] landlock.7: Explain the best-effort fallback mechanism in the example
Quoted 16 lines · Alejandro Colomar
Hi Mickaël,
Quoted 9 lines · Mickaël Salaün
Indeed, ENOTSUPP is a kernel error type, only EOPNOTSUPP should be used to return error to user space. ENOTSUPP is not used by the kernel, it is only defined by the libc:
# ifndef ENOTSUP # define ENOTSUP EOPNOTSUPP # endif[...]
Quoted 1 line
Quoted 8 lines
Quoted 3 lines
ENOTSUP doesn't exist in the kernel source, so it is legitimate that Landlock and any other kernel interfaces use EOPNOTSUPP. ENOTSUP should then not replace EOPNOTSUPP for Landlock nor any other kernel interfaces.
That sounds reasonable. It's a bit confusing that many man pages document ENOTSUP (user-space). I'll take this into account for when I see some patch that touches one of those ENOTSUPs, and ask why, and maybe remove them all in favor of EOPNOTSUPP.
I forgot to paste this:
$ grep -rl '\bENOTSUP\b' man* man2/clock_getres.2 man2/clock_nanosleep.2 man2/getxattr.2 man2/listxattr.2 man2/setxattr.2 man2/removexattr.2 man2/timer_create.2 man2/chmod.2 man3/pthread_attr_setinheritsched.3 man3/dirfd.3 man3/pthread_setschedparam.3 man3/pthread_attr_setscope.3 man3/pthread_attr_setschedpolicy.3 man3/pthread_mutexattr_getpshared.3 man3/errno.3 man3/pthread_setschedprio.3 man3/pthread_attr_setschedparam.3 man7/cgroups.7
Quoted 4 lines
Thanks,
Alex
Signature · 2 lines
<http://www.alejandro-colomar.es/> GPG key fingerprint: A9348594CE31283A826FBDD8D57633D441E25BB5