Merge tag 'selinux-pr-20180403' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux

Pull SELinux updates from Paul Moore:
 "A bigger than usual pull request for SELinux, 13 patches (lucky!)
  along with a scary looking diffstat.

  Although if you look a bit closer, excluding the usual minor
  tweaks/fixes, there are really only two significant changes in this
  pull request: the addition of proper SELinux access controls for SCTP
  and the encapsulation of a lot of internal SELinux state.

  The SCTP changes are the result of a multi-month effort (maybe even a
  year or longer?) between the SELinux folks and the SCTP folks to add
  proper SELinux controls. A special thanks go to Richard for seeing
  this through and keeping the effort moving forward.

  The state encapsulation work is a bit of janitorial work that came out
  of some early work on SELinux namespacing. The question of namespacing
  is still an open one, but I believe there is some real value in the
  encapsulation work so we've split that out and are now sending that up
  to you"

* tag 'selinux-pr-20180403' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux:
  selinux: wrap AVC state
  selinux: wrap selinuxfs state
  selinux: fix handling of uninitialized selinux state in get_bools/classes
  selinux: Update SELinux SCTP documentation
  selinux: Fix ltp test connect-syscall failure
  selinux: rename the {is,set}_enforcing() functions
  selinux: wrap global selinux state
  selinux: fix typo in selinux_netlbl_sctp_sk_clone declaration
  selinux: Add SCTP support
  sctp: Add LSM hooks
  sctp: Add ip option support
  security: Add support for SCTP security hooks
  netlabel: If PF_INET6, check sk_buff ip header version
This commit is contained in:
Linus Torvalds
2018-04-06 15:39:26 -07:00
43 changed files with 2953 additions and 1269 deletions

View File

