* [PATCH] landlock: Work around randstruct unnamed static initializer support @ 2025-04-21 0:08 Kees Cook 2025-04-22 12:25 ` Mickaël Salaün 2025-04-25 10:03 ` Günther Noack 0 siblings, 2 replies; 6+ messages in thread From: Kees Cook @ 2025-04-21 0:08 UTC (permalink / raw) To: Mickaël Salaün Cc: Kees Cook, Dr. David Alan Gilbert, Mark Brown, WangYuli, Günther Noack, Arnd Bergmann, Paul Moore, James Morris, Serge E. Hallyn, linux-security-module, linux-kernel, linux-hardening Unnamed static initializers aren't supported by the randstruct GCC plugin. Quoting the plugin, "set up a bogus anonymous struct field designed to error out on unnamed struct initializers as gcc provides no other way to detect such code". That is exactly what happens with the landlock code, so adjust the static initializers for structs lsm_ioctlop_audit and landlock_request that contain a randomized structure (struct path) to use named variables, which avoids the intentional GCC crashes: security/landlock/fs.c: In function 'hook_file_ioctl_common': security/landlock/fs.c:1745:61: internal compiler error: in count_type_elements, at expr.cc:7092 1745 | .u.op = &(struct lsm_ioctlop_audit) { | ^ security/landlock/fs.c: In function 'log_fs_change_topology_path': security/landlock/fs.c:1379:65: internal compiler error: in count_type_elements, at expr.cc:7092 1379 | landlock_log_denial(subject, &(struct landlock_request) { | ^ We went 8 years before tripping over this! With this patch landed, we can enable COMPILE_TEST builds with the randstruct GCC plugin again. Reported-by: "Dr. David Alan Gilbert" <linux@treblig.org> Closes: https://lore.kernel.org/lkml/Z_PRaKx7q70MKgCA@gallifrey/ Reported-by: Mark Brown <broonie@kernel.org> Closes: https://lore.kernel.org/lkml/20250407-kbuild-disable-gcc-plugins-v1-1-5d46ae583f5e@kernel.org/ Reported-by: WangYuli <wangyuli@uniontech.com> Closes: https://lore.kernel.org/lkml/337D5D4887277B27+3c677db3-a8b9-47f0-93a4-7809355f1381@uniontech.com/ Signed-off-by: Kees Cook <kees@kernel.org> --- Cc: "Mickaël Salaün" <mic@digikod.net> Cc: "Günther Noack" <gnoack@google.com> Cc: Mark Brown <broonie@kernel.org> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Paul Moore <paul@paul-moore.com> Cc: James Morris <jmorris@namei.org> Cc: "Serge E. Hallyn" <serge@hallyn.com> Cc: <linux-security-module@vger.kernel.org> --- security/landlock/fs.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/security/landlock/fs.c b/security/landlock/fs.c index 6fee7c20f64d..b2818afb0503 100644 --- a/security/landlock/fs.c +++ b/security/landlock/fs.c @@ -1376,14 +1376,14 @@ static void log_fs_change_topology_path(const struct landlock_cred_security *const subject, size_t handle_layer, const struct path *const path) { - landlock_log_denial(subject, &(struct landlock_request) { + struct landlock_request request = { .type = LANDLOCK_REQUEST_FS_CHANGE_TOPOLOGY, - .audit = { - .type = LSM_AUDIT_DATA_PATH, - .u.path = *path, - }, + .audit.type = LSM_AUDIT_DATA_PATH, .layer_plus_one = handle_layer + 1, - }); + }; + request.audit.u.path = *path; + + landlock_log_denial(subject, &request); } static void log_fs_change_topology_dentry( @@ -1720,6 +1720,7 @@ static int hook_file_truncate(struct file *const file) static int hook_file_ioctl_common(const struct file *const file, const unsigned int cmd, const bool is_compat) { + struct lsm_ioctlop_audit audit_log; access_mask_t allowed_access = landlock_file(file)->allowed_access; /* @@ -1738,14 +1739,13 @@ static int hook_file_ioctl_common(const struct file *const file, is_masked_device_ioctl(cmd)) return 0; + audit_log.path = file->f_path; + audit_log.cmd = cmd; landlock_log_denial(landlock_cred(file->f_cred), &(struct landlock_request) { .type = LANDLOCK_REQUEST_FS_ACCESS, .audit = { .type = LSM_AUDIT_DATA_IOCTL_OP, - .u.op = &(struct lsm_ioctlop_audit) { - .path = file->f_path, - .cmd = cmd, - }, + .u.op = &audit_log, }, .all_existing_optional_access = _LANDLOCK_ACCESS_FS_OPTIONAL, .access = LANDLOCK_ACCESS_FS_IOCTL_DEV, -- 2.34.1 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH] landlock: Work around randstruct unnamed static initializer support 2025-04-21 0:08 [PATCH] landlock: Work around randstruct unnamed static initializer support Kees Cook @ 2025-04-22 12:25 ` Mickaël Salaün 2025-04-22 12:53 ` Arnd Bergmann 2025-04-25 10:03 ` Günther Noack 1 sibling, 1 reply; 6+ messages in thread From: Mickaël Salaün @ 2025-04-22 12:25 UTC (permalink / raw) To: Kees Cook Cc: Dr. David Alan Gilbert, Mark Brown, WangYuli, Günther Noack, Arnd Bergmann, Paul Moore, James Morris, Serge E. Hallyn, Linus Torvalds, linux-security-module, linux-kernel, linux-hardening On Sun, Apr 20, 2025 at 05:08:59PM -0700, Kees Cook wrote: > Unnamed static initializers aren't supported by the randstruct GCC > plugin. Quoting the plugin, "set up a bogus anonymous struct field > designed to error out on unnamed struct initializers as gcc provides > no other way to detect such code". That is exactly what happens > with the landlock code, so adjust the static initializers for structs > lsm_ioctlop_audit and landlock_request that contain a randomized structure > (struct path) to use named variables, which avoids the intentional > GCC crashes: This is not a sustainable solution. Could we fix the plugin instead? This new Landlock change may be the first to trigger this plugin bug but it will probably not be the last to use unnamed static initializers. Forbidding specific C constructs should be documented. As a temporary solution (not sure if it's worth it, nor a good idea), could handling of types used in unnamed static initializers be ignored by this plugin? I guess [1] is already a temporary solution though. [1] https://lore.kernel.org/all/20250409151154.work.872-kees@kernel.org/ > > security/landlock/fs.c: In function 'hook_file_ioctl_common': > security/landlock/fs.c:1745:61: internal compiler error: in count_type_elements, at expr.cc:7092 > 1745 | .u.op = &(struct lsm_ioctlop_audit) { > | ^ > > security/landlock/fs.c: In function 'log_fs_change_topology_path': > security/landlock/fs.c:1379:65: internal compiler error: in count_type_elements, at expr.cc:7092 > 1379 | landlock_log_denial(subject, &(struct landlock_request) { > | ^ > > We went 8 years before tripping over this! With this patch landed, > we can enable COMPILE_TEST builds with the randstruct GCC plugin again. > > Reported-by: "Dr. David Alan Gilbert" <linux@treblig.org> > Closes: https://lore.kernel.org/lkml/Z_PRaKx7q70MKgCA@gallifrey/ > Reported-by: Mark Brown <broonie@kernel.org> > Closes: https://lore.kernel.org/lkml/20250407-kbuild-disable-gcc-plugins-v1-1-5d46ae583f5e@kernel.org/ > Reported-by: WangYuli <wangyuli@uniontech.com> > Closes: https://lore.kernel.org/lkml/337D5D4887277B27+3c677db3-a8b9-47f0-93a4-7809355f1381@uniontech.com/ > Signed-off-by: Kees Cook <kees@kernel.org> > --- > Cc: "Mickaël Salaün" <mic@digikod.net> > Cc: "Günther Noack" <gnoack@google.com> > Cc: Mark Brown <broonie@kernel.org> > Cc: Arnd Bergmann <arnd@arndb.de> > Cc: Paul Moore <paul@paul-moore.com> > Cc: James Morris <jmorris@namei.org> > Cc: "Serge E. Hallyn" <serge@hallyn.com> > Cc: <linux-security-module@vger.kernel.org> > --- > security/landlock/fs.c | 20 ++++++++++---------- > 1 file changed, 10 insertions(+), 10 deletions(-) > > diff --git a/security/landlock/fs.c b/security/landlock/fs.c > index 6fee7c20f64d..b2818afb0503 100644 > --- a/security/landlock/fs.c > +++ b/security/landlock/fs.c > @@ -1376,14 +1376,14 @@ static void > log_fs_change_topology_path(const struct landlock_cred_security *const subject, > size_t handle_layer, const struct path *const path) > { > - landlock_log_denial(subject, &(struct landlock_request) { > + struct landlock_request request = { > .type = LANDLOCK_REQUEST_FS_CHANGE_TOPOLOGY, > - .audit = { > - .type = LSM_AUDIT_DATA_PATH, > - .u.path = *path, > - }, > + .audit.type = LSM_AUDIT_DATA_PATH, > .layer_plus_one = handle_layer + 1, > - }); > + }; > + request.audit.u.path = *path; > + > + landlock_log_denial(subject, &request); > } > > static void log_fs_change_topology_dentry( > @@ -1720,6 +1720,7 @@ static int hook_file_truncate(struct file *const file) > static int hook_file_ioctl_common(const struct file *const file, > const unsigned int cmd, const bool is_compat) > { > + struct lsm_ioctlop_audit audit_log; > access_mask_t allowed_access = landlock_file(file)->allowed_access; > > /* > @@ -1738,14 +1739,13 @@ static int hook_file_ioctl_common(const struct file *const file, > is_masked_device_ioctl(cmd)) > return 0; > > + audit_log.path = file->f_path; > + audit_log.cmd = cmd; > landlock_log_denial(landlock_cred(file->f_cred), &(struct landlock_request) { > .type = LANDLOCK_REQUEST_FS_ACCESS, > .audit = { > .type = LSM_AUDIT_DATA_IOCTL_OP, > - .u.op = &(struct lsm_ioctlop_audit) { > - .path = file->f_path, > - .cmd = cmd, > - }, > + .u.op = &audit_log, > }, > .all_existing_optional_access = _LANDLOCK_ACCESS_FS_OPTIONAL, > .access = LANDLOCK_ACCESS_FS_IOCTL_DEV, > -- > 2.34.1 > > ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] landlock: Work around randstruct unnamed static initializer support 2025-04-22 12:25 ` Mickaël Salaün @ 2025-04-22 12:53 ` Arnd Bergmann 2025-04-22 14:59 ` Kees Cook 0 siblings, 1 reply; 6+ messages in thread From: Arnd Bergmann @ 2025-04-22 12:53 UTC (permalink / raw) To: Mickaël Salaün, Kees Cook Cc: linux, Mark Brown, WangYuli, Günther Noack, Paul Moore, James Morris, Serge E. Hallyn, Linus Torvalds, linux-security-module, linux-kernel, linux-hardening On Tue, Apr 22, 2025, at 14:25, Mickaël Salaün wrote: > On Sun, Apr 20, 2025 at 05:08:59PM -0700, Kees Cook wrote: >> Unnamed static initializers aren't supported by the randstruct GCC >> plugin. Quoting the plugin, "set up a bogus anonymous struct field >> designed to error out on unnamed struct initializers as gcc provides >> no other way to detect such code". That is exactly what happens >> with the landlock code, so adjust the static initializers for structs >> lsm_ioctlop_audit and landlock_request that contain a randomized structure >> (struct path) to use named variables, which avoids the intentional >> GCC crashes: > > This is not a sustainable solution. Could we fix the plugin instead? > This new Landlock change may be the first to trigger this plugin bug but > it will probably not be the last to use unnamed static initializers. > Forbidding specific C constructs should be documented. I think the version from Kees' patch looks more readable than the version with the compound literal, so it certainly seems appropriate as an immediate regression fix, even if it's possible to fix the plugin later. >> We went 8 years before tripping over this! Right, it's probably enough to revisit the plugin code after it happens again. >> Closes: https://lore.kernel.org/lkml/337D5D4887277B27+3c677db3-a8b9-47f0-93a4-7809355f1381@uniontech.com/ >> Signed-off-by: Kees Cook <kees@kernel.org> Acked-by: Arnd Bergmann <arnd@arndb.de> ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] landlock: Work around randstruct unnamed static initializer support 2025-04-22 12:53 ` Arnd Bergmann @ 2025-04-22 14:59 ` Kees Cook 2025-04-23 18:38 ` Mickaël Salaün 0 siblings, 1 reply; 6+ messages in thread From: Kees Cook @ 2025-04-22 14:59 UTC (permalink / raw) To: Arnd Bergmann Cc: Mickaël Salaün, linux, Mark Brown, WangYuli, Günther Noack, Paul Moore, James Morris, Serge E. Hallyn, Linus Torvalds, linux-security-module, linux-kernel, linux-hardening On Tue, Apr 22, 2025 at 02:53:05PM +0200, Arnd Bergmann wrote: > On Tue, Apr 22, 2025, at 14:25, Mickaël Salaün wrote: > > On Sun, Apr 20, 2025 at 05:08:59PM -0700, Kees Cook wrote: > >> Unnamed static initializers aren't supported by the randstruct GCC > >> plugin. Quoting the plugin, "set up a bogus anonymous struct field > >> designed to error out on unnamed struct initializers as gcc provides > >> no other way to detect such code". That is exactly what happens > >> with the landlock code, so adjust the static initializers for structs > >> lsm_ioctlop_audit and landlock_request that contain a randomized structure > >> (struct path) to use named variables, which avoids the intentional > >> GCC crashes: > > > > This is not a sustainable solution. Could we fix the plugin instead? > > This new Landlock change may be the first to trigger this plugin bug but > > it will probably not be the last to use unnamed static initializers. > > Forbidding specific C constructs should be documented. > > I think the version from Kees' patch looks more readable than > the version with the compound literal, so it certainly seems appropriate > as an immediate regression fix, even if it's possible to fix the > plugin later. > > >> We went 8 years before tripping over this! > > Right, it's probably enough to revisit the plugin code after > it happens again. Yeah, that's my thinking as well. > >> Closes: https://lore.kernel.org/lkml/337D5D4887277B27+3c677db3-a8b9-47f0-93a4-7809355f1381@uniontech.com/ > >> Signed-off-by: Kees Cook <kees@kernel.org> > > Acked-by: Arnd Bergmann <arnd@arndb.de> Thanks! Mickaël, are you good with this for now, and if so, do you want to carry it or shall I? -Kees -- Kees Cook ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] landlock: Work around randstruct unnamed static initializer support 2025-04-22 14:59 ` Kees Cook @ 2025-04-23 18:38 ` Mickaël Salaün 0 siblings, 0 replies; 6+ messages in thread From: Mickaël Salaün @ 2025-04-23 18:38 UTC (permalink / raw) To: Kees Cook Cc: Arnd Bergmann, linux, Mark Brown, WangYuli, Günther Noack, Paul Moore, James Morris, Serge E. Hallyn, Linus Torvalds, linux-security-module, linux-kernel, linux-hardening On Tue, Apr 22, 2025 at 07:59:07AM -0700, Kees Cook wrote: > On Tue, Apr 22, 2025 at 02:53:05PM +0200, Arnd Bergmann wrote: > > On Tue, Apr 22, 2025, at 14:25, Mickaël Salaün wrote: > > > On Sun, Apr 20, 2025 at 05:08:59PM -0700, Kees Cook wrote: > > >> Unnamed static initializers aren't supported by the randstruct GCC > > >> plugin. Quoting the plugin, "set up a bogus anonymous struct field > > >> designed to error out on unnamed struct initializers as gcc provides > > >> no other way to detect such code". That is exactly what happens > > >> with the landlock code, so adjust the static initializers for structs > > >> lsm_ioctlop_audit and landlock_request that contain a randomized structure > > >> (struct path) to use named variables, which avoids the intentional > > >> GCC crashes: > > > > > > This is not a sustainable solution. Could we fix the plugin instead? > > > This new Landlock change may be the first to trigger this plugin bug but > > > it will probably not be the last to use unnamed static initializers. > > > Forbidding specific C constructs should be documented. > > > > I think the version from Kees' patch looks more readable than > > the version with the compound literal, so it certainly seems appropriate > > as an immediate regression fix, even if it's possible to fix the > > plugin later. > > > > >> We went 8 years before tripping over this! > > > > Right, it's probably enough to revisit the plugin code after > > it happens again. > > Yeah, that's my thinking as well. > > > >> Closes: https://lore.kernel.org/lkml/337D5D4887277B27+3c677db3-a8b9-47f0-93a4-7809355f1381@uniontech.com/ > > >> Signed-off-by: Kees Cook <kees@kernel.org> > > > > Acked-by: Arnd Bergmann <arnd@arndb.de> > > Thanks! Mickaël, are you good with this for now, and if so, do you want > to carry it or shall I? I don't like this kind of change but I'm OK with it if it comes with documentation explaining what construct should not be used in the kernel (and even better, updating checkpatch.pl accordingly), or if it's a temporary workaround and someone is working on fixing the plugin. Are you or someone else working on it? In the meantime, feel free to carry this patch. ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] landlock: Work around randstruct unnamed static initializer support 2025-04-21 0:08 [PATCH] landlock: Work around randstruct unnamed static initializer support Kees Cook 2025-04-22 12:25 ` Mickaël Salaün @ 2025-04-25 10:03 ` Günther Noack 1 sibling, 0 replies; 6+ messages in thread From: Günther Noack @ 2025-04-25 10:03 UTC (permalink / raw) To: Kees Cook Cc: Mickaël Salaün, Dr. David Alan Gilbert, Mark Brown, WangYuli, Arnd Bergmann, Paul Moore, James Morris, Serge E. Hallyn, linux-security-module, linux-kernel, linux-hardening Hello Kees! On Sun, Apr 20, 2025 at 05:08:59PM -0700, Kees Cook wrote: > Unnamed static initializers aren't supported by the randstruct GCC > plugin. Quoting the plugin, "set up a bogus anonymous struct field > designed to error out on unnamed struct initializers as gcc provides > no other way to detect such code". That is exactly what happens > with the landlock code, so adjust the static initializers for structs > lsm_ioctlop_audit and landlock_request that contain a randomized structure > (struct path) to use named variables, which avoids the intentional > GCC crashes: > > security/landlock/fs.c: In function 'hook_file_ioctl_common': > security/landlock/fs.c:1745:61: internal compiler error: in count_type_elements, at expr.cc:7092 > 1745 | .u.op = &(struct lsm_ioctlop_audit) { > | ^ > > security/landlock/fs.c: In function 'log_fs_change_topology_path': > security/landlock/fs.c:1379:65: internal compiler error: in count_type_elements, at expr.cc:7092 > 1379 | landlock_log_denial(subject, &(struct landlock_request) { > | ^ > > We went 8 years before tripping over this! With this patch landed, > we can enable COMPILE_TEST builds with the randstruct GCC plugin again. I am still struggling to understand the boundaries of what the randstruct plugin supports and what it fails on. Could you please clarify? (Specific questions below.) > Reported-by: "Dr. David Alan Gilbert" <linux@treblig.org> > Closes: https://lore.kernel.org/lkml/Z_PRaKx7q70MKgCA@gallifrey/ > Reported-by: Mark Brown <broonie@kernel.org> > Closes: https://lore.kernel.org/lkml/20250407-kbuild-disable-gcc-plugins-v1-1-5d46ae583f5e@kernel.org/ > Reported-by: WangYuli <wangyuli@uniontech.com> > Closes: https://lore.kernel.org/lkml/337D5D4887277B27+3c677db3-a8b9-47f0-93a4-7809355f1381@uniontech.com/ > Signed-off-by: Kees Cook <kees@kernel.org> > --- > Cc: "Mickaël Salaün" <mic@digikod.net> > Cc: "Günther Noack" <gnoack@google.com> > Cc: Mark Brown <broonie@kernel.org> > Cc: Arnd Bergmann <arnd@arndb.de> > Cc: Paul Moore <paul@paul-moore.com> > Cc: James Morris <jmorris@namei.org> > Cc: "Serge E. Hallyn" <serge@hallyn.com> > Cc: <linux-security-module@vger.kernel.org> > --- > security/landlock/fs.c | 20 ++++++++++---------- > 1 file changed, 10 insertions(+), 10 deletions(-) > > diff --git a/security/landlock/fs.c b/security/landlock/fs.c > index 6fee7c20f64d..b2818afb0503 100644 > --- a/security/landlock/fs.c > +++ b/security/landlock/fs.c > @@ -1376,14 +1376,14 @@ static void > log_fs_change_topology_path(const struct landlock_cred_security *const subject, > size_t handle_layer, const struct path *const path) > { > - landlock_log_denial(subject, &(struct landlock_request) { > + struct landlock_request request = { > .type = LANDLOCK_REQUEST_FS_CHANGE_TOPOLOGY, > - .audit = { > - .type = LSM_AUDIT_DATA_PATH, > - .u.path = *path, > - }, > + .audit.type = LSM_AUDIT_DATA_PATH, > .layer_plus_one = handle_layer + 1, > - }); > + }; > + request.audit.u.path = *path; > + > + landlock_log_denial(subject, &request); > } If I understood the commit message correctly, we are giving a name ("request") to the struct landlock_request here, because the randstruct plugin needs that if the constructed struct (recursively?) contains a randstruct-enabled member, like .audit.u.path in this case? I am surprised that you pulled the assignment to "request.audit.u.path" out of the struct initialization expression though. Was that also necessary for randstruct to work? Would it have worked to initialize it inline instead, like this? struct landlock_request request = { .type = LANDLOCK_REQUEST_FS_CHANGE_TOPOLOGY, .audit.type = LSM_AUDIT_DATA_PATH, .audit.u.path = *path, .layer_plus_one = handle_layer + 1, }; > > static void log_fs_change_topology_dentry( > @@ -1720,6 +1720,7 @@ static int hook_file_truncate(struct file *const file) > static int hook_file_ioctl_common(const struct file *const file, > const unsigned int cmd, const bool is_compat) > { > + struct lsm_ioctlop_audit audit_log; > access_mask_t allowed_access = landlock_file(file)->allowed_access; > > /* > @@ -1738,14 +1739,13 @@ static int hook_file_ioctl_common(const struct file *const file, > is_masked_device_ioctl(cmd)) > return 0; > > + audit_log.path = file->f_path; > + audit_log.cmd = cmd; Same question here, I guess. This could not have been written like this? struct lsm_ioctlop_audit audit_log = { .path = file->f_path, .cmd = cmd, }; > landlock_log_denial(landlock_cred(file->f_cred), &(struct landlock_request) { > .type = LANDLOCK_REQUEST_FS_ACCESS, > .audit = { > .type = LSM_AUDIT_DATA_IOCTL_OP, > - .u.op = &(struct lsm_ioctlop_audit) { > - .path = file->f_path, > - .cmd = cmd, > - }, > + .u.op = &audit_log, > }, > .all_existing_optional_access = _LANDLOCK_ACCESS_FS_OPTIONAL, > .access = LANDLOCK_ACCESS_FS_IOCTL_DEV, > -- > 2.34.1 > That being said, the code transformation in this patch is obviously correct, and it's good to fix the build, so looks good: Reviewed-by: Günther Noack <gnoack@google.com> But as Mickaël also said, it seems worrying that otherwise correct C code does not compile with that plugin, especially when the conditions under which that happens are not clear. I would also like to understand this better, so that we can avoid tripping over it in the future. Thanks! -Günther ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2025-04-25 10:03 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2025-04-21 0:08 [PATCH] landlock: Work around randstruct unnamed static initializer support Kees Cook 2025-04-22 12:25 ` Mickaël Salaün 2025-04-22 12:53 ` Arnd Bergmann 2025-04-22 14:59 ` Kees Cook 2025-04-23 18:38 ` Mickaël Salaün 2025-04-25 10:03 ` Günther Noack
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).