Skip to content

Commit 729b39e

Browse files
committed
Merge tag 'selinux-pr-20230626' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux
Pull selinux updates from Paul Moore: - Thanks to help from the MPTCP folks, it looks like we have finally sorted out a proper solution to the MPTCP socket labeling issue, see the new security_mptcp_add_subflow() LSM hook. - Fix the labeled NFS handling such that a labeled NFS share mounted prior to the initial SELinux policy load is properly labeled once a policy is loaded; more information in the commit description. - Two patches to security/selinux/Makefile, the first took the cleanups in v6.4 a bit further and the second removed the grouped targets support as that functionality doesn't appear to be properly supported prior to make v4.3. - Deprecate the "fs" object context type in SELinux policies. The fs object context type was an old vestige that was introduced back in v2.6.12-rc2 but never really used. - A number of small changes that remove dead code, clean up some awkward bits, and generally improve the quality of the code. See the individual commit descriptions for more information. * tag 'selinux-pr-20230626' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux: selinux: avoid bool as identifier name selinux: fix Makefile for versions of make < v4.3 selinux: make labeled NFS work when mounted before policy load selinux: cleanup exit_sel_fs() declaration selinux: deprecated fs ocon selinux: make header files self-including selinux: keep context struct members in sync selinux: Implement mptcp_add_subflow hook security, lsm: Introduce security_mptcp_add_subflow() selinux: small cleanups in selinux_audit_rule_init() selinux: declare read-only data arrays const selinux: retain const qualifier on string literal in avtab_hash_eval() selinux: drop return at end of void function avc_insert() selinux: avc: drop unused function avc_disable() selinux: adjust typos in comments selinux: do not leave dangling pointer behind selinux: more Makefile tweaks
2 parents cae7202 + 447a568 commit 729b39e

24 files changed

Lines changed: 157 additions & 92 deletions

include/linux/lsm_hook_defs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,7 @@ LSM_HOOK(void, LSM_RET_VOID, sctp_sk_clone, struct sctp_association *asoc,
343343
struct sock *sk, struct sock *newsk)
344344
LSM_HOOK(int, 0, sctp_assoc_established, struct sctp_association *asoc,
345345
struct sk_buff *skb)
346+
LSM_HOOK(int, 0, mptcp_add_subflow, struct sock *sk, struct sock *ssk)
346347
#endif /* CONFIG_SECURITY_NETWORK */
347348

348349
#ifdef CONFIG_SECURITY_INFINIBAND

include/linux/security.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1465,6 +1465,7 @@ void security_sctp_sk_clone(struct sctp_association *asoc, struct sock *sk,
14651465
struct sock *newsk);
14661466
int security_sctp_assoc_established(struct sctp_association *asoc,
14671467
struct sk_buff *skb);
1468+
int security_mptcp_add_subflow(struct sock *sk, struct sock *ssk);
14681469

