diff options
Diffstat (limited to 'security/selinux/include')
| -rw-r--r-- | security/selinux/include/avc.h | 102 | ||||
| -rw-r--r-- | security/selinux/include/avc_ss.h | 6 | ||||
| -rw-r--r-- | security/selinux/include/classmap.h | 13 | ||||
| -rw-r--r-- | security/selinux/include/netif.h | 2 | ||||
| -rw-r--r-- | security/selinux/include/netlabel.h | 2 | ||||
| -rw-r--r-- | security/selinux/include/netnode.h | 2 | ||||
| -rw-r--r-- | security/selinux/include/netport.h | 2 | ||||
| -rw-r--r-- | security/selinux/include/objsec.h | 13 | ||||
| -rw-r--r-- | security/selinux/include/security.h | 43 | ||||
| -rw-r--r-- | security/selinux/include/xfrm.h | 61 | 
10 files changed, 182 insertions, 64 deletions
diff --git a/security/selinux/include/avc.h b/security/selinux/include/avc.h index e94e82f7381..ddf8eec03f2 100644 --- a/security/selinux/include/avc.h +++ b/security/selinux/include/avc.h @@ -15,8 +15,6 @@  #include <linux/audit.h>  #include <linux/lsm_audit.h>  #include <linux/in6.h> -#include <linux/path.h> -#include <asm/system.h>  #include "flask.h"  #include "av_permissions.h"  #include "security.h" @@ -42,7 +40,6 @@ struct sk_buff;   */  struct avc_cache_stats {  	unsigned int lookups; -	unsigned int hits;  	unsigned int misses;  	unsigned int allocations;  	unsigned int reclaims; @@ -50,16 +47,99 @@ struct avc_cache_stats {  };  /* + * We only need this data after we have decided to send an audit message. + */ +struct selinux_audit_data { +	u32 ssid; +	u32 tsid; +	u16 tclass; +	u32 requested; +	u32 audited; +	u32 denied; +	int result; +}; + +/*   * AVC operations   */  void __init avc_init(void); -void avc_audit(u32 ssid, u32 tsid, -	       u16 tclass, u32 requested, -	       struct av_decision *avd, -	       int result, -	       struct common_audit_data *a); +static inline u32 avc_audit_required(u32 requested, +			      struct av_decision *avd, +			      int result, +			      u32 auditdeny, +			      u32 *deniedp) +{ +	u32 denied, audited; +	denied = requested & ~avd->allowed; +	if (unlikely(denied)) { +		audited = denied & avd->auditdeny; +		/* +		 * auditdeny is TRICKY!  Setting a bit in +		 * this field means that ANY denials should NOT be audited if +		 * the policy contains an explicit dontaudit rule for that +		 * permission.  Take notice that this is unrelated to the +		 * actual permissions that were denied.  As an example lets +		 * assume: +		 * +		 * denied == READ +		 * avd.auditdeny & ACCESS == 0 (not set means explicit rule) +		 * auditdeny & ACCESS == 1 +		 * +		 * We will NOT audit the denial even though the denied +		 * permission was READ and the auditdeny checks were for +		 * ACCESS +		 */ +		if (auditdeny && !(auditdeny & avd->auditdeny)) +			audited = 0; +	} else if (result) +		audited = denied = requested; +	else +		audited = requested & avd->auditallow; +	*deniedp = denied; +	return audited; +} + +int slow_avc_audit(u32 ssid, u32 tsid, u16 tclass, +		   u32 requested, u32 audited, u32 denied, int result, +		   struct common_audit_data *a, +		   unsigned flags); + +/** + * avc_audit - Audit the granting or denial of permissions. + * @ssid: source security identifier + * @tsid: target security identifier + * @tclass: target security class + * @requested: requested permissions + * @avd: access vector decisions + * @result: result from avc_has_perm_noaudit + * @a:  auxiliary audit data + * @flags: VFS walk flags + * + * Audit the granting or denial of permissions in accordance + * with the policy.  This function is typically called by + * avc_has_perm() after a permission check, but can also be + * called directly by callers who use avc_has_perm_noaudit() + * in order to separate the permission check from the auditing. + * For example, this separation is useful when the permission check must + * be performed under a lock, to allow the lock to be released + * before calling the auditing code. + */ +static inline int avc_audit(u32 ssid, u32 tsid, +			    u16 tclass, u32 requested, +			    struct av_decision *avd, +			    int result, +			    struct common_audit_data *a) +{ +	u32 audited, denied; +	audited = avc_audit_required(requested, avd, result, 0, &denied); +	if (likely(!audited)) +		return 0; +	return slow_avc_audit(ssid, tsid, tclass, +			      requested, audited, denied, result, +			      a, 0); +}  #define AVC_STRICT 1 /* Ignore permissive mode. */  int avc_has_perm_noaudit(u32 ssid, u32 tsid, @@ -82,11 +162,7 @@ u32 avc_policy_seqno(void);  #define AVC_CALLBACK_AUDITDENY_ENABLE	64  #define AVC_CALLBACK_AUDITDENY_DISABLE	128 -int avc_add_callback(int (*callback)(u32 event, u32 ssid, u32 tsid, -				     u16 tclass, u32 perms, -				     u32 *out_retained), -		     u32 events, u32 ssid, u32 tsid, -		     u16 tclass, u32 perms); +int avc_add_callback(int (*callback)(u32 event), u32 events);  /* Exported to selinuxfs */  int avc_get_hash_stats(char *page); diff --git a/security/selinux/include/avc_ss.h b/security/selinux/include/avc_ss.h index 4677aa519b0..d5c328452df 100644 --- a/security/selinux/include/avc_ss.h +++ b/security/selinux/include/avc_ss.h @@ -18,5 +18,11 @@ struct security_class_mapping {  extern struct security_class_mapping secclass_map[]; +/* + * The security server must be initialized before + * any labeling or access decisions can be provided. + */ +extern int ss_initialized; +  #endif /* _SELINUX_AVC_SS_H_ */ diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h index 8858d2b2d4b..be491a74c1e 100644 --- a/security/selinux/include/classmap.h +++ b/security/selinux/include/classmap.h @@ -12,6 +12,10 @@  #define COMMON_IPC_PERMS "create", "destroy", "getattr", "setattr", "read", \  	    "write", "associate", "unix_read", "unix_write" +/* + * Note: The name for any socket class should be suffixed by "socket", + *	 and doesn't contain more than one substr of "socket". + */  struct security_class_mapping secclass_map[] = {  	{ "security",  	  { "compute_av", "compute_create", "compute_member", @@ -132,8 +136,7 @@ struct security_class_mapping secclass_map[] = {  	{ "appletalk_socket",  	  { COMMON_SOCK_PERMS, NULL } },  	{ "packet", -	  { "send", "recv", "relabelto", "flow_in", "flow_out", -	    "forward_in", "forward_out", NULL } }, +	  { "send", "recv", "relabelto", "forward_in", "forward_out", NULL } },  	{ "key",  	  { "view", "read", "write", "search", "link", "setattr", "create",  	    NULL } }, @@ -142,9 +145,11 @@ struct security_class_mapping secclass_map[] = {  	    "node_bind", "name_connect", NULL } },  	{ "memprotect", { "mmap_zero", NULL } },  	{ "peer", { "recv", NULL } }, -	{ "capability2", { "mac_override", "mac_admin", NULL } }, +	{ "capability2", +	  { "mac_override", "mac_admin", "syslog", "wake_alarm", "block_suspend", +	    "audit_read", NULL } },  	{ "kernel_service", { "use_as_override", "create_files_as", NULL } },  	{ "tun_socket", -	  { COMMON_SOCK_PERMS, NULL } }, +	  { COMMON_SOCK_PERMS, "attach_queue", NULL } },  	{ NULL }    }; diff --git a/security/selinux/include/netif.h b/security/selinux/include/netif.h index ce23edd128b..43d507242b4 100644 --- a/security/selinux/include/netif.h +++ b/security/selinux/include/netif.h @@ -8,7 +8,7 @@   *   * Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com>   * Copyright (C) 2007 Hewlett-Packard Development Company, L.P. - *                    Paul Moore, <paul.moore@hp.com> + *                    Paul Moore <paul@paul-moore.com>   *   * This program is free software; you can redistribute it and/or modify   * it under the terms of the GNU General Public License version 2, diff --git a/security/selinux/include/netlabel.h b/security/selinux/include/netlabel.h index cf2f628e6e2..8c59b8f150e 100644 --- a/security/selinux/include/netlabel.h +++ b/security/selinux/include/netlabel.h @@ -1,7 +1,7 @@  /*   * SELinux interface to the NetLabel subsystem   * - * Author : Paul Moore <paul.moore@hp.com> + * Author: Paul Moore <paul@paul-moore.com>   *   */ diff --git a/security/selinux/include/netnode.h b/security/selinux/include/netnode.h index 1b94450d11d..df7a5ed6c69 100644 --- a/security/selinux/include/netnode.h +++ b/security/selinux/include/netnode.h @@ -6,7 +6,7 @@   * needed to reduce the lookup overhead since most of these queries happen on   * a per-packet basis.   * - * Author: Paul Moore <paul.moore@hp.com> + * Author: Paul Moore <paul@paul-moore.com>   *   */ diff --git a/security/selinux/include/netport.h b/security/selinux/include/netport.h index 8991752eaf9..4d965b83d73 100644 --- a/security/selinux/include/netport.h +++ b/security/selinux/include/netport.h @@ -5,7 +5,7 @@   * mapping is maintained as part of the normal policy but a fast cache is   * needed to reduce the lookup overhead.   * - * Author: Paul Moore <paul.moore@hp.com> + * Author: Paul Moore <paul@paul-moore.com>   *   */ diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h index 26c7eee1c30..078e553f52f 100644 --- a/security/selinux/include/objsec.h +++ b/security/selinux/include/objsec.h @@ -38,7 +38,10 @@ struct task_security_struct {  struct inode_security_struct {  	struct inode *inode;	/* back pointer to inode object */ -	struct list_head list;	/* list of inode_security_struct */ +	union { +		struct list_head list;	/* list of inode_security_struct */ +		struct rcu_head rcu;	/* for freeing the inode_security_struct */ +	};  	u32 task_sid;		/* SID of creating task */  	u32 sid;		/* SID of this object */  	u16 sclass;		/* security class of this object */ @@ -58,8 +61,8 @@ 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 char flags;		/* which mount options were specified */ +	unsigned short behavior;	/* labeling behavior */ +	unsigned short flags;		/* which mount options were specified */  	struct mutex lock;  	struct list_head isec_head;  	spinlock_t isec_lock; @@ -110,6 +113,10 @@ struct sk_security_struct {  	u16 sclass;			/* sock security class */  }; +struct tun_security_struct { +	u32 sid;			/* SID for the tun device sockets */ +}; +  struct key_security_struct {  	u32 sid;	/* SID of key */  }; diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index 671273eb111..ce7852cf526 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h @@ -8,6 +8,7 @@  #ifndef _SELINUX_SECURITY_H_  #define _SELINUX_SECURITY_H_ +#include <linux/dcache.h>  #include <linux/magic.h>  #include <linux/types.h>  #include "flask.h" @@ -28,26 +29,32 @@  #define POLICYDB_VERSION_POLCAP		22  #define POLICYDB_VERSION_PERMISSIVE	23  #define POLICYDB_VERSION_BOUNDARY	24 +#define POLICYDB_VERSION_FILENAME_TRANS	25 +#define POLICYDB_VERSION_ROLETRANS	26 +#define POLICYDB_VERSION_NEW_OBJECT_DEFAULTS	27 +#define POLICYDB_VERSION_DEFAULT_TYPE	28 +#define POLICYDB_VERSION_CONSTRAINT_NAMES	29  /* Range of policy versions we understand*/  #define POLICYDB_VERSION_MIN   POLICYDB_VERSION_BASE  #ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX  #define POLICYDB_VERSION_MAX	CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE  #else -#define POLICYDB_VERSION_MAX	POLICYDB_VERSION_BOUNDARY +#define POLICYDB_VERSION_MAX	POLICYDB_VERSION_CONSTRAINT_NAMES  #endif  /* 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 SE_SBLABELSUPP	0x40 +#define SE_SBINITIALIZED	0x0100 +#define SE_SBPROC		0x0200  #define CONTEXT_STR	"context="  #define FSCONTEXT_STR	"fscontext=" @@ -63,12 +70,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 @@ -83,7 +93,7 @@ extern int selinux_policycap_openperm;  int security_mls_enabled(void);  int security_load_policy(void *data, size_t len); -int security_read_policy(void **data, ssize_t *len); +int security_read_policy(void **data, size_t *len);  size_t security_policydb_len(void);  int security_policycap_supported(unsigned int req_cap); @@ -106,11 +116,11 @@ void security_compute_av(u32 ssid, u32 tsid,  void security_compute_av_user(u32 ssid, u32 tsid,  			     u16 tclass, struct av_decision *avd); -int security_transition_sid(u32 ssid, u32 tsid, -			    u16 tclass, u32 *out_sid); +int security_transition_sid(u32 ssid, u32 tsid, u16 tclass, +			    const struct qstr *qstr, u32 *out_sid); -int security_transition_sid_user(u32 ssid, u32 tsid, -				 u16 tclass, u32 *out_sid); +int security_transition_sid_user(u32 ssid, u32 tsid, u16 tclass, +				 const char *objname, u32 *out_sid);  int security_member_sid(u32 ssid, u32 tsid,  	u16 tclass, u32 *out_sid); @@ -124,7 +134,7 @@ int security_sid_to_context(u32 sid, char **scontext,  int security_sid_to_context_force(u32 sid, char **scontext, u32 *scontext_len);  int security_context_to_sid(const char *scontext, u32 scontext_len, -	u32 *out_sid); +			    u32 *out_sid, gfp_t gfp);  int security_context_to_sid_default(const char *scontext, u32 scontext_len,  				    u32 *out_sid, u32 def_sid, gfp_t gfp_flags); @@ -164,9 +174,10 @@ int security_get_allow_unknown(void);  #define SECURITY_FS_USE_GENFS		4 /* use the genfs support */  #define SECURITY_FS_USE_NONE		5 /* no labeling support */  #define SECURITY_FS_USE_MNTPOINT	6 /* use mountpoint labeling */ +#define SECURITY_FS_USE_NATIVE		7 /* use native label support */ +#define SECURITY_FS_USE_MAX		7 /* Highest SECURITY_FS_USE_XXX */ -int security_fs_use(const char *fstype, 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); @@ -213,6 +224,14 @@ struct selinux_kernel_status {  extern void selinux_status_update_setenforce(int enforcing);  extern void selinux_status_update_policyload(int seqno); +extern void selinux_complete_init(void); +extern int selinux_disable(void); +extern void exit_sel_fs(void); +extern struct path selinux_null; +extern struct vfsmount *selinuxfs_mount; +extern void selnl_notify_setenforce(int val); +extern void selnl_notify_policyload(u32 seqno); +extern int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm);  #endif /* _SELINUX_SECURITY_H_ */ diff --git a/security/selinux/include/xfrm.h b/security/selinux/include/xfrm.h index 13128f9a3e5..1450f85b946 100644 --- a/security/selinux/include/xfrm.h +++ b/security/selinux/include/xfrm.h @@ -7,30 +7,25 @@  #ifndef _SELINUX_XFRM_H_  #define _SELINUX_XFRM_H_ +#include <net/flow.h> +  int selinux_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp, -			      struct xfrm_user_sec_ctx *sec_ctx); +			      struct xfrm_user_sec_ctx *uctx, +			      gfp_t gfp);  int selinux_xfrm_policy_clone(struct xfrm_sec_ctx *old_ctx,  			      struct xfrm_sec_ctx **new_ctxp);  void selinux_xfrm_policy_free(struct xfrm_sec_ctx *ctx);  int selinux_xfrm_policy_delete(struct xfrm_sec_ctx *ctx);  int selinux_xfrm_state_alloc(struct xfrm_state *x, -	struct xfrm_user_sec_ctx *sec_ctx, u32 secid); +			     struct xfrm_user_sec_ctx *uctx); +int selinux_xfrm_state_alloc_acquire(struct xfrm_state *x, +				     struct xfrm_sec_ctx *polsec, u32 secid);  void selinux_xfrm_state_free(struct xfrm_state *x);  int selinux_xfrm_state_delete(struct xfrm_state *x);  int selinux_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid, u8 dir);  int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x, -			struct xfrm_policy *xp, struct flowi *fl); - -/* - * Extract the security blob from the sock (it's actually on the socket) - */ -static inline struct inode_security_struct *get_sock_isec(struct sock *sk) -{ -	if (!sk->sk_socket) -		return NULL; - -	return SOCK_INODE(sk->sk_socket)->i_security; -} +				      struct xfrm_policy *xp, +				      const struct flowi *fl);  #ifdef CONFIG_SECURITY_NETWORK_XFRM  extern atomic_t selinux_xfrm_refcount; @@ -40,15 +35,23 @@ static inline int selinux_xfrm_enabled(void)  	return (atomic_read(&selinux_xfrm_refcount) > 0);  } -int selinux_xfrm_sock_rcv_skb(u32 sid, struct sk_buff *skb, -			struct common_audit_data *ad); -int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb, -			struct common_audit_data *ad, u8 proto); +int selinux_xfrm_sock_rcv_skb(u32 sk_sid, struct sk_buff *skb, +			      struct common_audit_data *ad); +int selinux_xfrm_postroute_last(u32 sk_sid, struct sk_buff *skb, +				struct common_audit_data *ad, u8 proto);  int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall); +int selinux_xfrm_skb_sid(struct sk_buff *skb, u32 *sid);  static inline void selinux_xfrm_notify_policyload(void)  { -	atomic_inc(&flow_cache_genid); +	struct net *net; + +	rtnl_lock(); +	for_each_net(net) { +		atomic_inc(&net->xfrm.flow_cache_genid); +		rt_genid_bump_all(net); +	} +	rtnl_unlock();  }  #else  static inline int selinux_xfrm_enabled(void) @@ -56,19 +59,21 @@ static inline int selinux_xfrm_enabled(void)  	return 0;  } -static inline int selinux_xfrm_sock_rcv_skb(u32 isec_sid, struct sk_buff *skb, -			struct common_audit_data *ad) +static inline int selinux_xfrm_sock_rcv_skb(u32 sk_sid, struct sk_buff *skb, +					    struct common_audit_data *ad)  {  	return 0;  } -static inline int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb, -			struct common_audit_data *ad, u8 proto) +static inline int selinux_xfrm_postroute_last(u32 sk_sid, struct sk_buff *skb, +					      struct common_audit_data *ad, +					      u8 proto)  {  	return 0;  } -static inline int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall) +static inline int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, +					      int ckall)  {  	*sid = SECSID_NULL;  	return 0; @@ -77,12 +82,12 @@ static inline int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int  static inline void selinux_xfrm_notify_policyload(void)  {  } -#endif -static inline void selinux_skb_xfrm_sid(struct sk_buff *skb, u32 *sid) +static inline int selinux_xfrm_skb_sid(struct sk_buff *skb, u32 *sid)  { -	int err = selinux_xfrm_decode_session(skb, sid, 0); -	BUG_ON(err); +	*sid = SECSID_NULL; +	return 0;  } +#endif  #endif /* _SELINUX_XFRM_H_ */  | 
