Skip to content

Commit ad060db

Browse files
committed
Merge tag 'selinux-pr-20240911' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux
Pull selinux updates from Paul Moore: - Ensure that both IPv4 and IPv6 connections are properly initialized While we always properly initialized IPv4 connections early in their life, we missed the necessary IPv6 change when we were adding IPv6 support. - Annotate the SELinux inode revalidation function to quiet KCSAN KCSAN correctly identifies a race in __inode_security_revalidate() when we check to see if an inode's SELinux has been properly initialized. While KCSAN is correct, it is an intentional choice made for performance reasons; if necessary, we check the state a second time, this time with a lock held, before initializing the inode's state. - Code cleanups, simplification, etc. A handful of individual patches to simplify some SELinux kernel logic, improve return code granularity via ERR_PTR(), follow the guidance on using KMEM_CACHE(), and correct some minor style problems. * tag 'selinux-pr-20240911' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux: selinux: fix style problems in security/selinux/include/audit.h selinux: simplify avc_xperms_audit_required() selinux: mark both IPv4 and IPv6 accepted connection sockets as labeled selinux: replace kmem_cache_create() with KMEM_CACHE() selinux: annotate false positive data race to avoid KCSAN warnings selinux: refactor code to return ERR_PTR in selinux_netlbl_sock_genattr selinux: Streamline type determination in security_compute_sid
2 parents dc644fb + d19a9e2 commit ad060db

File tree

8 files changed

+68
-76
lines changed

8 files changed

+68
-76
lines changed

security/selinux/avc.c

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -134,18 +134,10 @@ static inline u32 avc_hash(u32 ssid, u32 tsid, u16 tclass)
134134
*/
135135
void __init avc_init(void)
136136
{
137-
avc_node_cachep = kmem_cache_create("avc_node", sizeof(struct avc_node),
138-
0, SLAB_PANIC, NULL);
139-
avc_xperms_cachep = kmem_cache_create("avc_xperms_node",
140-
sizeof(struct avc_xperms_node),
141-
0, SLAB_PANIC, NULL);
142-
avc_xperms_decision_cachep = kmem_cache_create(
143-
"avc_xperms_decision_node",
144-
sizeof(struct avc_xperms_decision_node),
145-
0, SLAB_PANIC, NULL);
146-
avc_xperms_data_cachep = kmem_cache_create("avc_xperms_data",
147-
sizeof(struct extended_perms_data),
148-
0, SLAB_PANIC, NULL);
137+
avc_node_cachep = KMEM_CACHE(avc_node, SLAB_PANIC);
138+
avc_xperms_cachep = KMEM_CACHE(avc_xperms_node, SLAB_PANIC);
139+
avc_xperms_decision_cachep = KMEM_CACHE(avc_xperms_decision_node, SLAB_PANIC);
140+
avc_xperms_data_cachep = KMEM_CACHE(extended_perms_data, SLAB_PANIC);
149141
}
150142

151143
int avc_get_hash_stats(char *page)
@@ -396,15 +388,15 @@ static inline u32 avc_xperms_audit_required(u32 requested,
396388
audited = denied & avd->auditdeny;
397389
if (audited && xpd) {
398390
if (avc_xperms_has_perm(xpd, perm, XPERMS_DONTAUDIT))
399-
audited &= ~requested;
391+
audited = 0;
400392
}
401393
} else if (result) {
402394
audited = denied = requested;
403395
} else {
404396
audited = requested & avd->auditallow;
405397
if (audited && xpd) {
406398
if (!avc_xperms_has_perm(xpd, perm, XPERMS_AUDITALLOW))
407-
audited &= ~requested;
399+
audited = 0;
408400
}
409401
}
410402

