From 12f348b9dcf6d9616c86a049c3c8700f9dc0af55 Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Tue, 9 Oct 2012 10:56:25 -0400 Subject: SELinux: rename SE_SBLABELSUPP to SBLABEL_MNT Just a flag rename as we prepare to make it not so special. Signed-off-by: Eric Paris --- security/selinux/include/security.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'security/selinux/include/security.h') diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index 6d3885165d14..7ec750609cca 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h @@ -52,7 +52,7 @@ /* Non-mount related flags */ #define SE_SBINITIALIZED 0x10 #define SE_SBPROC 0x20 -#define SE_SBLABELSUPP 0x40 +#define SBLABEL_MNT 0x40 #define CONTEXT_STR "context=" #define FSCONTEXT_STR "fscontext=" -- cgit v1.2.3 From cfca0303da0e2c3f570cb5cfc7c373828e6c13a2 Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Tue, 9 Oct 2012 16:20:08 -0400 Subject: SELinux: renumber the superblock options Just to make it clear that we have mount time options and flags, separate them. Since I decided to move the non-mount options above above 0x10, we need a short instead of a char. (x86 padding says this takes up no additional space as we have a 3byte whole in the structure) Signed-off-by: Eric Paris --- security/selinux/include/objsec.h | 2 +- security/selinux/include/security.h | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'security/selinux/include/security.h') diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h index aa47bcabb5f6..fe99f64a1d54 100644 --- a/security/selinux/include/objsec.h +++ b/security/selinux/include/objsec.h @@ -59,7 +59,7 @@ struct superblock_security_struct { u32 def_sid; /* default SID for labeling */ u32 mntpoint_sid; /* SECURITY_FS_USE_MNTPOINT context for files */ unsigned int behavior; /* labeling behavior */ - unsigned char flags; /* which mount options were specified */ + unsigned short flags; /* which mount options were specified */ struct mutex lock; struct list_head isec_head; spinlock_t isec_lock; diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index 7ec750609cca..9c424d8bd2e0 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h @@ -45,14 +45,15 @@ /* Mask for just the mount related flags */ #define SE_MNTMASK 0x0f /* Super block security struct flags for mount options */ +/* BE CAREFUL, these need to be the low order bits for selinux_get_mnt_opts */ #define CONTEXT_MNT 0x01 #define FSCONTEXT_MNT 0x02 #define ROOTCONTEXT_MNT 0x04 #define DEFCONTEXT_MNT 0x08 +#define SBLABEL_MNT 0x10 /* Non-mount related flags */ -#define SE_SBINITIALIZED 0x10 -#define SE_SBPROC 0x20 -#define SBLABEL_MNT 0x40 +#define SE_SBINITIALIZED 0x0100 +#define SE_SBPROC 0x0200 #define CONTEXT_STR "context=" #define FSCONTEXT_STR "fscontext=" -- cgit v1.2.3 From f936c6e502d3bc21b87c9830b3a24d1e07e6b6e1 Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Wed, 10 Oct 2012 10:38:47 -0400 Subject: SELinux: change sbsec->behavior to short We only have 6 options, so char is good enough, but use a short as that packs nicely. This shrinks the superblock_security_struct just a little bit. Signed-off-by: Eric Paris --- security/selinux/include/objsec.h | 2 +- security/selinux/include/security.h | 2 +- security/selinux/ss/services.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'security/selinux/include/security.h') diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h index fe99f64a1d54..b1dfe1049450 100644 --- a/security/selinux/include/objsec.h +++ b/security/selinux/include/objsec.h @@ -58,7 +58,7 @@ struct superblock_security_struct { u32 sid; /* SID of file system superblock */ u32 def_sid; /* default SID for labeling */ u32 mntpoint_sid; /* SECURITY_FS_USE_MNTPOINT context for files */ - unsigned int behavior; /* labeling behavior */ + unsigned short behavior; /* labeling behavior */ unsigned short flags; /* which mount options were specified */ struct mutex lock; struct list_head isec_head; diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index 9c424d8bd2e0..20830be6b61f 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h @@ -171,7 +171,7 @@ int security_get_allow_unknown(void); #define SECURITY_FS_USE_NONE 5 /* no labeling support */ #define SECURITY_FS_USE_MNTPOINT 6 /* use mountpoint labeling */ -int security_fs_use(const char *fstype, unsigned int *behavior, +int security_fs_use(const char *fstype, short unsigned int *behavior, u32 *sid); int security_genfs_sid(const char *fstype, char *name, u16 sclass, diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index b4feecc3fe01..603c638434bb 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -2329,7 +2329,7 @@ out: */ int security_fs_use( const char *fstype, - unsigned int *behavior, + short unsigned int *behavior, u32 *sid) { int rc = 0; -- cgit v1.2.3 From 308ab70c465d97cf7e3168961dfd365535de21a6 Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Fri, 24 Aug 2012 15:59:21 -0400 Subject: SELinux: do not handle seclabel as a special flag Instead of having special code around the 'non-mount' seclabel mount option just handle it like the mount options. Signed-off-by: Eric Paris --- security/selinux/hooks.c | 3 --- security/selinux/include/security.h | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) (limited to 'security/selinux/include/security.h') diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index ca0a1c671f0e..5596dc51e21b 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -474,9 +474,6 @@ static int selinux_get_mnt_opts(const struct super_block *sb, opts->num_mnt_opts++; tmp >>= 1; } - /* Check if the Label support flag is set */ - if (sbsec->flags & SBLABEL_MNT) - opts->num_mnt_opts++; opts->mnt_opts = kcalloc(opts->num_mnt_opts, sizeof(char *), GFP_ATOMIC); if (!opts->mnt_opts) { diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index 20830be6b61f..1a73fcd51d56 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h @@ -43,7 +43,7 @@ #endif /* Mask for just the mount related flags */ -#define SE_MNTMASK 0x0f +#define SE_MNTMASK 0x1f /* Super block security struct flags for mount options */ /* BE CAREFUL, these need to be the low order bits for selinux_get_mnt_opts */ #define CONTEXT_MNT 0x01 -- cgit v1.2.3 From a64c54cf0811b8032fdab8c9d52576f0370837fa Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Fri, 24 Aug 2012 15:59:07 -0400 Subject: SELinux: pass a superblock to security_fs_use Rather than passing pointers to memory locations, strings, and other stuff just give up on the separation and give security_fs_use the superblock. It just makes the code easier to read (even if not easier to reuse on some other OS) Signed-off-by: Eric Paris --- security/selinux/hooks.c | 2 +- security/selinux/include/security.h | 3 +-- security/selinux/ss/services.c | 21 +++++++++------------ 3 files changed, 11 insertions(+), 15 deletions(-) (limited to 'security/selinux/include/security.h') diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 5596dc51e21b..ec15a5694b9e 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -677,7 +677,7 @@ static int selinux_set_mnt_opts(struct super_block *sb, sbsec->flags |= SE_SBPROC; /* Determine the labeling behavior to use for this filesystem type. */ - rc = security_fs_use(sb->s_type->name, &sbsec->behavior, &sbsec->sid); + rc = security_fs_use(sb); if (rc) { printk(KERN_WARNING "%s: security_fs_use(%s) returned %d\n", __func__, sb->s_type->name, rc); diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index 1a73fcd51d56..01a0382c43ca 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h @@ -171,8 +171,7 @@ int security_get_allow_unknown(void); #define SECURITY_FS_USE_NONE 5 /* no labeling support */ #define SECURITY_FS_USE_MNTPOINT 6 /* use mountpoint labeling */ -int security_fs_use(const char *fstype, short unsigned int *behavior, - u32 *sid); +int security_fs_use(struct super_block *sb); int security_genfs_sid(const char *fstype, char *name, u16 sclass, u32 *sid); diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 603c638434bb..a90721771615 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -2323,17 +2323,14 @@ out: /** * security_fs_use - Determine how to handle labeling for a filesystem. - * @fstype: filesystem type - * @behavior: labeling behavior - * @sid: SID for filesystem (superblock) + * @sb: superblock in question */ -int security_fs_use( - const char *fstype, - short unsigned int *behavior, - u32 *sid) +int security_fs_use(struct super_block *sb) { int rc = 0; struct ocontext *c; + struct superblock_security_struct *sbsec = sb->s_security; + const char *fstype = sb->s_type->name; read_lock(&policy_rwlock); @@ -2345,21 +2342,21 @@ int security_fs_use( } if (c) { - *behavior = c->v.behavior; + sbsec->behavior = c->v.behavior; if (!c->sid[0]) { rc = sidtab_context_to_sid(&sidtab, &c->context[0], &c->sid[0]); if (rc) goto out; } - *sid = c->sid[0]; + sbsec->sid = c->sid[0]; } else { - rc = security_genfs_sid(fstype, "/", SECCLASS_DIR, sid); + rc = security_genfs_sid(fstype, "/", SECCLASS_DIR, &sbsec->sid); if (rc) { - *behavior = SECURITY_FS_USE_NONE; + sbsec->behavior = SECURITY_FS_USE_NONE; rc = 0; } else { - *behavior = SECURITY_FS_USE_GENFS; + sbsec->behavior = SECURITY_FS_USE_GENFS; } } -- cgit v1.2.3 From 2be4d74f2fd45460d70d4fe65cc1972ef45bf849 Mon Sep 17 00:00:00 2001 From: Chris PeBenito Date: Fri, 3 May 2013 09:05:39 -0400 Subject: Add SELinux policy capability for always checking packet and peer classes. Currently the packet class in SELinux is not checked if there are no SECMARK rules in the security or mangle netfilter tables. Some systems prefer that packets are always checked, for example, to protect the system should the netfilter rules fail to load or if the nefilter rules were maliciously flushed. Add the always_check_network policy capability which, when enabled, treats SECMARK as enabled, even if there are no netfilter SECMARK rules and treats peer labeling as enabled, even if there is no Netlabel or labeled IPSEC configuration. Includes definition of "redhat1" SELinux policy capability, which exists in the SELinux userpace library, to keep ordering correct. The SELinux userpace portion of this was merged last year, but this kernel change fell on the floor. Signed-off-by: Chris PeBenito Signed-off-by: Eric Paris --- security/selinux/hooks.c | 26 +++++++++++++++++++++----- security/selinux/include/security.h | 3 +++ security/selinux/selinuxfs.c | 4 +++- security/selinux/ss/services.c | 3 +++ 4 files changed, 30 insertions(+), 6 deletions(-) (limited to 'security/selinux/include/security.h') diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index b222e966babe..4fbf2c5f26ce 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -136,12 +136,28 @@ static struct kmem_cache *sel_inode_cache; * This function checks the SECMARK reference counter to see if any SECMARK * targets are currently configured, if the reference counter is greater than * zero SECMARK is considered to be enabled. Returns true (1) if SECMARK is - * enabled, false (0) if SECMARK is disabled. + * enabled, false (0) if SECMARK is disabled. If the always_check_network + * policy capability is enabled, SECMARK is always considered enabled. * */ static int selinux_secmark_enabled(void) { - return (atomic_read(&selinux_secmark_refcount) > 0); + return (selinux_policycap_alwaysnetwork || atomic_read(&selinux_secmark_refcount)); +} + +/** + * selinux_peerlbl_enabled - Check to see if peer labeling is currently enabled + * + * Description: + * This function checks if NetLabel or labeled IPSEC is enabled. Returns true + * (1) if any are enabled or false (0) if neither are enabled. If the + * always_check_network policy capability is enabled, peer labeling + * is always considered enabled. + * + */ +static int selinux_peerlbl_enabled(void) +{ + return (selinux_policycap_alwaysnetwork || netlbl_enabled() || selinux_xfrm_enabled()); } /* @@ -4197,7 +4213,7 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) return selinux_sock_rcv_skb_compat(sk, skb, family); secmark_active = selinux_secmark_enabled(); - peerlbl_active = netlbl_enabled() || selinux_xfrm_enabled(); + peerlbl_active = selinux_peerlbl_enabled(); if (!secmark_active && !peerlbl_active) return 0; @@ -4579,7 +4595,7 @@ static unsigned int selinux_ip_forward(struct sk_buff *skb, int ifindex, secmark_active = selinux_secmark_enabled(); netlbl_active = netlbl_enabled(); - peerlbl_active = netlbl_active || selinux_xfrm_enabled(); + peerlbl_active = selinux_peerlbl_enabled(); if (!secmark_active && !peerlbl_active) return NF_ACCEPT; @@ -4731,7 +4747,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex, return NF_ACCEPT; #endif secmark_active = selinux_secmark_enabled(); - peerlbl_active = netlbl_enabled() || selinux_xfrm_enabled(); + peerlbl_active = selinux_peerlbl_enabled(); if (!secmark_active && !peerlbl_active) return NF_ACCEPT; diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index 01a0382c43ca..004a2479880f 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h @@ -69,12 +69,15 @@ extern int selinux_enabled; enum { POLICYDB_CAPABILITY_NETPEER, POLICYDB_CAPABILITY_OPENPERM, + POLICYDB_CAPABILITY_REDHAT1, + POLICYDB_CAPABILITY_ALWAYSNETWORK, __POLICYDB_CAPABILITY_MAX }; #define POLICYDB_CAPABILITY_MAX (__POLICYDB_CAPABILITY_MAX - 1) extern int selinux_policycap_netpeer; extern int selinux_policycap_openperm; +extern int selinux_policycap_alwaysnetwork; /* * type_datum properties diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c index ff427733c290..5122affe06a8 100644 --- a/security/selinux/selinuxfs.c +++ b/security/selinux/selinuxfs.c @@ -44,7 +44,9 @@ /* Policy capability filenames */ static char *policycap_names[] = { "network_peer_controls", - "open_perms" + "open_perms", + "redhat1", + "always_check_network" }; unsigned int selinux_checkreqprot = CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE; diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index a90721771615..d106733ad987 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -72,6 +72,7 @@ int selinux_policycap_netpeer; int selinux_policycap_openperm; +int selinux_policycap_alwaysnetwork; static DEFINE_RWLOCK(policy_rwlock); @@ -1812,6 +1813,8 @@ static void security_load_policycaps(void) POLICYDB_CAPABILITY_NETPEER); selinux_policycap_openperm = ebitmap_get_bit(&policydb.policycaps, POLICYDB_CAPABILITY_OPENPERM); + selinux_policycap_alwaysnetwork = ebitmap_get_bit(&policydb.policycaps, + POLICYDB_CAPABILITY_ALWAYSNETWORK); } static int security_preserve_bools(struct policydb *p); -- cgit v1.2.3 From 0b4bdb3573a86a88c829b9e4ad702859eb923e7e Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Wed, 28 Aug 2013 13:32:42 -0400 Subject: Revert "SELinux: do not handle seclabel as a special flag" This reverts commit 308ab70c465d97cf7e3168961dfd365535de21a6. It breaks my FC6 test box. /dev/pts is not mounted. dmesg says SELinux: mount invalid. Same superblock, different security settings for (dev devpts, type devpts) Cc: Peter Hurley Cc: Greg KH Signed-off-by: Andrew Morton Signed-off-by: Eric Paris --- security/selinux/hooks.c | 3 +++ security/selinux/include/security.h | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'security/selinux/include/security.h') diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 0d4408debb45..c156f5eb1aea 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -504,6 +504,9 @@ static int selinux_get_mnt_opts(const struct super_block *sb, opts->num_mnt_opts++; tmp >>= 1; } + /* Check if the Label support flag is set */ + if (sbsec->flags & SBLABEL_MNT) + opts->num_mnt_opts++; opts->mnt_opts = kcalloc(opts->num_mnt_opts, sizeof(char *), GFP_ATOMIC); if (!opts->mnt_opts) { diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index 004a2479880f..7aad3a1389d1 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h @@ -43,7 +43,7 @@ #endif /* Mask for just the mount related flags */ -#define SE_MNTMASK 0x1f +#define SE_MNTMASK 0x0f /* Super block security struct flags for mount options */ /* BE CAREFUL, these need to be the low order bits for selinux_get_mnt_opts */ #define CONTEXT_MNT 0x01 -- cgit v1.2.3