Message ID | 20250409185019.238841-57-paul@paul-moore.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | Rework the LSM initialization | expand |
On Wed, Apr 9, 2025 at 2:55 PM Paul Moore <paul@paul-moore.com> wrote: > > SELinux currently has a number of initcalls so we've created a new > function, selinux_initcall(), which wraps all of these initcalls so > that we have a single initcall function that can be registered with the > LSM framework. > > Signed-off-by: Paul Moore <paul@paul-moore.com> > --- > diff --git a/security/selinux/include/audit.h b/security/selinux/include/audit.h > index d5b0425055e4..5989f8dd1e86 100644 > --- a/security/selinux/include/audit.h > +++ b/security/selinux/include/audit.h > @@ -15,6 +15,11 @@ > #include <linux/audit.h> > #include <linux/types.h> > > +/** > + * XXX > + */ Assuming this will be fixed before merge. > +int selinux_audit_rule_avc_callback(u32 event); > + > /** > * selinux_audit_rule_init - alloc/init an selinux audit rule structure. > * @field: the field this rule refers to > diff --git a/security/selinux/include/initcalls.h b/security/selinux/include/initcalls.h > new file mode 100644 > index 000000000000..6674cf489473 > --- /dev/null > +++ b/security/selinux/include/initcalls.h > @@ -0,0 +1,19 @@ > +// SPDX-License-Identifier: GPL-2.0-only > +/* > + * SELinux initcalls > + */ > + > +#ifndef _SELINUX_INITCALLS_H > +#define _SELINUX_INITCALLS_H > + > +int init_sel_fs(void); > +int sel_netport_init(void); > +int sel_netnode_init(void); > +int sel_netif_init(void); > +int sel_netlink_init(void); > +int sel_ib_pkey_init(void); > +int selinux_nf_ip_init(void); The last two only exist if certain Kconfig options are set. > + > +int selinux_initcall(void); > + > +#endif > diff --git a/security/selinux/initcalls.c b/security/selinux/initcalls.c > new file mode 100644 > index 000000000000..81f01f8ad215 > --- /dev/null > +++ b/security/selinux/initcalls.c > @@ -0,0 +1,50 @@ > +// SPDX-License-Identifier: GPL-2.0-only > +/* > + * SELinux initcalls > + */ > + > +#include <linux/init.h> > + > +#include "initcalls.h" > + > +/** > + * selinux_initcall - Perform the SELinux initcalls > + * > + * Used as a device initcall in the SELinux LSM definition. > + */ > +int __init selinux_initcall(void) > +{ > + int rc = 0, rc_tmp = 0; > + > + rc_tmp = init_sel_fs(); > + if (!rc && rc_tmp) > + rc = rc_tmp; > + > + rc_tmp = sel_netport_init(); > + if (!rc && rc_tmp) > + rc = rc_tmp; > + > + rc_tmp = sel_netnode_init(); > + if (!rc && rc_tmp) > + rc = rc_tmp; > + > + rc_tmp = sel_netif_init(); > + if (!rc && rc_tmp) > + rc = rc_tmp; > + > + rc_tmp = sel_netlink_init(); > + if (!rc && rc_tmp) > + rc = rc_tmp; > + > + rc_tmp = sel_ib_pkey_init(); This one depends on CONFIG_SECURITY_INFINIBAND. > + if (!rc && rc_tmp) > + rc = rc_tmp; > + > +#if defined(CONFIG_NETFILTER) > + rc_tmp = selinux_nf_ip_init(); > + if (!rc && rc_tmp) > + rc = rc_tmp; > +#endif > + > + return rc; > +}
On Thu, Apr 10, 2025 at 12:33 PM Stephen Smalley <stephen.smalley.work@gmail.com> wrote: > On Wed, Apr 9, 2025 at 2:55 PM Paul Moore <paul@paul-moore.com> wrote: > > > > SELinux currently has a number of initcalls so we've created a new > > function, selinux_initcall(), which wraps all of these initcalls so > > that we have a single initcall function that can be registered with the > > LSM framework. > > > > Signed-off-by: Paul Moore <paul@paul-moore.com> > > --- > > > diff --git a/security/selinux/include/audit.h b/security/selinux/include/audit.h > > index d5b0425055e4..5989f8dd1e86 100644 > > --- a/security/selinux/include/audit.h > > +++ b/security/selinux/include/audit.h > > @@ -15,6 +15,11 @@ > > #include <linux/audit.h> > > #include <linux/types.h> > > > > +/** > > + * XXX > > + */ > > Assuming this will be fixed before merge. Yep, I noticed that very shortly after posting and added the comment block. > > +int selinux_audit_rule_avc_callback(u32 event); > > + > > /** > > * selinux_audit_rule_init - alloc/init an selinux audit rule structure. > > * @field: the field this rule refers to > > diff --git a/security/selinux/include/initcalls.h b/security/selinux/include/initcalls.h > > new file mode 100644 > > index 000000000000..6674cf489473 > > --- /dev/null > > +++ b/security/selinux/include/initcalls.h > > @@ -0,0 +1,19 @@ > > +// SPDX-License-Identifier: GPL-2.0-only > > +/* > > + * SELinux initcalls > > + */ > > + > > +#ifndef _SELINUX_INITCALLS_H > > +#define _SELINUX_INITCALLS_H > > + > > +int init_sel_fs(void); > > +int sel_netport_init(void); > > +int sel_netnode_init(void); > > +int sel_netif_init(void); > > +int sel_netlink_init(void); > > +int sel_ib_pkey_init(void); > > +int selinux_nf_ip_init(void); > > The last two only exist if certain Kconfig options are set. Good catch, thanks. The use of the netfilter initcall is already conditional on CONFIG_NETFILTER in selinux_initcall(), but I forgot the InfiniBand inticall. Unless I'm mistaken, it should be harmless to have the function declaration regardless of if it is defined anywhere. > > diff --git a/security/selinux/initcalls.c b/security/selinux/initcalls.c > > new file mode 100644 > > index 000000000000..81f01f8ad215 > > --- /dev/null > > +++ b/security/selinux/initcalls.c > > @@ -0,0 +1,50 @@ > > +// SPDX-License-Identifier: GPL-2.0-only > > +/* > > + * SELinux initcalls > > + */ > > + > > +#include <linux/init.h> > > + > > +#include "initcalls.h" > > + > > +/** > > + * selinux_initcall - Perform the SELinux initcalls > > + * > > + * Used as a device initcall in the SELinux LSM definition. > > + */ > > +int __init selinux_initcall(void) > > +{ > > + int rc = 0, rc_tmp = 0; > > + > > + rc_tmp = init_sel_fs(); > > + if (!rc && rc_tmp) > > + rc = rc_tmp; > > + > > + rc_tmp = sel_netport_init(); > > + if (!rc && rc_tmp) > > + rc = rc_tmp; > > + > > + rc_tmp = sel_netnode_init(); > > + if (!rc && rc_tmp) > > + rc = rc_tmp; > > + > > + rc_tmp = sel_netif_init(); > > + if (!rc && rc_tmp) > > + rc = rc_tmp; > > + > > + rc_tmp = sel_netlink_init(); > > + if (!rc && rc_tmp) > > + rc = rc_tmp; > > + > > + rc_tmp = sel_ib_pkey_init(); > > This one depends on CONFIG_SECURITY_INFINIBAND. Fixed, thanks. > > + if (!rc && rc_tmp) > > + rc = rc_tmp; > > + > > +#if defined(CONFIG_NETFILTER) > > + rc_tmp = selinux_nf_ip_init(); > > + if (!rc && rc_tmp) > > + rc = rc_tmp; > > +#endif > > + > > + return rc; > > +}
diff --git a/security/selinux/Makefile b/security/selinux/Makefile index 66e56e9011df..72d3baf7900c 100644 --- a/security/selinux/Makefile +++ b/security/selinux/Makefile @@ -15,7 +15,7 @@ ccflags-y := -I$(srctree)/security/selinux -I$(srctree)/security/selinux/include ccflags-$(CONFIG_SECURITY_SELINUX_DEBUG) += -DDEBUG selinux-y := avc.o hooks.o selinuxfs.o netlink.o nlmsgtab.o netif.o \ - netnode.o netport.o status.o \ + netnode.o netport.o status.o initcalls.o \ ss/ebitmap.o ss/hashtab.o ss/symtab.o ss/sidtab.o ss/avtab.o \ ss/policydb.o ss/services.o ss/conditional.o ss/mls.o ss/context.o diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index f28a12a0a1c8..95b2399b1f4d 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -95,6 +95,7 @@ #include <linux/io_uring/cmd.h> #include <uapi/linux/lsm.h> +#include "initcalls.h" #include "avc.h" #include "objsec.h" #include "netif.h" @@ -7535,6 +7536,10 @@ static __init int selinux_init(void) if (avc_add_callback(selinux_lsm_notifier_avc_callback, AVC_CALLBACK_RESET)) panic("SELinux: Unable to register AVC LSM notifier callback\n"); + if (avc_add_callback(selinux_audit_rule_avc_callback, + AVC_CALLBACK_RESET)) + panic("SELinux: Unable to register AVC audit callback\n"); + if (selinux_enforcing_boot) pr_debug("SELinux: Starting in enforcing mode\n"); else @@ -7567,6 +7572,7 @@ DEFINE_LSM(selinux) = { .enabled = &selinux_enabled_boot, .blobs = &selinux_blob_sizes, .init = selinux_init, + .initcall_device = selinux_initcall, }; #if defined(CONFIG_NETFILTER) @@ -7628,7 +7634,7 @@ static struct pernet_operations selinux_net_ops = { .exit = selinux_nf_unregister, }; -static int __init selinux_nf_ip_init(void) +int __init selinux_nf_ip_init(void) { int err; @@ -7643,5 +7649,4 @@ static int __init selinux_nf_ip_init(void) return 0; } -__initcall(selinux_nf_ip_init); #endif /* CONFIG_NETFILTER */ diff --git a/security/selinux/ibpkey.c b/security/selinux/ibpkey.c index 48f537b41c58..2609913f338a 100644 --- a/security/selinux/ibpkey.c +++ b/security/selinux/ibpkey.c @@ -23,6 +23,7 @@ #include <linux/list.h> #include <linux/spinlock.h> +#include "initcalls.h" #include "ibpkey.h" #include "objsec.h" @@ -219,7 +220,7 @@ void sel_ib_pkey_flush(void) spin_unlock_irqrestore(&sel_ib_pkey_lock, flags); } -static __init int sel_ib_pkey_init(void) +int __init sel_ib_pkey_init(void) { int iter; @@ -233,5 +234,3 @@ static __init int sel_ib_pkey_init(void) return 0; } - -subsys_initcall(sel_ib_pkey_init); diff --git a/security/selinux/include/audit.h b/security/selinux/include/audit.h index d5b0425055e4..5989f8dd1e86 100644 --- a/security/selinux/include/audit.h +++ b/security/selinux/include/audit.h @@ -15,6 +15,11 @@ #include <linux/audit.h> #include <linux/types.h> +/** + * XXX + */ +int selinux_audit_rule_avc_callback(u32 event); + /** * selinux_audit_rule_init - alloc/init an selinux audit rule structure. * @field: the field this rule refers to diff --git a/security/selinux/include/initcalls.h b/security/selinux/include/initcalls.h new file mode 100644 index 000000000000..6674cf489473 --- /dev/null +++ b/security/selinux/include/initcalls.h @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * SELinux initcalls + */ + +#ifndef _SELINUX_INITCALLS_H +#define _SELINUX_INITCALLS_H + +int init_sel_fs(void); +int sel_netport_init(void); +int sel_netnode_init(void); +int sel_netif_init(void); +int sel_netlink_init(void); +int sel_ib_pkey_init(void); +int selinux_nf_ip_init(void); + +int selinux_initcall(void); + +#endif diff --git a/security/selinux/initcalls.c b/security/selinux/initcalls.c new file mode 100644 index 000000000000..81f01f8ad215 --- /dev/null +++ b/security/selinux/initcalls.c @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * SELinux initcalls + */ + +#include <linux/init.h> + +#include "initcalls.h" + +/** + * selinux_initcall - Perform the SELinux initcalls + * + * Used as a device initcall in the SELinux LSM definition. + */ +int __init selinux_initcall(void) +{ + int rc = 0, rc_tmp = 0; + + rc_tmp = init_sel_fs(); + if (!rc && rc_tmp) + rc = rc_tmp; + + rc_tmp = sel_netport_init(); + if (!rc && rc_tmp) + rc = rc_tmp; + + rc_tmp = sel_netnode_init(); + if (!rc && rc_tmp) + rc = rc_tmp; + + rc_tmp = sel_netif_init(); + if (!rc && rc_tmp) + rc = rc_tmp; + + rc_tmp = sel_netlink_init(); + if (!rc && rc_tmp) + rc = rc_tmp; + + rc_tmp = sel_ib_pkey_init(); + if (!rc && rc_tmp) + rc = rc_tmp; + +#if defined(CONFIG_NETFILTER) + rc_tmp = selinux_nf_ip_init(); + if (!rc && rc_tmp) + rc = rc_tmp; +#endif + + return rc; +} diff --git a/security/selinux/netif.c b/security/selinux/netif.c index 43a0d3594b72..69f660721dc8 100644 --- a/security/selinux/netif.c +++ b/security/selinux/netif.c @@ -22,6 +22,7 @@ #include <linux/rcupdate.h> #include <net/net_namespace.h> +#include "initcalls.h" #include "security.h" #include "objsec.h" #include "netif.h" @@ -261,7 +262,7 @@ static struct notifier_block sel_netif_netdev_notifier = { .notifier_call = sel_netif_netdev_notifier_handler, }; -static __init int sel_netif_init(void) +int __init sel_netif_init(void) { int i; @@ -276,5 +277,3 @@ static __init int sel_netif_init(void) return 0; } -__initcall(sel_netif_init); - diff --git a/security/selinux/netlink.c b/security/selinux/netlink.c index 1760aee712fd..eb40e4603475 100644 --- a/security/selinux/netlink.c +++ b/security/selinux/netlink.c @@ -17,6 +17,7 @@ #include <net/net_namespace.h> #include <net/netlink.h> +#include "initcalls.h" #include "security.h" static struct sock *selnl __ro_after_init; @@ -105,7 +106,7 @@ void selnl_notify_policyload(u32 seqno) selnl_notify(SELNL_MSG_POLICYLOAD, &seqno); } -static int __init selnl_init(void) +int __init sel_netlink_init(void) { struct netlink_kernel_cfg cfg = { .groups = SELNLGRP_MAX, @@ -117,5 +118,3 @@ static int __init selnl_init(void) panic("SELinux: Cannot create netlink socket."); return 0; } - -__initcall(selnl_init); diff --git a/security/selinux/netnode.c b/security/selinux/netnode.c index 5c8c77e50aad..11b5eac30641 100644 --- a/security/selinux/netnode.c +++ b/security/selinux/netnode.c @@ -30,6 +30,7 @@ #include <net/ip.h> #include <net/ipv6.h> +#include "initcalls.h" #include "netnode.h" #include "objsec.h" @@ -287,7 +288,7 @@ void sel_netnode_flush(void) spin_unlock_bh(&sel_netnode_lock); } -static __init int sel_netnode_init(void) +int __init sel_netnode_init(void) { int iter; @@ -301,5 +302,3 @@ static __init int sel_netnode_init(void) return 0; } - -__initcall(sel_netnode_init); diff --git a/security/selinux/netport.c b/security/selinux/netport.c index 2e22ad9c2bd0..d1c12f58a628 100644 --- a/security/selinux/netport.c +++ b/security/selinux/netport.c @@ -29,6 +29,7 @@ #include <net/ip.h> #include <net/ipv6.h> +#include "initcalls.h" #include "netport.h" #include "objsec.h" @@ -220,7 +221,7 @@ void sel_netport_flush(void) spin_unlock_bh(&sel_netport_lock); } -static __init int sel_netport_init(void) +int __init sel_netport_init(void) { int iter; @@ -234,5 +235,3 @@ static __init int sel_netport_init(void) return 0; } - -__initcall(sel_netport_init); diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c index 47480eb2189b..88d16c1dbb5a 100644 --- a/security/selinux/selinuxfs.c +++ b/security/selinux/selinuxfs.c @@ -35,6 +35,7 @@ /* selinuxfs pseudo filesystem for exporting the security policy API. Based on the proc code and the fs/nfsd/nfsctl.c code. */ +#include "initcalls.h" #include "flask.h" #include "avc.h" #include "avc_ss.h" @@ -2131,7 +2132,7 @@ static struct file_system_type sel_fs_type = { struct path selinux_null __ro_after_init; -static int __init init_sel_fs(void) +int __init init_sel_fs(void) { struct qstr null_name = QSTR_INIT(NULL_FILE_NAME, sizeof(NULL_FILE_NAME)-1); @@ -2175,5 +2176,3 @@ static int __init init_sel_fs(void) return err; } - -__initcall(init_sel_fs); diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index e431772c6168..d84a496e5f7f 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -3534,6 +3534,13 @@ struct selinux_audit_rule { struct context au_ctxt; }; +int selinux_audit_rule_avc_callback(u32 event) +{ + if (event == AVC_CALLBACK_RESET) + return audit_update_lsm_rules(); + return 0; +} + void selinux_audit_rule_free(void *vrule) { struct selinux_audit_rule *rule = vrule; @@ -3784,25 +3791,6 @@ int selinux_audit_rule_match(struct lsm_prop *prop, u32 field, u32 op, void *vru return match; } -static int aurule_avc_callback(u32 event) -{ - if (event == AVC_CALLBACK_RESET) - return audit_update_lsm_rules(); - return 0; -} - -static int __init aurule_init(void) -{ - int err; - - err = avc_add_callback(aurule_avc_callback, AVC_CALLBACK_RESET); - if (err) - panic("avc_add_callback() failed, error %d\n", err); - - return err; -} -__initcall(aurule_init); - #ifdef CONFIG_NETLABEL /** * security_netlbl_cache_add - Add an entry to the NetLabel cache
SELinux currently has a number of initcalls so we've created a new function, selinux_initcall(), which wraps all of these initcalls so that we have a single initcall function that can be registered with the LSM framework. Signed-off-by: Paul Moore <paul@paul-moore.com> --- security/selinux/Makefile | 2 +- security/selinux/hooks.c | 9 +++-- security/selinux/ibpkey.c | 5 ++- security/selinux/include/audit.h | 5 +++ security/selinux/include/initcalls.h | 19 +++++++++++ security/selinux/initcalls.c | 50 ++++++++++++++++++++++++++++ security/selinux/netif.c | 5 ++- security/selinux/netlink.c | 5 ++- security/selinux/netnode.c | 5 ++- security/selinux/netport.c | 5 ++- security/selinux/selinuxfs.c | 5 ++- security/selinux/ss/services.c | 26 ++++----------- 12 files changed, 101 insertions(+), 40 deletions(-) create mode 100644 security/selinux/include/initcalls.h create mode 100644 security/selinux/initcalls.c