security/selinux/hooks.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,8 +282,13 @@ static int __inode_security_revalidate(struct inode *inode,
282282

283283
might_sleep_if(may_sleep);
284284

285+
/*
286+
* The check of isec->initialized below is racy but
287+
* inode_doinit_with_dentry() will recheck with
288+
* isec->lock held.
289+
*/
285290
if (selinux_initialized() &&
286-
isec->initialized != LABEL_INITIALIZED) {
291+
data_race(isec->initialized != LABEL_INITIALIZED)) {
287292
if (!may_sleep)
288293
return -ECHILD;
289294

security/selinux/include/audit.h

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -16,45 +16,45 @@
1616
#include <linux/types.h>
1717

1818
/**
19-
* selinux_audit_rule_init - alloc/init an selinux audit rule structure.
20-
* @field: the field this rule refers to
21-
* @op: the operator the rule uses
22-
* @rulestr: the text "target" of the rule
23-
* @rule: pointer to the new rule structure returned via this
24-
* @gfp: GFP flag used for kmalloc
19+
* selinux_audit_rule_init - alloc/init an selinux audit rule structure.
20+
* @field: the field this rule refers to
21+
* @op: the operator the rule uses
22+
* @rulestr: the text "target" of the rule
23+
* @rule: pointer to the new rule structure returned via this
24+
* @gfp: GFP flag used for kmalloc
2525
*
26-
* Returns 0 if successful, -errno if not. On success, the rule structure
27-
* will be allocated internally. The caller must free this structure with
28-
* selinux_audit_rule_free() after use.
26+
* Returns 0 if successful, -errno if not. On success, the rule structure
27+
* will be allocated internally. The caller must free this structure with
28+
* selinux_audit_rule_free() after use.
2929
*/
3030
int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **rule,
3131
gfp_t gfp);
3232

3333
/**
34-
* selinux_audit_rule_free - free an selinux audit rule structure.
35-
* @rule: pointer to the audit rule to be freed
34+
* selinux_audit_rule_free - free an selinux audit rule structure.
35+
* @rule: pointer to the audit rule to be freed
3636
*
37-
* This will free all memory associated with the given rule.
38-
* If @rule is NULL, no operation is performed.
37+
* This will free all memory associated with the given rule.
38+
* If @rule is NULL, no operation is performed.
3939
*/
4040
void selinux_audit_rule_free(void *rule);
4141

4242
/**
43-
* selinux_audit_rule_match - determine if a context ID matches a rule.
44-
* @sid: the context ID to check
45-
* @field: the field this rule refers to
46-
* @op: the operator the rule uses
47-
* @rule: pointer to the audit rule to check against
43+
* selinux_audit_rule_match - determine if a context ID matches a rule.
44+
* @sid: the context ID to check
45+
* @field: the field this rule refers to
46+
* @op: the operator the rule uses
47+
* @rule: pointer to the audit rule to check against
4848
*
49-
* Returns 1 if the context id matches the rule, 0 if it does not, and
50-
* -errno on failure.
49+
* Returns 1 if the context id matches the rule, 0 if it does not, and
50+
* -errno on failure.
5151
*/
5252
int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *rule);
5353

5454
/**
55-
* selinux_audit_rule_known - check to see if rule contains selinux fields.
56-
* @rule: rule to be checked
57-
* Returns 1 if there are selinux fields specified in the rule, 0 otherwise.
55+
* selinux_audit_rule_known - check to see if rule contains selinux fields.
56+
* @rule: rule to be checked
57+
* Returns 1 if there are selinux fields specified in the rule, 0 otherwise.
5858
*/
5959
int selinux_audit_rule_known(struct audit_krule *rule);
6060

