Skip to content

Commit 59c017c

Browse files
committed
Merge tag 'selinux-pr-20250323' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux
Pull selinux updates from Paul Moore: - Add additional SELinux access controls for kernel file reads/loads The SELinux kernel file read/load access controls were never updated beyond the initial kernel module support, this pull request adds support for firmware, kexec, policies, and x.509 certificates. - Add support for wildcards in network interface names There are a number of userspace tools which auto-generate network interface names using some pattern of <XXXX>-<NN> where <XXXX> is a fixed string, e.g. "podman", and <NN> is a increasing counter. Supporting wildcards in the SELinux policy for network interfaces simplifies the policy associted with these interfaces. - Fix a potential problem in the kernel read file SELinux code SELinux should always check the file label in the security_kernel_read_file() LSM hook, regardless of if the file is being read in chunks. Unfortunately, the existing code only considered the file label on the first chunk; this pull request fixes this problem. There is more detail in the individual commit, but thankfully the existing code didn't expose a bug due to multi-stage reads only taking place in one driver, and that driver loading a file type that isn't targeted by the SELinux policy. - Fix the subshell error handling in the example policy loader Minor fix to SELinux example policy loader in scripts/selinux due to an undesired interaction with subshells and errexit. * tag 'selinux-pr-20250323' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux: selinux: get netif_wildcard policycap from policy instead of cache selinux: support wildcard network interface names selinux: Chain up tool resolving errors in install_policy.sh selinux: add permission checks for loading other kinds of kernel files selinux: always check the file label in selinux_kernel_read_file() selinux: fix spelling error
2 parents 0545702 + a3d3043 commit 59c017c

File tree

8 files changed

+79
-25
lines changed

8 files changed

+79
-25
lines changed

scripts/selinux/install_policy.sh

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,27 +6,24 @@ if [ `id -u` -ne 0 ]; then
66
exit 1
77
fi
88

9-
SF=`which setfiles`
10-
if [ $? -eq 1 ]; then
9+
SF=`which setfiles` || {
1110
echo "Could not find setfiles"
1211
echo "Do you have policycoreutils installed?"
1312
exit 1
14-
fi
13+
}
1514

16-
CP=`which checkpolicy`
17-
if [ $? -eq 1 ]; then
15+
CP=`which checkpolicy` || {
1816
echo "Could not find checkpolicy"
1917
echo "Do you have checkpolicy installed?"
2018
exit 1
21-
fi
19+
}
2220
VERS=`$CP -V | awk '{print $1}'`
2321

24-
ENABLED=`which selinuxenabled`
25-
if [ $? -eq 1 ]; then
22+
ENABLED=`which selinuxenabled` || {
2623
echo "Could not find selinuxenabled"
2724
echo "Do you have libselinux-utils installed?"
2825
exit 1
29-
fi
26+
}
3027

3128
if selinuxenabled; then
3229
echo "SELinux is already enabled"

security/selinux/avc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -936,7 +936,7 @@ static void avc_flush(void)
936936

937937
spin_lock_irqsave(lock, flag);
938938
/*
939-
* With preemptable RCU, the outer spinlock does not
939+
* With preemptible RCU, the outer spinlock does not
940940
* prevent RCU grace periods from ending.
941941
*/
942942
rcu_read_lock();

security/selinux/hooks.c

Lines changed: 48 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4099,20 +4099,16 @@ static int selinux_kernel_module_request(char *kmod_name)
40994099
SYSTEM__MODULE_REQUEST, &ad);
41004100
}
41014101

4102-
static int selinux_kernel_module_from_file(struct file *file)
4102+
static int selinux_kernel_load_from_file(struct file *file, u32 requested)
41034103
{
41044104
struct common_audit_data ad;
41054105
struct inode_security_struct *isec;
41064106
struct file_security_struct *fsec;
41074107
u32 sid = current_sid();
41084108
int rc;
41094109

4110-
/* init_module */
41114110
if (file == NULL)
4112-
return avc_has_perm(sid, sid, SECCLASS_SYSTEM,
4113-
SYSTEM__MODULE_LOAD, NULL);
4114-
4115-
/* finit_module */
4111+
return avc_has_perm(sid, sid, SECCLASS_SYSTEM, requested, NULL);
41164112

41174113
ad.type = LSM_AUDIT_DATA_FILE;
41184114
ad.u.file = file;
@@ -4125,8 +4121,7 @@ static int selinux_kernel_module_from_file(struct file *file)
41254121
}
41264122

