Merge tag 'selinux-pr-20250926' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux

Pull selinux updates from Paul Moore:

 - Support per-file labeling for functionfs

   Both genfscon and user defined labeling methods are supported. This
   should help users who want to provide separation between the control
   endpoint file, "ep0", and other endpoints.

 - Remove our use of get_zeroed_page() in sel_read_bool()

   Update sel_read_bool() to use a four byte stack buffer instead of a
   memory page fetched via get_zeroed_page(), and fix a memory in the
   process.

   Needless to say we should have done this a long time ago, but it was
   in a very old chunk of code that "just worked" and I don't think
   anyone had taken a real look at it in many years.

 - Better use of the netdev skb/sock helper functions

   Convert a sk_to_full_sk(skb->sk) into a skb_to_full_sk(skb) call.

 - Remove some old, dead, and/or redundant code

* tag 'selinux-pr-20250926' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux:
  selinux: enable per-file labeling for functionfs
  selinux: fix sel_read_bool() allocation and error handling
  selinux: Remove redundant __GFP_NOWARN
  selinux: use a consistent method to get full socket from skb
  selinux: Remove unused function selinux_policycap_netif_wildcard()
This commit is contained in:
Linus Torvalds
2025-09-30 08:30:32 -07:00
6 changed files with 22 additions and 25 deletions

View File

@@ -292,27 +292,26 @@ static struct avc_xperms_decision_node
struct avc_xperms_decision_node *xpd_node;
struct extended_perms_decision *xpd;
xpd_node = kmem_cache_zalloc(avc_xperms_decision_cachep,
GFP_NOWAIT | __GFP_NOWARN);
xpd_node = kmem_cache_zalloc(avc_xperms_decision_cachep, GFP_NOWAIT);
if (!xpd_node)
return NULL;
xpd = &xpd_node->xpd;
if (which & XPERMS_ALLOWED) {
xpd->allowed = kmem_cache_zalloc(avc_xperms_data_cachep,
GFP_NOWAIT | __GFP_NOWARN);
GFP_NOWAIT);
if (!xpd->allowed)
goto error;
}
if (which & XPERMS_AUDITALLOW) {
xpd->auditallow = kmem_cache_zalloc(avc_xperms_data_cachep,
GFP_NOWAIT | __GFP_NOWARN);
GFP_NOWAIT);
if (!xpd->auditallow)
goto error;
}
if (which & XPERMS_DONTAUDIT) {
xpd->dontaudit = kmem_cache_zalloc(avc_xperms_data_cachep,
GFP_NOWAIT | __GFP_NOWARN);
GFP_NOWAIT);
if (!xpd->dontaudit)
goto error;
}
@@ -340,7 +339,7 @@ static struct avc_xperms_node *avc_xperms_alloc(void)
{
struct avc_xperms_node *xp_node;
xp_node = kmem_cache_zalloc(avc_xperms_cachep, GFP_NOWAIT | __GFP_NOWARN);
xp_node = kmem_cache_zalloc(avc_xperms_cachep, GFP_NOWAIT);
if (!xp_node)
return xp_node;
INIT_LIST_HEAD(&xp_node->xpd_head);
@@ -495,7 +494,7 @@ static struct avc_node *avc_alloc_node(void)
{
struct avc_node *node;
node = kmem_cache_zalloc(avc_node_cachep, GFP_NOWAIT | __GFP_NOWARN);
node = kmem_cache_zalloc(avc_node_cachep, GFP_NOWAIT);
if (!node)
goto out;

View File

@@ -476,7 +476,9 @@ static int selinux_is_genfs_special_handling(struct super_block *sb)
!strcmp(sb->s_type->name, "rootfs") ||
(selinux_policycap_cgroupseclabel() &&
(!strcmp(sb->s_type->name, "cgroup") ||
!strcmp(sb->s_type->name, "cgroup2")));
!strcmp(sb->s_type->name, "cgroup2"))) ||
(selinux_policycap_functionfs_seclabel() &&
!strcmp(sb->s_type->name, "functionfs"));
}
static int selinux_is_sblabel_mnt(struct super_block *sb)
@@ -741,7 +743,9 @@ static int selinux_set_mnt_opts(struct super_block *sb,
!strcmp(sb->s_type->name, "binder") ||
!strcmp(sb->s_type->name, "bpf") ||
!strcmp(sb->s_type->name, "pstore") ||
!strcmp(sb->s_type->name, "securityfs"))
!strcmp(sb->s_type->name, "securityfs") ||
(selinux_policycap_functionfs_seclabel() &&
!strcmp(sb->s_type->name, "functionfs")))
sbsec->flags |= SE_SBGENFS;
if (!strcmp(sb->s_type->name, "sysfs") ||
@@ -5885,7 +5889,7 @@ static unsigned int selinux_ip_output(void *priv, struct sk_buff *skb,
/* we do this in the LOCAL_OUT path and not the POST_ROUTING path
* because we want to make sure we apply the necessary labeling
* before IPsec is applied so we can leverage AH protection */
sk = sk_to_full_sk(skb->sk);
sk = skb_to_full_sk(skb);
if (sk) {
struct sk_security_struct *sksec;

View File

@@ -17,6 +17,7 @@ enum {
POLICYDB_CAP_NETLINK_XPERM,
POLICYDB_CAP_NETIF_WILDCARD,
POLICYDB_CAP_GENFS_SECLABEL_WILDCARD,
POLICYDB_CAP_FUNCTIONFS_SECLABEL,
__POLICYDB_CAP_MAX
};
#define POLICYDB_CAP_MAX (__POLICYDB_CAP_MAX - 1)

View File

@@ -20,6 +20,7 @@ const char *const selinux_policycap_names[__POLICYDB_CAP_MAX] = {
"netlink_xperm",
"netif_wildcard",
"genfs_seclabel_wildcard",
"functionfs_seclabel",
};
/* clang-format on */

View File

@@ -203,10 +203,10 @@ static inline bool selinux_policycap_netlink_xperm(void)
selinux_state.policycap[POLICYDB_CAP_NETLINK_XPERM]);
}
static inline bool selinux_policycap_netif_wildcard(void)
static inline bool selinux_policycap_functionfs_seclabel(void)
{
return READ_ONCE(
selinux_state.policycap[POLICYDB_CAP_NETIF_WILDCARD]);
selinux_state.policycap[POLICYDB_CAP_FUNCTIONFS_SECLABEL]);
}
struct selinux_policy_convert_data;