14691470
#else /* CONFIG_SECURITY_NETWORK */
14701471
static inline int security_unix_stream_connect(struct sock *sock,
@@ -1692,6 +1693,11 @@ static inline int security_sctp_assoc_established(struct sctp_association *asoc,
16921693
{
16931694
return 0;
16941695
}
1696+
1697+
static inline int security_mptcp_add_subflow(struct sock *sk, struct sock *ssk)
1698+
{
1699+
return 0;
1700+
}
16951701
#endif /* CONFIG_SECURITY_NETWORK */
16961702

16971703
#ifdef CONFIG_SECURITY_INFINIBAND

net/mptcp/subflow.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1668,6 +1668,10 @@ int mptcp_subflow_create_socket(struct sock *sk, unsigned short family,
16681668

16691669
lock_sock_nested(sf->sk, SINGLE_DEPTH_NESTING);
16701670

1671+
err = security_mptcp_add_subflow(sk, sf->sk);
1672+
if (err)
1673+
goto release_ssk;
1674+
16711675
/* the newly created socket has to be in the same cgroup as its parent */
16721676
mptcp_attach_cgroup(sk, sf->sk);
16731677

@@ -1680,6 +1684,8 @@ int mptcp_subflow_create_socket(struct sock *sk, unsigned short family,
16801684
get_net_track(net, &sf->sk->ns_tracker, GFP_KERNEL);
16811685
sock_inuse_add(net, 1);
16821686
err = tcp_set_ulp(sf->sk, "mptcp");
1687+
1688+
release_ssk:
16831689
release_sock(sf->sk);
16841690

16851691
if (err) {

security/security.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4667,6 +4667,23 @@ int security_sctp_assoc_established(struct sctp_association *asoc,
46674667
}
46684668
EXPORT_SYMBOL(security_sctp_assoc_established);
46694669

4670+
/**
4671+
* security_mptcp_add_subflow() - Inherit the LSM label from the MPTCP socket
4672+
* @sk: the owning MPTCP socket
4673+
* @ssk: the new subflow
4674+
*
4675+
* Update the labeling for the given MPTCP subflow, to match the one of the
4676+
* owning MPTCP socket. This hook has to be called after the socket creation and
4677+
* initialization via the security_socket_create() and
4678+
* security_socket_post_create() LSM hooks.
4679+
*
4680+
* Return: Returns 0 on success or a negative error code on failure.
4681+
*/
4682+
int security_mptcp_add_subflow(struct sock *sk, struct sock *ssk)
4683+
{
4684+
return call_int_hook(mptcp_add_subflow, 0, sk, ssk);
4685+
}
4686+
46704687
#endif /* CONFIG_SECURITY_NETWORK */
46714688

46724689
#ifdef CONFIG_SECURITY_INFINIBAND

security/selinux/Makefile

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,32 +3,38 @@
33
# Makefile for building the SELinux module as part of the kernel tree.
44
#
55

6+
# NOTE: There are a number of improvements that can be made to this Makefile
7+
# once the kernel requires make v4.3 or greater; the most important feature
8+
# lacking in older versions of make is support for grouped targets. These
9+
# improvements are noted inline in the Makefile below ...
10+
611
obj-$(CONFIG_SECURITY_SELINUX) := selinux.o
712

13+
ccflags-y := -I$(srctree)/security/selinux -I$(srctree)/security/selinux/include
14+
815
selinux-y := avc.o hooks.o selinuxfs.o netlink.o nlmsgtab.o netif.o \
916
netnode.o netport.o status.o \
1017
ss/ebitmap.o ss/hashtab.o ss/symtab.o ss/sidtab.o ss/avtab.o \
1118
ss/policydb.o ss/services.o ss/conditional.o ss/mls.o ss/context.o
1219

1320
selinux-$(CONFIG_SECURITY_NETWORK_XFRM) += xfrm.o
14-
1521
selinux-$(CONFIG_NETLABEL) += netlabel.o
16-
1722
selinux-$(CONFIG_SECURITY_INFINIBAND) += ibpkey.o
18-
1923
selinux-$(CONFIG_IMA) += ima.o
2024

21-
ccflags-y := -I$(srctree)/security/selinux -I$(srctree)/security/selinux/include
25+
genhdrs := flask.h av_permissions.h
2226

27+
# see the note above, replace the dependency rule with the one below:
28+
# $(addprefix $(obj)/,$(selinux-y)): $(addprefix $(obj)/,$(genhdrs))
2329
$(addprefix $(obj)/,$(selinux-y)): $(obj)/flask.h
2430

25-
quiet_cmd_flask = GEN $(obj)/flask.h $(obj)/av_permissions.h
26-
cmd_flask = $< $(obj)/flask.h $(obj)/av_permissions.h
31+
quiet_cmd_genhdrs = GEN $(addprefix $(obj)/,$(genhdrs))
32+
cmd_genhdrs = $< $(addprefix $(obj)/,$(genhdrs))
2733

28-
targets += flask.h av_permissions.h
29-
# once make >= 4.3 is required, we can use grouped targets in the rule below,
30-
# which basically involves adding both headers and a '&' before the colon, see
31-
# the example below:
32-
# $(obj)/flask.h $(obj)/av_permissions.h &: scripts/selinux/...
34+
# see the note above, replace the $targets and 'flask.h' rule with the lines
35+
# below:
36+
# targets += $(genhdrs)
37+
# $(addprefix $(obj)/,$(genhdrs)) &: scripts/selinux/...
38+
targets += flask.h
3339
$(obj)/flask.h: scripts/selinux/genheaders/genheaders FORCE
34-
$(call if_changed,flask)
40+
$(call if_changed,genhdrs)

security/selinux/avc.c

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -642,7 +642,6 @@ static void avc_insert(u32 ssid, u32 tsid, u16 tclass,
642642
hlist_add_head_rcu(&node->list, head);
643643
found:
644644
spin_unlock_irqrestore(lock, flag);
645-
return;
646645
}
647646

648647
/**
@@ -1203,22 +1202,3 @@ u32 avc_policy_seqno(void)
12031202
{
12041203
return selinux_avc.avc_cache.latest_notif;
12051204
}
1206-
1207-
void avc_disable(void)
1208-
{
1209-
/*
1210-
* If you are looking at this because you have realized that we are
1211-
* not destroying the avc_node_cachep it might be easy to fix, but
1212-
* I don't know the memory barrier semantics well enough to know. It's
1213-
* possible that some other task dereferenced security_ops when
1214-
* it still pointed to selinux operations. If that is the case it's
1215-
* possible that it is about to use the avc and is about to need the
1216-
* avc_node_cachep. I know I could wrap the security.c security_ops call
1217-
* in an rcu_lock, but seriously, it's not worth it. Instead I just flush
1218-
* the cache and get that memory back.
1219-
*/
1220-
if (avc_node_cachep) {
1221-
avc_flush();
1222-
/* kmem_cache_destroy(avc_node_cachep); */
1223-
}
1224-
}

security/selinux/hooks.c

Lines changed: 59 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,7 @@ enum {
357357
};
358358

359359
#define A(s, has_arg) {#s, sizeof(#s) - 1, Opt_##s, has_arg}
360-
static struct {
360+
static const struct {
361361
const char *name;
362362
int len;
363363
int opt;
@@ -605,26 +605,31 @@ static int selinux_set_mnt_opts(struct super_block *sb,
605605
u32 defcontext_sid = 0;
606606
int rc = 0;
607607

608+
/*
609+
* Specifying internal flags without providing a place to
610+
* place the results is not allowed
611+
*/
612+
if (kern_flags && !set_kern_flags)
613+
return -EINVAL;
614+
608615
mutex_lock(&sbsec->lock);
609616

610617
if (!selinux_initialized()) {
611618
if (!opts) {
612619
/* Defer initialization until selinux_complete_init,
613620
after the initial policy is loaded and the security
614621
server is ready to handle calls. */
622+
if (kern_flags & SECURITY_LSM_NATIVE_LABELS) {
623+
sbsec->flags |= SE_SBNATIVE;
624+
*set_kern_flags |= SECURITY_LSM_NATIVE_LABELS;
625+
}
615626
goto out;
616627
}
617628
rc = -EINVAL;
618629
pr_warn("SELinux: Unable to set superblock options "
619630
"before the security server is initialized\n");
620631
goto out;
621632
}
622-
if (kern_flags && !set_kern_flags) {
623-
/* Specifying internal flags without providing a place to
624-
* place the results is not allowed */
625-
rc = -EINVAL;
626-
goto out;
627-
}
628633

629634
/*
630635
* Binary mount data FS will come through this function twice. Once
@@ -757,7 +762,17 @@ static int selinux_set_mnt_opts(struct super_block *sb,
757762
* sets the label used on all file below the mountpoint, and will set
758763
* the superblock context if not already set.
759764
*/
760-
if (kern_flags & SECURITY_LSM_NATIVE_LABELS && !context_sid) {
765+
if (sbsec->flags & SE_SBNATIVE) {
766+
/*
767+
* This means we are initializing a superblock that has been
768+
* mounted before the SELinux was initialized and the
769+
* filesystem requested native labeling. We had already
770+
* returned SECURITY_LSM_NATIVE_LABELS in *set_kern_flags
771+
* in the original mount attempt, so now we just need to set
772+
* the SECURITY_FS_USE_NATIVE behavior.
773+
*/
774+
sbsec->behavior = SECURITY_FS_USE_NATIVE;
775+
} else if (kern_flags & SECURITY_LSM_NATIVE_LABELS && !context_sid) {
761776
sbsec->behavior = SECURITY_FS_USE_NATIVE;
762777
*set_kern_flags |= SECURITY_LSM_NATIVE_LABELS;
763778
}
@@ -868,32 +883,38 @@ static int selinux_sb_clone_mnt_opts(const struct super_block *oldsb,
868883
int set_context = (oldsbsec->flags & CONTEXT_MNT);
869884
int set_rootcontext = (oldsbsec->flags & ROOTCONTEXT_MNT);
870885

871-
/*
872-
* if the parent was able to be mounted it clearly had no special lsm
873-
* mount options. thus we can safely deal with this superblock later
874-
*/
875-
if (!selinux_initialized())
876-
return 0;
877-
878886
/*
879887
* Specifying internal flags without providing a place to
880888
* place the results is not allowed.
881889
*/
882890
if (kern_flags && !set_kern_flags)
883891
return -EINVAL;
884892

893+
mutex_lock(&newsbsec->lock);
894+
895+
/*
896+
* if the parent was able to be mounted it clearly had no special lsm
897+
* mount options. thus we can safely deal with this superblock later
898+
*/
899+
if (!selinux_initialized()) {
900+
if (kern_flags & SECURITY_LSM_NATIVE_LABELS) {
901+
newsbsec->flags |= SE_SBNATIVE;
902+
*set_kern_flags |= SECURITY_LSM_NATIVE_LABELS;
903+
}
904+
goto out;
905+
}
906+
885907
/* how can we clone if the old one wasn't set up?? */
886908
BUG_ON(!(oldsbsec->flags & SE_SBINITIALIZED));
887909

888910
/* if fs is reusing a sb, make sure that the contexts match */
889911
if (newsbsec->flags & SE_SBINITIALIZED) {
912+
mutex_unlock(&newsbsec->lock);
890913
if ((kern_flags & SECURITY_LSM_NATIVE_LABELS) && !set_context)
891914
*set_kern_flags |= SECURITY_LSM_NATIVE_LABELS;
892915
return selinux_cmp_sb_context(oldsb, newsb);
893916
}
894917

895-
mutex_lock(&newsbsec->lock);
896-
897918
newsbsec->flags = oldsbsec->flags;
898919

899920
newsbsec->sid = oldsbsec->sid;
@@ -937,7 +958,7 @@ static int selinux_sb_clone_mnt_opts(const struct super_block *oldsb,
937958
}
938959

939960
/*
940-
* NOTE: the caller is resposible for freeing the memory even if on error.
961+
* NOTE: the caller is responsible for freeing the memory even if on error.
941962
*/
942963
static int selinux_add_opt(int token, const char *s, void **mnt_opts)
943964
{
@@ -1394,8 +1415,11 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
13941415
spin_unlock(&isec->lock);
13951416

13961417
switch (sbsec->behavior) {
1418+
/*
1419+
* In case of SECURITY_FS_USE_NATIVE we need to re-fetch the labels
1420+
* via xattr when called from delayed_superblock_init().
1421+
*/
13971422
case SECURITY_FS_USE_NATIVE:
1398-
break;
13991423
case SECURITY_FS_USE_XATTR:
14001424
if (!(inode->i_opflags & IOP_XATTR)) {
14011425
sid = sbsec->def_sid;
@@ -5379,6 +5403,21 @@ static void selinux_sctp_sk_clone(struct sctp_association *asoc, struct sock *sk
53795403
selinux_netlbl_sctp_sk_clone(sk, newsk);
53805404
}
53815405

5406+
static int selinux_mptcp_add_subflow(struct sock *sk, struct sock *ssk)
5407+
{
5408+
struct sk_security_struct *ssksec = ssk->sk_security;
5409+
struct sk_security_struct *sksec = sk->sk_security;
5410+
5411+
ssksec->sclass = sksec->sclass;
5412+
ssksec->sid = sksec->sid;
5413+
5414+
/* replace the existing subflow label deleting the existing one
5415+
* and re-recreating a new label using the updated context
5416+
*/
5417+
selinux_netlbl_sk_security_free(ssksec);
5418+
return selinux_netlbl_socket_post_create(ssk, ssk->sk_family);
5419+
}
5420+
53825421
static int selinux_inet_conn_request(const struct sock *sk, struct sk_buff *skb,
53835422
struct request_sock *req)
53845423
{
@@ -7074,6 +7113,7 @@ static struct security_hook_list selinux_hooks[] __ro_after_init = {
70747113
LSM_HOOK_INIT(sctp_sk_clone, selinux_sctp_sk_clone),
70757114
LSM_HOOK_INIT(sctp_bind_connect, selinux_sctp_bind_connect),
70767115
LSM_HOOK_INIT(sctp_assoc_established, selinux_sctp_assoc_established),
7116+
LSM_HOOK_INIT(mptcp_add_subflow, selinux_mptcp_add_subflow),
70777117
LSM_HOOK_INIT(inet_conn_request, selinux_inet_conn_request),
70787118
LSM_HOOK_INIT(inet_csk_clone, selinux_inet_csk_clone),
70797119
LSM_HOOK_INIT(inet_conn_established, selinux_inet_conn_established),

security/selinux/ima.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*
55
* Author: Lakshmi Ramasubramanian (nramas@linux.microsoft.com)
66
*
7-
* Measure critical data structures maintainted by SELinux
7+
* Measure critical data structures maintained by SELinux
88
* using IMA subsystem.
99
*/
1010
#include <linux/vmalloc.h>

security/selinux/include/audit.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ void selinux_audit_rule_free(void *rule);
4141
* selinux_audit_rule_match - determine if a context ID matches a rule.
4242
* @sid: the context ID to check
4343
* @field: the field this rule refers to
44-
* @op: the operater the rule uses
44+
* @op: the operator the rule uses
4545
* @rule: pointer to the audit rule to check against
4646
*
4747
* Returns 1 if the context id matches the rule, 0 if it does not, and

security/selinux/include/avc.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -168,9 +168,6 @@ int avc_get_hash_stats(char *page);
168168
unsigned int avc_get_cache_threshold(void);
169169
void avc_set_cache_threshold(unsigned int cache_threshold);
170170

171-
/* Attempt to free avc node cache */
172-
void avc_disable(void);
173-
174171
#ifdef CONFIG_SECURITY_SELINUX_AVC_STATS
175172
DECLARE_PER_CPU(struct avc_cache_stats, avc_cache_stats);
176173
#endif

0 commit comments

Comments
 (0)