mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-09-04 20:19:47 +08:00
selinux/stable-6.17 PR 20250725
-----BEGIN PGP SIGNATURE----- iQJIBAABCgAyFiEES0KozwfymdVUl37v6iDy2pc3iXMFAmiD08EUHHBhdWxAcGF1 bC1tb29yZS5jb20ACgkQ6iDy2pc3iXOFzRAAwTbLKcFggDs0bG6AfqT5KCQHRtRW z/0+kvDZeKzJvmJ4XvNMdW3orC2iIYgGCYJgj8umEXh1BOGIOSd4edpGaUKvJB9Z S4py0I3udGjlchInmDBZqW2qGaN0EAl/s0AWBbf6QLYmMV1r9+nb5lH71pVBbEQv 4Vltg61KkQPc6PuDpk7F+BD7yYKSCqxxWyy7zEJsFMntg4jCyoI2PfRhrHM5xuCE RRqctblhCc4nNqzhPvse4Vt9PD+cVQx0Pi7arxvSD8M7mVrFTsUV17OoSKlCcLGh 1LlFk7heoDNC/UQy7xFg5hsy8GeI6gYYY/Fomu7Ue3SYJL2fqqr7xsbJyCCNg8kC S17gRPBxqftzl/2SE76V8y5toIRMtT7b+6aXudtukfFbxtBq09XNflq1G3iR9fTo o6f9MGpyWW3t/e8wk2yPYfXNXrLe3yJoxV6lIsDaHejOwGi098ArcahKKuxNzRit AikIoqn8GEO+j3/X/4YS1xbdS/HkG7N3t+Rbr2GNO4XsmU6iqZRBkmz5UlCcL8u1 OTQNjzqqSy/DKAfrPAyqN7wiBVXt5siBPwAXIcPbh9JfAI/kRN7LUxAQeGnUps+o kJn2zCV3G4kD2qtCVCQ7VifIYGCMxa1PTYsiwu5S4Wgm1Ducvtsx4r3TVKiCuObC bwv/1k9kpkvLy/E= =M55j -----END PGP SIGNATURE----- Merge tag 'selinux-pr-20250725' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux Pull selinux updates from Paul Moore: - Introduce the concept of a SELinux "neveraudit" type which prevents all auditing of the given type/domain. Taken by itself, the benefit of marking a SELinux domain with the "neveraudit" tag is likely not very interesting, especially given the significant overlap with the "dontaudit" tag. However, given that the "neveraudit" tag applies to *all* auditing of the tagged domain, we can do some fairly interesting optimizations when a SELinux domain is marked as both "permissive" and "dontaudit" (think of the unconfined_t domain). While this pull request includes optimized inode permission and getattr hooks, these optimizations require SELinux policy changes, therefore the improvements may not be visible on standard downstream Linux distos for a period of time. - Continue the deprecation process of /sys/fs/selinux/user. After removing the associated userspace code in 2020, we marked the /sys/fs/selinux/user interface as deprecated in Linux v6.13 with pr_warn() and the usual documention update. This adds a five second sleep after the pr_warn(), following a previous deprecation process pattern that has worked well for us in the past in helping identify any existing users that we haven't yet reached. - Add a __GFP_NOWARN flag to our initial hash table allocation. Fuzzers such a syzbot often attempt abnormally large SELinux policy loads, which the SELinux code gracefully handles by checking for allocation failures, but not before the allocator emits a warning which causes the automated fuzzing to flag this as an error and report it to the list. While we want to continue to support the work done by the fuzzing teams, we want to focus on proper issues and not an error case that is already handled safely. Add a NOWARN flag to quiet the allocator and prevent syzbot from tripping on this again. - Remove some unnecessary selinuxfs cleanup code, courtesy of Al. - Update the SELinux in-kernel documentation with pointers to additional information. * tag 'selinux-pr-20250725' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux: selinux: don't bother with selinuxfs_info_free() on failures selinux: add __GFP_NOWARN to hashtab_init() allocations selinux: optimize selinux_inode_getattr/permission() based on neveraudit|permissive selinux: introduce neveraudit types documentation: add links to SELinux resources selinux: add a 5 second sleep to /sys/fs/selinux/user
This commit is contained in:
commit
dffb641bea
@ -2,6 +2,17 @@
|
||||
SELinux
|
||||
=======
|
||||
|
||||
Information about the SELinux kernel subsystem can be found at the
|
||||
following links:
|
||||
|
||||
https://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux.git/tree/README.md
|
||||
|
||||
https://github.com/selinuxproject/selinux-kernel/wiki
|
||||
|
||||
Information about the SELinux userspace can be found at:
|
||||
|
||||
https://github.com/SELinuxProject/selinux/wiki
|
||||
|
||||
If you want to use SELinux, chances are you will want
|
||||
to use the distro-provided policies, or install the
|
||||
latest reference policy release from
|
||||
|
@ -3181,6 +3181,8 @@ static inline void task_avdcache_update(struct task_security_struct *tsec,
|
||||
tsec->avdcache.dir[spot].audited = audited;
|
||||
tsec->avdcache.dir[spot].allowed = avd->allowed;
|
||||
tsec->avdcache.dir[spot].permissive = avd->flags & AVD_FLAGS_PERMISSIVE;
|
||||
tsec->avdcache.permissive_neveraudit =
|
||||
(avd->flags == (AVD_FLAGS_PERMISSIVE|AVD_FLAGS_NEVERAUDIT));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -3207,10 +3209,13 @@ static int selinux_inode_permission(struct inode *inode, int requested)
|
||||
if (!mask)
|
||||
return 0;
|
||||
|
||||
tsec = selinux_cred(current_cred());
|
||||
if (task_avdcache_permnoaudit(tsec))
|
||||
return 0;
|
||||
|
||||
isec = inode_security_rcu(inode, requested & MAY_NOT_BLOCK);
|
||||
if (IS_ERR(isec))
|
||||
return PTR_ERR(isec);
|
||||
tsec = selinux_cred(current_cred());
|
||||
perms = file_mask_to_av(inode->i_mode, mask);
|
||||
|
||||
rc = task_avdcache_search(tsec, isec, &avdc);
|
||||
@ -3274,6 +3279,13 @@ static int selinux_inode_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
|
||||
|
||||
static int selinux_inode_getattr(const struct path *path)
|
||||
{
|
||||
struct task_security_struct *tsec;
|
||||
|
||||
tsec = selinux_cred(current_cred());
|
||||
|
||||
if (task_avdcache_permnoaudit(tsec))
|
||||
return 0;
|
||||
|
||||
return path_has_perm(current_cred(), path, FILE__GETATTR);
|
||||
}
|
||||
|
||||
|
@ -65,6 +65,10 @@ static inline u32 avc_audit_required(u32 requested, struct av_decision *avd,
|
||||
int result, u32 auditdeny, u32 *deniedp)
|
||||
{
|
||||
u32 denied, audited;
|
||||
|
||||
if (avd->flags & AVD_FLAGS_NEVERAUDIT)
|
||||
return 0;
|
||||
|
||||
denied = requested & ~avd->allowed;
|
||||
if (unlikely(denied)) {
|
||||
audited = denied & avd->auditdeny;
|
||||
|
@ -49,9 +49,17 @@ struct task_security_struct {
|
||||
u32 seqno; /* AVC sequence number */
|
||||
unsigned int dir_spot; /* dir cache index to check first */
|
||||
struct avdc_entry dir[TSEC_AVDC_DIR_SIZE]; /* dir entries */
|
||||
bool permissive_neveraudit; /* permissive and neveraudit */
|
||||
} avdcache;
|
||||
} __randomize_layout;
|
||||
|
||||
static inline bool task_avdcache_permnoaudit(struct task_security_struct *tsec)
|
||||
{
|
||||
return (tsec->avdcache.permissive_neveraudit &&
|
||||
tsec->sid == tsec->avdcache.sid &&
|
||||
tsec->avdcache.seqno == avc_policy_seqno());
|
||||
}
|
||||
|
||||
enum label_initialized {
|
||||
LABEL_INVALID, /* invalid or not initialized */
|
||||
LABEL_INITIALIZED, /* initialized */
|
||||
|
@ -47,10 +47,11 @@
|
||||
#define POLICYDB_VERSION_GLBLUB 32
|
||||
#define POLICYDB_VERSION_COMP_FTRANS 33 /* compressed filename transitions */
|
||||
#define POLICYDB_VERSION_COND_XPERMS 34 /* extended permissions in conditional policies */
|
||||
#define POLICYDB_VERSION_NEVERAUDIT 35 /* neveraudit types */
|
||||
|
||||
/* Range of policy versions we understand*/
|
||||
#define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE
|
||||
#define POLICYDB_VERSION_MAX POLICYDB_VERSION_COND_XPERMS
|
||||
#define POLICYDB_VERSION_MAX POLICYDB_VERSION_NEVERAUDIT
|
||||
|
||||
/* Mask for just the mount related flags */
|
||||
#define SE_MNTMASK 0x0f
|
||||
@ -260,6 +261,7 @@ struct extended_perms {
|
||||
|
||||
/* definitions of av_decision.flags */
|
||||
#define AVD_FLAGS_PERMISSIVE 0x0001
|
||||
#define AVD_FLAGS_NEVERAUDIT 0x0002
|
||||
|
||||
void security_compute_av(u32 ssid, u32 tsid, u16 tclass,
|
||||
struct av_decision *avd,
|
||||
|
@ -1072,6 +1072,7 @@ static ssize_t sel_write_user(struct file *file, char *buf, size_t size)
|
||||
pr_warn_ratelimited("SELinux: %s (%d) wrote to /sys/fs/selinux/user!"
|
||||
" This will not be supported in the future; please update your"
|
||||
" userspace.\n", current->comm, current->pid);
|
||||
ssleep(5);
|
||||
|
||||
length = avc_has_perm(current_sid(), SECINITSID_SECURITY,
|
||||
SECCLASS_SECURITY, SECURITY__COMPUTE_USER,
|
||||
@ -2097,8 +2098,6 @@ err:
|
||||
pr_err("SELinux: %s: failed while creating inodes\n",
|
||||
__func__);
|
||||
|
||||
selinux_fs_info_free(sb);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -40,7 +40,8 @@ int hashtab_init(struct hashtab *h, u32 nel_hint)
|
||||
h->htable = NULL;
|
||||
|
||||
if (size) {
|
||||
h->htable = kcalloc(size, sizeof(*h->htable), GFP_KERNEL);
|
||||
h->htable = kcalloc(size, sizeof(*h->htable),
|
||||
GFP_KERNEL | __GFP_NOWARN);
|
||||
if (!h->htable)
|
||||
return -ENOMEM;
|
||||
h->size = size;
|
||||
|
@ -160,6 +160,11 @@ static const struct policydb_compat_info policydb_compat[] = {
|
||||
.sym_num = SYM_NUM,
|
||||
.ocon_num = OCON_NUM,
|
||||
},
|
||||
{
|
||||
.version = POLICYDB_VERSION_NEVERAUDIT,
|
||||
.sym_num = SYM_NUM,
|
||||
.ocon_num = OCON_NUM,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct policydb_compat_info *
|
||||
@ -531,6 +536,7 @@ static void policydb_init(struct policydb *p)
|
||||
ebitmap_init(&p->filename_trans_ttypes);
|
||||
ebitmap_init(&p->policycaps);
|
||||
ebitmap_init(&p->permissive_map);
|
||||
ebitmap_init(&p->neveraudit_map);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -852,6 +858,7 @@ void policydb_destroy(struct policydb *p)
|
||||
ebitmap_destroy(&p->filename_trans_ttypes);
|
||||
ebitmap_destroy(&p->policycaps);
|
||||
ebitmap_destroy(&p->permissive_map);
|
||||
ebitmap_destroy(&p->neveraudit_map);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2538,6 +2545,12 @@ int policydb_read(struct policydb *p, struct policy_file *fp)
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if (p->policyvers >= POLICYDB_VERSION_NEVERAUDIT) {
|
||||
rc = ebitmap_read(&p->neveraudit_map, fp);
|
||||
if (rc)
|
||||
goto bad;
|
||||
}
|
||||
|
||||
rc = -EINVAL;
|
||||
info = policydb_lookup_compat(p->policyvers);
|
||||
if (!info) {
|
||||
@ -3723,6 +3736,12 @@ int policydb_write(struct policydb *p, struct policy_file *fp)
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (p->policyvers >= POLICYDB_VERSION_NEVERAUDIT) {
|
||||
rc = ebitmap_write(&p->neveraudit_map, fp);
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
|
||||
num_syms = info->sym_num;
|
||||
for (i = 0; i < num_syms; i++) {
|
||||
struct policy_data pd;
|
||||
|
@ -300,6 +300,8 @@ struct policydb {
|
||||
|
||||
struct ebitmap permissive_map;
|
||||
|
||||
struct ebitmap neveraudit_map;
|
||||
|
||||
/* length of this policy when it was loaded */
|
||||
size_t len;
|
||||
|
||||
|
@ -1153,6 +1153,14 @@ void security_compute_av(u32 ssid,
|
||||
if (ebitmap_get_bit(&policydb->permissive_map, scontext->type))
|
||||
avd->flags |= AVD_FLAGS_PERMISSIVE;
|
||||
|
||||
/* neveraudit domain? */
|
||||
if (ebitmap_get_bit(&policydb->neveraudit_map, scontext->type))
|
||||
avd->flags |= AVD_FLAGS_NEVERAUDIT;
|
||||
|
||||
/* both permissive and neveraudit => allow */
|
||||
if (avd->flags == (AVD_FLAGS_PERMISSIVE|AVD_FLAGS_NEVERAUDIT))
|
||||
goto allow;
|
||||
|
||||
tcontext = sidtab_search(sidtab, tsid);
|
||||
if (!tcontext) {
|
||||
pr_err("SELinux: %s: unrecognized SID %d\n",
|
||||
@ -1172,6 +1180,8 @@ void security_compute_av(u32 ssid,
|
||||
policydb->allow_unknown);
|
||||
out:
|
||||
rcu_read_unlock();
|
||||
if (avd->flags & AVD_FLAGS_NEVERAUDIT)
|
||||
avd->auditallow = avd->auditdeny = 0;
|
||||
return;
|
||||
allow:
|
||||
avd->allowed = 0xffffffff;
|
||||
@ -1208,6 +1218,14 @@ void security_compute_av_user(u32 ssid,
|
||||
if (ebitmap_get_bit(&policydb->permissive_map, scontext->type))
|
||||
avd->flags |= AVD_FLAGS_PERMISSIVE;
|
||||
|
||||
/* neveraudit domain? */
|
||||
if (ebitmap_get_bit(&policydb->neveraudit_map, scontext->type))
|
||||
avd->flags |= AVD_FLAGS_NEVERAUDIT;
|
||||
|
||||
/* both permissive and neveraudit => allow */
|
||||
if (avd->flags == (AVD_FLAGS_PERMISSIVE|AVD_FLAGS_NEVERAUDIT))
|
||||
goto allow;
|
||||
|
||||
tcontext = sidtab_search(sidtab, tsid);
|
||||
if (!tcontext) {
|
||||
pr_err("SELinux: %s: unrecognized SID %d\n",
|
||||
@ -1225,6 +1243,8 @@ void security_compute_av_user(u32 ssid,
|
||||
NULL);
|
||||
out:
|
||||
rcu_read_unlock();
|
||||
if (avd->flags & AVD_FLAGS_NEVERAUDIT)
|
||||
avd->auditallow = avd->auditdeny = 0;
|
||||
return;
|
||||
allow:
|
||||
avd->allowed = 0xffffffff;
|
||||
|
Loading…
Reference in New Issue
Block a user