View File

@@ -1203,7 +1203,7 @@ static ssize_t sel_read_bool(struct file *filep, char __user *buf,
size_t count, loff_t *ppos)
{
struct selinux_fs_info *fsi = file_inode(filep)->i_sb->s_fs_info;
char *page = NULL;
char buffer[4];
ssize_t length;
ssize_t ret;
int cur_enforcing;
@@ -1217,27 +1217,19 @@ static ssize_t sel_read_bool(struct file *filep, char __user *buf,
fsi->bool_pending_names[index]))
goto out_unlock;
ret = -ENOMEM;
page = (char *)get_zeroed_page(GFP_KERNEL);
if (!page)
goto out_unlock;
cur_enforcing = security_get_bool_value(index);
if (cur_enforcing < 0) {
ret = cur_enforcing;
goto out_unlock;
}
length = scnprintf(page, PAGE_SIZE, "%d %d", cur_enforcing,
fsi->bool_pending_values[index]);
length = scnprintf(buffer, sizeof(buffer), "%d %d", !!cur_enforcing,
!!fsi->bool_pending_values[index]);
mutex_unlock(&selinux_state.policy_mutex);
ret = simple_read_from_buffer(buf, count, ppos, page, length);
out_free:
free_page((unsigned long)page);
return ret;
return simple_read_from_buffer(buf, count, ppos, buffer, length);
out_unlock:
mutex_unlock(&selinux_state.policy_mutex);
goto out_free;
return ret;
}
static ssize_t sel_write_bool(struct file *filep, const char __user *buf,