@@ -20,12 +20,6 @@
#include "av_permissions.h"
#include "security.h"
#ifdef CONFIG_SECURITY_SELINUX_DEVELOP
extern int selinux_enforcing;
#else
#define selinux_enforcing 1
#endif
/*
* An entry in the AVC.
*/
@@ -58,6 +52,7 @@ struct selinux_audit_data {
u32 audited;
u32 denied;
int result;
struct selinux_state *state;
};
/*
@@ -102,7 +97,8 @@ static inline u32 avc_audit_required(u32 requested,
return audited;
}
int slow_avc_audit(u32 ssid, u32 tsid, u16 tclass,
int slow_avc_audit(struct selinux_state *state,
u32 ssid, u32 tsid, u16 tclass,
u32 requested, u32 audited, u32 denied, int result,
struct common_audit_data *a,
unsigned flags);
@@ -127,7 +123,8 @@ int slow_avc_audit(u32 ssid, u32 tsid, u16 tclass,
* 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,
static inline int avc_audit(struct selinux_state *state,
u32 ssid, u32 tsid,
u16 tclass, u32 requested,
struct av_decision *avd,
int result,
@@ -138,31 +135,35 @@ static inline int avc_audit(u32 ssid, u32 tsid,
audited = avc_audit_required(requested, avd, result, 0, &denied);
if (likely(!audited))
return 0;
return slow_avc_audit(ssid, tsid, tclass,
return slow_avc_audit(state, ssid, tsid, tclass,
requested, audited, denied, result,
a, flags);
}
#define AVC_STRICT 1 /* Ignore permissive mode. */
#define AVC_EXTENDED_PERMS 2 /* update extended permissions */
int avc_has_perm_noaudit(u32 ssid, u32 tsid,
int avc_has_perm_noaudit(struct selinux_state *state,
u32 ssid, u32 tsid,
u16 tclass, u32 requested,
unsigned flags,
struct av_decision *avd);
int avc_has_perm(u32 ssid, u32 tsid,
int avc_has_perm(struct selinux_state *state,
u32 ssid, u32 tsid,
u16 tclass, u32 requested,
struct common_audit_data *auditdata);
int avc_has_perm_flags(u32 ssid, u32 tsid,
int avc_has_perm_flags(struct selinux_state *state,
u32 ssid, u32 tsid,
u16 tclass, u32 requested,
struct common_audit_data *auditdata,
int flags);
int avc_has_extended_perms(u32 ssid, u32 tsid, u16 tclass, u32 requested,
u8 driver, u8 perm, struct common_audit_data *ad);
int avc_has_extended_perms(struct selinux_state *state,
u32 ssid, u32 tsid, u16 tclass, u32 requested,
u8 driver, u8 perm, struct common_audit_data *ad);
u32 avc_policy_seqno(void);
u32 avc_policy_seqno(struct selinux_state *state);
#define AVC_CALLBACK_GRANT 1
#define AVC_CALLBACK_TRY_REVOKE 2
@@ -177,8 +178,11 @@ u32 avc_policy_seqno(void);
int avc_add_callback(int (*callback)(u32 event), u32 events);
/* Exported to selinuxfs */
int avc_get_hash_stats(char *page);
extern unsigned int avc_cache_threshold;
struct selinux_avc;
int avc_get_hash_stats(struct selinux_avc *avc, char *page);
unsigned int avc_get_cache_threshold(struct selinux_avc *avc);
void avc_set_cache_threshold(struct selinux_avc *avc,
unsigned int cache_threshold);
/* Attempt to free avc node cache */
void avc_disable(void);

View File

@@ -9,7 +9,8 @@
#include "flask.h"
int avc_ss_reset(u32 seqno);
struct selinux_avc;
int avc_ss_reset(struct selinux_avc *avc, u32 seqno);
/* Class/perm mapping support */
struct security_class_mapping {
@@ -19,11 +20,5 @@ 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_ */

View File

@@ -176,7 +176,7 @@ struct security_class_mapping secclass_map[] = {
{ COMMON_CAP2_PERMS, NULL } },
{ "sctp_socket",
{ COMMON_SOCK_PERMS,
"node_bind", NULL } },
"node_bind", "name_connect", "association", NULL } },
{ "icmp_socket",
{ COMMON_SOCK_PERMS,
"node_bind", NULL } },

View File

@@ -13,10 +13,15 @@
#ifndef _SELINUX_CONDITIONAL_H_
#define _SELINUX_CONDITIONAL_H_
int security_get_bools(int *len, char ***names, int **values);
#include "security.h"
int security_set_bools(int len, int *values);
int security_get_bools(struct selinux_state *state,
int *len, char ***names, int **values);
int security_get_bool_value(int index);
int security_set_bools(struct selinux_state *state,
int len, int *values);
int security_get_bool_value(struct selinux_state *state,
int index);
#endif

View File

@@ -32,6 +32,7 @@
#include <linux/skbuff.h>
#include <net/sock.h>
#include <net/request_sock.h>
#include <net/sctp/structs.h>
#include "avc.h"
#include "objsec.h"
@@ -52,9 +53,11 @@ int selinux_netlbl_skbuff_getsid(struct sk_buff *skb,
int selinux_netlbl_skbuff_setsid(struct sk_buff *skb,
u16 family,
u32 sid);
int selinux_netlbl_sctp_assoc_request(struct sctp_endpoint *ep,
struct sk_buff *skb);
int selinux_netlbl_inet_conn_request(struct request_sock *req, u16 family);
void selinux_netlbl_inet_csk_clone(struct sock *sk, u16 family);
void selinux_netlbl_sctp_sk_clone(struct sock *sk, struct sock *newsk);
int selinux_netlbl_socket_post_create(struct sock *sk, u16 family);
int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec,
struct sk_buff *skb,
@@ -64,6 +67,8 @@ int selinux_netlbl_socket_setsockopt(struct socket *sock,
int level,
int optname);
int selinux_netlbl_socket_connect(struct sock *sk, struct sockaddr *addr);
int selinux_netlbl_socket_connect_locked(struct sock *sk,
struct sockaddr *addr);
#else
static inline void selinux_netlbl_cache_invalidate(void)
@@ -113,6 +118,11 @@ static inline int selinux_netlbl_conn_setsid(struct sock *sk,
return 0;
}
static inline int selinux_netlbl_sctp_assoc_request(struct sctp_endpoint *ep,
struct sk_buff *skb)
{
return 0;
}
static inline int selinux_netlbl_inet_conn_request(struct request_sock *req,
u16 family)
{
@@ -122,6 +132,11 @@ static inline void selinux_netlbl_inet_csk_clone(struct sock *sk, u16 family)
{
return;
}
static inline void selinux_netlbl_sctp_sk_clone(struct sock *sk,
struct sock *newsk)
{
return;
}
static inline int selinux_netlbl_socket_post_create(struct sock *sk,
u16 family)
{
@@ -145,6 +160,11 @@ static inline int selinux_netlbl_socket_connect(struct sock *sk,
{
return 0;
}
static inline int selinux_netlbl_socket_connect_locked(struct sock *sk,
struct sockaddr *addr)
{
return 0;
}
#endif /* CONFIG_NETLABEL */
#endif

View File

@@ -130,6 +130,10 @@ struct sk_security_struct {
u32 sid; /* SID of this object */
u32 peer_sid; /* SID of peer */
u16 sclass; /* sock security class */
enum { /* SCTP association state */
SCTP_ASSOC_UNSET = 0,
SCTP_ASSOC_SET,
} sctp_assoc_state;
};
struct tun_security_struct {
@@ -154,6 +158,4 @@ struct bpf_security_struct {
u32 sid; /*SID of bpf obj creater*/
};
extern unsigned int selinux_checkreqprot;
#endif /* _SELINUX_OBJSEC_H_ */

View File

@@ -13,6 +13,8 @@
#include <linux/dcache.h>
#include <linux/magic.h>
#include <linux/types.h>
#include <linux/refcount.h>
#include <linux/workqueue.h>
#include "flask.h"
#define SECSID_NULL 0x00000000 /* unspecified SID */
@@ -81,13 +83,6 @@ enum {
extern char *selinux_policycap_names[__POLICYDB_CAPABILITY_MAX];
extern int selinux_policycap_netpeer;
extern int selinux_policycap_openperm;
extern int selinux_policycap_extsockclass;
extern int selinux_policycap_alwaysnetwork;
extern int selinux_policycap_cgroupseclabel;
extern int selinux_policycap_nnp_nosuid_transition;
/*
* type_datum properties
* available at the kernel policy version >= POLICYDB_VERSION_BOUNDARY
@@ -98,13 +93,98 @@ extern int selinux_policycap_nnp_nosuid_transition;
/* limitation of boundary depth */
#define POLICYDB_BOUNDS_MAXDEPTH 4
int security_mls_enabled(void);
struct selinux_avc;
struct selinux_ss;
int security_load_policy(void *data, size_t len);
int security_read_policy(void **data, size_t *len);
size_t security_policydb_len(void);
struct selinux_state {
bool disabled;
#ifdef CONFIG_SECURITY_SELINUX_DEVELOP
bool enforcing;
#endif
bool checkreqprot;
bool initialized;
bool policycap[__POLICYDB_CAPABILITY_MAX];
struct selinux_avc *avc;
struct selinux_ss *ss;
};
int security_policycap_supported(unsigned int req_cap);
void selinux_ss_init(struct selinux_ss **ss);
void selinux_avc_init(struct selinux_avc **avc);
extern struct selinux_state selinux_state;
#ifdef CONFIG_SECURITY_SELINUX_DEVELOP
static inline bool enforcing_enabled(struct selinux_state *state)
{
return state->enforcing;
}
static inline void enforcing_set(struct selinux_state *state, bool value)
{
state->enforcing = value;
}
#else
static inline bool enforcing_enabled(struct selinux_state *state)
{
return true;
}
static inline void enforcing_set(struct selinux_state *state, bool value)
{
}
#endif
static inline bool selinux_policycap_netpeer(void)
{
struct selinux_state *state = &selinux_state;
return state->policycap[POLICYDB_CAPABILITY_NETPEER];
}
static inline bool selinux_policycap_openperm(void)
{
struct selinux_state *state = &selinux_state;
return state->policycap[POLICYDB_CAPABILITY_OPENPERM];
}
static inline bool selinux_policycap_extsockclass(void)
{
struct selinux_state *state = &selinux_state;
return state->policycap[POLICYDB_CAPABILITY_EXTSOCKCLASS];
}
static inline bool selinux_policycap_alwaysnetwork(void)
{
struct selinux_state *state = &selinux_state;
return state->policycap[POLICYDB_CAPABILITY_ALWAYSNETWORK];
}
static inline bool selinux_policycap_cgroupseclabel(void)
{
struct selinux_state *state = &selinux_state;
return state->policycap[POLICYDB_CAPABILITY_CGROUPSECLABEL];
}
static inline bool selinux_policycap_nnp_nosuid_transition(void)
{
struct selinux_state *state = &selinux_state;
return state->policycap[POLICYDB_CAPABILITY_NNP_NOSUID_TRANSITION];
}
int security_mls_enabled(struct selinux_state *state);
int security_load_policy(struct selinux_state *state,
void *data, size_t len);
int security_read_policy(struct selinux_state *state,
void **data, size_t *len);
size_t security_policydb_len(struct selinux_state *state);
int security_policycap_supported(struct selinux_state *state,
unsigned int req_cap);
#define SEL_VEC_MAX 32
struct av_decision {
@@ -141,76 +221,100 @@ struct extended_perms {
/* definitions of av_decision.flags */
#define AVD_FLAGS_PERMISSIVE 0x0001
void security_compute_av(u32 ssid, u32 tsid,
void security_compute_av(struct selinux_state *state,
u32 ssid, u32 tsid,
u16 tclass, struct av_decision *avd,
struct extended_perms *xperms);
void security_compute_xperms_decision(u32 ssid, u32 tsid, u16 tclass,
u8 driver, struct extended_perms_decision *xpermd);
void security_compute_xperms_decision(struct selinux_state *state,
u32 ssid, u32 tsid, u16 tclass,
u8 driver,
struct extended_perms_decision *xpermd);
void security_compute_av_user(u32 ssid, u32 tsid,
u16 tclass, struct av_decision *avd);
void security_compute_av_user(struct selinux_state *state,
u32 ssid, u32 tsid,
u16 tclass, struct av_decision *avd);
int security_transition_sid(u32 ssid, u32 tsid, u16 tclass,
int security_transition_sid(struct selinux_state *state,
u32 ssid, u32 tsid, u16 tclass,
const struct qstr *qstr, u32 *out_sid);
int security_transition_sid_user(u32 ssid, u32 tsid, u16 tclass,
int security_transition_sid_user(struct selinux_state *state,
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);
int security_member_sid(struct selinux_state *state, u32 ssid, u32 tsid,
u16 tclass, u32 *out_sid);
int security_change_sid(u32 ssid, u32 tsid,
u16 tclass, u32 *out_sid);
int security_change_sid(struct selinux_state *state, u32 ssid, u32 tsid,
u16 tclass, u32 *out_sid);
int security_sid_to_context(u32 sid, char **scontext,
u32 *scontext_len);
int security_sid_to_context(struct selinux_state *state, u32 sid,
char **scontext, u32 *scontext_len);
int security_sid_to_context_force(u32 sid, char **scontext, u32 *scontext_len);
int security_sid_to_context_force(struct selinux_state *state,
u32 sid, char **scontext, u32 *scontext_len);
int security_context_to_sid(const char *scontext, u32 scontext_len,
int security_context_to_sid(struct selinux_state *state,
const char *scontext, u32 scontext_len,
u32 *out_sid, gfp_t gfp);
int security_context_str_to_sid(const char *scontext, u32 *out_sid, gfp_t gfp);
int security_context_str_to_sid(struct selinux_state *state,
const char *scontext, u32 *out_sid, gfp_t gfp);
int security_context_to_sid_default(const char *scontext, u32 scontext_len,
int security_context_to_sid_default(struct selinux_state *state,
const char *scontext, u32 scontext_len,
u32 *out_sid, u32 def_sid, gfp_t gfp_flags);
int security_context_to_sid_force(const char *scontext, u32 scontext_len,
int security_context_to_sid_force(struct selinux_state *state,
const char *scontext, u32 scontext_len,
u32 *sid);
int security_get_user_sids(u32 callsid, char *username,
int security_get_user_sids(struct selinux_state *state,
u32 callsid, char *username,
u32 **sids, u32 *nel);
int security_port_sid(u8 protocol, u16 port, u32 *out_sid);
int security_port_sid(struct selinux_state *state,
u8 protocol, u16 port, u32 *out_sid);
int security_ib_pkey_sid(u64 subnet_prefix, u16 pkey_num, u32 *out_sid);
int security_ib_pkey_sid(struct selinux_state *state,
u64 subnet_prefix, u16 pkey_num, u32 *out_sid);
int security_ib_endport_sid(const char *dev_name, u8 port_num, u32 *out_sid);
int security_ib_endport_sid(struct selinux_state *state,
const char *dev_name, u8 port_num, u32 *out_sid);
int security_netif_sid(char *name, u32 *if_sid);
int security_netif_sid(struct selinux_state *state,
char *name, u32 *if_sid);
int security_node_sid(u16 domain, void *addr, u32 addrlen,
u32 *out_sid);
int security_node_sid(struct selinux_state *state,
u16 domain, void *addr, u32 addrlen,
u32 *out_sid);
int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid,
int security_validate_transition(struct selinux_state *state,
u32 oldsid, u32 newsid, u32 tasksid,
u16 tclass);
int security_validate_transition_user(u32 oldsid, u32 newsid, u32 tasksid,
int security_validate_transition_user(struct selinux_state *state,
u32 oldsid, u32 newsid, u32 tasksid,
u16 tclass);
int security_bounded_transition(u32 oldsid, u32 newsid);
int security_bounded_transition(struct selinux_state *state,
u32 oldsid, u32 newsid);
int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid);
int security_sid_mls_copy(struct selinux_state *state,
u32 sid, u32 mls_sid, u32 *new_sid);
int security_net_peersid_resolve(u32 nlbl_sid, u32 nlbl_type,
int security_net_peersid_resolve(struct selinux_state *state,
u32 nlbl_sid, u32 nlbl_type,
u32 xfrm_sid,
u32 *peer_sid);
int security_get_classes(char ***classes, int *nclasses);
int security_get_permissions(char *class, char ***perms, int *nperms);
int security_get_reject_unknown(void);
int security_get_allow_unknown(void);
int security_get_classes(struct selinux_state *state,
char ***classes, int *nclasses);
int security_get_permissions(struct selinux_state *state,
char *class, char ***perms, int *nperms);
int security_get_reject_unknown(struct selinux_state *state);
int security_get_allow_unknown(struct selinux_state *state);
#define SECURITY_FS_USE_XATTR 1 /* use xattr */
#define SECURITY_FS_USE_TRANS 2 /* use transition SIDs, e.g. devpts/tmpfs */
@@ -221,27 +325,31 @@ int security_get_allow_unknown(void);
#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(struct super_block *sb);
int security_fs_use(struct selinux_state *state, struct super_block *sb);
int security_genfs_sid(const char *fstype, char *name, u16 sclass,
u32 *sid);
int security_genfs_sid(struct selinux_state *state,
const char *fstype, char *name, u16 sclass,
u32 *sid);
#ifdef CONFIG_NETLABEL
int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr,
int security_netlbl_secattr_to_sid(struct selinux_state *state,
struct netlbl_lsm_secattr *secattr,
u32 *sid);
int security_netlbl_sid_to_secattr(u32 sid,
int security_netlbl_sid_to_secattr(struct selinux_state *state,
u32 sid,
struct netlbl_lsm_secattr *secattr);
#else
static inline int security_netlbl_secattr_to_sid(
static inline int security_netlbl_secattr_to_sid(struct selinux_state *state,
struct netlbl_lsm_secattr *secattr,
u32 *sid)
{
return -EIDRM;
}
static inline int security_netlbl_sid_to_secattr(u32 sid,
struct netlbl_lsm_secattr *secattr)
static inline int security_netlbl_sid_to_secattr(struct selinux_state *state,
u32 sid,
struct netlbl_lsm_secattr *secattr)
{
return -ENOENT;
}
@@ -252,7 +360,7 @@ const char *security_get_initial_sid_context(u32 sid);
/*
* status notifier using mmap interface
*/
extern struct page *selinux_kernel_status_page(void);
extern struct page *selinux_kernel_status_page(struct selinux_state *state);
#define SELINUX_KERNEL_STATUS_VERSION 1
struct selinux_kernel_status {
@@ -266,10 +374,12 @@ struct selinux_kernel_status {
*/
} __packed;
extern void selinux_status_update_setenforce(int enforcing);
extern void selinux_status_update_policyload(int seqno);
extern void selinux_status_update_setenforce(struct selinux_state *state,
int enforcing);
extern void selinux_status_update_policyload(struct selinux_state *state,
int seqno);
extern void selinux_complete_init(void);
extern int selinux_disable(void);
extern int selinux_disable(struct selinux_state *state);
extern void exit_sel_fs(void);
extern struct path selinux_null;
extern struct vfsmount *selinuxfs_mount;
@@ -277,5 +387,8 @@ 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_ */
extern void avtab_cache_init(void);
extern void ebitmap_cache_init(void);
extern void hashtab_cache_init(void);
#endif /* _SELINUX_SECURITY_H_ */