41274123
isec = inode_security(file_inode(file));
4128-
return avc_has_perm(sid, isec->sid, SECCLASS_SYSTEM,
4129-
SYSTEM__MODULE_LOAD, &ad);
4124+
return avc_has_perm(sid, isec->sid, SECCLASS_SYSTEM, requested, &ad);
41304125
}
41314126

41324127
static int selinux_kernel_read_file(struct file *file,
@@ -4135,9 +4130,30 @@ static int selinux_kernel_read_file(struct file *file,
41354130
{
41364131
int rc = 0;
41374132

4133+
BUILD_BUG_ON_MSG(READING_MAX_ID > 7,
4134+
"New kernel_read_file_id introduced; update SELinux!");
4135+
41384136
switch (id) {
4137+
case READING_FIRMWARE:
4138+
rc = selinux_kernel_load_from_file(file, SYSTEM__FIRMWARE_LOAD);
4139+
break;
41394140
case READING_MODULE:
4140-
rc = selinux_kernel_module_from_file(contents ? file : NULL);
4141+
rc = selinux_kernel_load_from_file(file, SYSTEM__MODULE_LOAD);
4142+
break;
4143+
case READING_KEXEC_IMAGE:
4144+
rc = selinux_kernel_load_from_file(file,
4145+
SYSTEM__KEXEC_IMAGE_LOAD);
4146+
break;
4147+
case READING_KEXEC_INITRAMFS:
4148+
rc = selinux_kernel_load_from_file(file,
4149+
SYSTEM__KEXEC_INITRAMFS_LOAD);
4150+
break;
4151+
case READING_POLICY:
4152+
rc = selinux_kernel_load_from_file(file, SYSTEM__POLICY_LOAD);
4153+
break;
4154+
case READING_X509_CERTIFICATE:
4155+
rc = selinux_kernel_load_from_file(file,
4156+
SYSTEM__X509_CERTIFICATE_LOAD);
41414157
break;
41424158
default:
41434159
break;
@@ -4150,9 +4166,31 @@ static int selinux_kernel_load_data(enum kernel_load_data_id id, bool contents)
41504166
{
41514167
int rc = 0;
41524168

4169+
BUILD_BUG_ON_MSG(LOADING_MAX_ID > 7,
4170+
"New kernel_load_data_id introduced; update SELinux!");
4171+
41534172
switch (id) {
4173+
case LOADING_FIRMWARE:
4174+
rc = selinux_kernel_load_from_file(NULL, SYSTEM__FIRMWARE_LOAD);
4175+
break;
41544176
case LOADING_MODULE:
4155-
rc = selinux_kernel_module_from_file(NULL);
4177+
rc = selinux_kernel_load_from_file(NULL, SYSTEM__MODULE_LOAD);
4178+
break;
4179+
case LOADING_KEXEC_IMAGE:
4180+
rc = selinux_kernel_load_from_file(NULL,
4181+
SYSTEM__KEXEC_IMAGE_LOAD);
4182+
break;
4183+
case LOADING_KEXEC_INITRAMFS:
4184+
rc = selinux_kernel_load_from_file(NULL,
4185+
SYSTEM__KEXEC_INITRAMFS_LOAD);
4186+
break;
4187+
case LOADING_POLICY:
4188+
rc = selinux_kernel_load_from_file(NULL,
4189+
SYSTEM__POLICY_LOAD);
4190+
break;
4191+
case LOADING_X509_CERTIFICATE:
4192+
rc = selinux_kernel_load_from_file(NULL,
4193+
SYSTEM__X509_CERTIFICATE_LOAD);
41564194
break;
41574195
default:
41584196
break;

security/selinux/include/classmap.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,9 @@ const struct security_class_mapping secclass_map[] = {
6363
{ "process2", { "nnp_transition", "nosuid_transition", NULL } },
6464
{ "system",
6565
{ "ipc_info", "syslog_read", "syslog_mod", "syslog_console",
66-
"module_request", "module_load", NULL } },
66+
"module_request", "module_load", "firmware_load",
67+
"kexec_image_load", "kexec_initramfs_load", "policy_load",
68+
"x509_certificate_load", NULL } },
6769
{ "capability", { COMMON_CAP_PERMS, NULL } },
6870
{ "filesystem",
6971
{ "mount", "remount", "unmount", "getattr", "relabelfrom",

security/selinux/include/policycap.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ enum {
1515
POLICYDB_CAP_IOCTL_SKIP_CLOEXEC,
1616
POLICYDB_CAP_USERSPACE_INITIAL_CONTEXT,
1717
POLICYDB_CAP_NETLINK_XPERM,
18+
POLICYDB_CAP_NETIF_WILDCARD,
1819
__POLICYDB_CAP_MAX
1920
};
2021
#define POLICYDB_CAP_MAX (__POLICYDB_CAP_MAX - 1)

security/selinux/include/policycap_names.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ const char *const selinux_policycap_names[__POLICYDB_CAP_MAX] = {
1818
"ioctl_skip_cloexec",
1919
"userspace_initial_context",
2020
"netlink_xperm",
21+
"netif_wildcard",
2122
};
2223
/* clang-format on */
2324

security/selinux/include/security.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,12 @@ static inline bool selinux_policycap_netlink_xperm(void)
202202
selinux_state.policycap[POLICYDB_CAP_NETLINK_XPERM]);
203203
}
204204

205+
static inline bool selinux_policycap_netif_wildcard(void)
206+
{
207+
return READ_ONCE(
208+
selinux_state.policycap[POLICYDB_CAP_NETIF_WILDCARD]);
209+
}
210+
205211
struct selinux_policy_convert_data;
206212

207213
struct selinux_load_state {
@@ -301,7 +307,7 @@ int security_ib_pkey_sid(u64 subnet_prefix, u16 pkey_num, u32 *out_sid);
301307

302308
int security_ib_endport_sid(const char *dev_name, u8 port_num, u32 *out_sid);
303309

304-
int security_netif_sid(char *name, u32 *if_sid);
310+
int security_netif_sid(const char *name, u32 *if_sid);
305311

306312
int security_node_sid(u16 domain, void *addr, u32 addrlen, u32 *out_sid);
307313

security/selinux/ss/services.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
#include <linux/in.h>
4747
#include <linux/sched.h>
4848
#include <linux/audit.h>
49+
#include <linux/parser.h>
4950
#include <linux/vmalloc.h>
5051
#include <linux/lsm_hooks.h>
5152
#include <net/netlabel.h>
@@ -2572,13 +2573,14 @@ int security_ib_endport_sid(const char *dev_name, u8 port_num, u32 *out_sid)
25722573
* @name: interface name
25732574
* @if_sid: interface SID
25742575
*/
2575-
int security_netif_sid(char *name, u32 *if_sid)
2576+
int security_netif_sid(const char *name, u32 *if_sid)
25762577
{
25772578
struct selinux_policy *policy;
25782579
struct policydb *policydb;
25792580
struct sidtab *sidtab;
25802581
int rc;
25812582
struct ocontext *c;
2583+
bool wildcard_support;
25822584

25832585
if (!selinux_initialized()) {
25842586
*if_sid = SECINITSID_NETIF;
@@ -2591,11 +2593,18 @@ int security_netif_sid(char *name, u32 *if_sid)
25912593
policy = rcu_dereference(selinux_state.policy);
25922594
policydb = &policy->policydb;
25932595
sidtab = policy->sidtab;
2596+
wildcard_support = ebitmap_get_bit(&policydb->policycaps, POLICYDB_CAP_NETIF_WILDCARD);
25942597

25952598
c = policydb->ocontexts[OCON_NETIF];
25962599
while (c) {
2597-
if (strcmp(name, c->u.name) == 0)
2598-
break;
2600+
if (wildcard_support) {
2601+
if (match_wildcard(c->u.name, name))
2602+
break;
2603+
} else {
2604+
if (strcmp(c->u.name, name) == 0)
2605+
break;
2606+
}
2607+
25992608
c = c->next;
26002609
}
26012610

0 commit comments

Comments
 (0)