security/selinux/netlabel.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ static int selinux_netlbl_sidlookup_cached(struct sk_buff *skb,
6262
* Description:
6363
* Generate the NetLabel security attributes for a socket, making full use of
6464
* the socket's attribute cache. Returns a pointer to the security attributes
65-
* on success, NULL on failure.
65+
* on success, or an ERR_PTR on failure.
6666
*
6767
*/
6868
static struct netlbl_lsm_secattr *selinux_netlbl_sock_genattr(struct sock *sk)
@@ -76,11 +76,12 @@ static struct netlbl_lsm_secattr *selinux_netlbl_sock_genattr(struct sock *sk)
7676

7777
secattr = netlbl_secattr_alloc(GFP_ATOMIC);
7878
if (secattr == NULL)
79-
return NULL;
79+
return ERR_PTR(-ENOMEM);
80+
8081
rc = security_netlbl_sid_to_secattr(sksec->sid, secattr);
8182
if (rc != 0) {
8283
netlbl_secattr_free(secattr);
83-
return NULL;
84+
return ERR_PTR(rc);
8485
}
8586
sksec->nlbl_secattr = secattr;
8687

@@ -358,7 +359,7 @@ void selinux_netlbl_inet_csk_clone(struct sock *sk, u16 family)
358359
{
359360
struct sk_security_struct *sksec = sk->sk_security;
360361

361-
if (family == PF_INET)
362+
if (family == PF_INET || family == PF_INET6)
362363
sksec->nlbl_state = NLBL_LABELED;
363364
else
364365
sksec->nlbl_state = NLBL_UNSET;
@@ -400,8 +401,8 @@ int selinux_netlbl_socket_post_create(struct sock *sk, u16 family)
400401
return 0;
401402

402403
secattr = selinux_netlbl_sock_genattr(sk);
403-
if (secattr == NULL)
404-
return -ENOMEM;
404+
if (IS_ERR(secattr))
405+
return PTR_ERR(secattr);
405406
/* On socket creation, replacement of IP options is safe even if
406407
* the caller does not hold the socket lock.
407408
*/
@@ -561,10 +562,9 @@ static int selinux_netlbl_socket_connect_helper(struct sock *sk,
561562
return rc;
562563
}
563564
secattr = selinux_netlbl_sock_genattr(sk);
564-
if (secattr == NULL) {
565-
rc = -ENOMEM;
566-
return rc;
567-
}
565+
if (IS_ERR(secattr))
566+
return PTR_ERR(secattr);
567+
568568
rc = netlbl_conn_setattr(sk, addr, secattr);
569569
if (rc == 0)
570570
sksec->nlbl_state = NLBL_CONNLABELED;

security/selinux/ss/avtab.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -604,9 +604,6 @@ int avtab_write(struct policydb *p, struct avtab *a, void *fp)
604604

605605
void __init avtab_cache_init(void)
606606
{
607-
avtab_node_cachep = kmem_cache_create(
608-
"avtab_node", sizeof(struct avtab_node), 0, SLAB_PANIC, NULL);
609-
avtab_xperms_cachep = kmem_cache_create(
610-
"avtab_extended_perms", sizeof(struct avtab_extended_perms), 0,
611-
SLAB_PANIC, NULL);
607+
avtab_node_cachep = KMEM_CACHE(avtab_node, SLAB_PANIC);
608+
avtab_xperms_cachep = KMEM_CACHE(avtab_extended_perms, SLAB_PANIC);
612609
}

security/selinux/ss/ebitmap.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -572,7 +572,5 @@ u32 ebitmap_hash(const struct ebitmap *e, u32 hash)
572572

573573
void __init ebitmap_cache_init(void)
574574
{
575-
ebitmap_node_cachep = kmem_cache_create("ebitmap_node",
576-
sizeof(struct ebitmap_node), 0,
577-
SLAB_PANIC, NULL);
575+
ebitmap_node_cachep = KMEM_CACHE(ebitmap_node, SLAB_PANIC);
578576
}

security/selinux/ss/hashtab.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,5 @@ int hashtab_duplicate(struct hashtab *new, const struct hashtab *orig,
194194

195195
void __init hashtab_cache_init(void)
196196
{
197-
hashtab_node_cachep = kmem_cache_create("hashtab_node",
198-
sizeof(struct hashtab_node), 0,
199-
SLAB_PANIC, NULL);
197+
hashtab_node_cachep = KMEM_CACHE(hashtab_node, SLAB_PANIC);
200198
}

security/selinux/ss/services.c

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1804,22 +1804,9 @@ static int security_compute_sid(u32 ssid,
18041804
newcontext.role = OBJECT_R_VAL;
18051805
}
18061806

1807-
/* Set the type to default values. */
1808-
if (cladatum && cladatum->default_type == DEFAULT_SOURCE) {
1809-
newcontext.type = scontext->type;
1810-
} else if (cladatum && cladatum->default_type == DEFAULT_TARGET) {
1811-
newcontext.type = tcontext->type;
1812-
} else {
1813-
if ((tclass == policydb->process_class) || sock) {
1814-
/* Use the type of process. */
1815-
newcontext.type = scontext->type;
1816-
} else {
1817-
/* Use the type of the related object. */
1818-
newcontext.type = tcontext->type;
1819-
}
1820-
}
1821-
1822-
/* Look for a type transition/member/change rule. */
1807+
/* Set the type.
1808+
* Look for a type transition/member/change rule.
1809+
*/
18231810
avkey.source_type = scontext->type;
18241811
avkey.target_type = tcontext->type;
18251812
avkey.target_class = tclass;
@@ -1837,9 +1824,24 @@ static int security_compute_sid(u32 ssid,
18371824
}
18381825
}
18391826

1827+
/* If a permanent rule is found, use the type from
1828+
* the type transition/member/change rule. Otherwise,
1829+
* set the type to its default values.
1830+
*/
18401831
if (avnode) {
1841-
/* Use the type from the type transition/member/change rule. */
18421832
newcontext.type = avnode->datum.u.data;
1833+
} else if (cladatum && cladatum->default_type == DEFAULT_SOURCE) {
1834+
newcontext.type = scontext->type;
1835+
} else if (cladatum && cladatum->default_type == DEFAULT_TARGET) {
1836+
newcontext.type = tcontext->type;
1837+
} else {
1838+
if ((tclass == policydb->process_class) || sock) {
1839+
/* Use the type of process. */
1840+
newcontext.type = scontext->type;
1841+
} else {
1842+
/* Use the type of the related object. */
1843+
newcontext.type = tcontext->type;
1844+
}
18431845
}
18441846

18451847
/* if we have a objname this is a file trans check so check those rules */

0 commit comments

Comments
 (0)