Commit 6f799c97 authored by James Morris's avatar James Morris

Merge branch 'master' of git://git.infradead.org/users/pcmoore/selinux into ra-next

parents eb8948a0 42d64e1a
...@@ -1052,17 +1052,25 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) ...@@ -1052,17 +1052,25 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
* @xfrm_policy_delete_security: * @xfrm_policy_delete_security:
* @ctx contains the xfrm_sec_ctx. * @ctx contains the xfrm_sec_ctx.
* Authorize deletion of xp->security. * Authorize deletion of xp->security.
* @xfrm_state_alloc_security: * @xfrm_state_alloc:
* @x contains the xfrm_state being added to the Security Association * @x contains the xfrm_state being added to the Security Association
* Database by the XFRM system. * Database by the XFRM system.
* @sec_ctx contains the security context information being provided by * @sec_ctx contains the security context information being provided by
* the user-level SA generation program (e.g., setkey or racoon). * the user-level SA generation program (e.g., setkey or racoon).
* @secid contains the secid from which to take the mls portion of the context.
* Allocate a security structure to the x->security field; the security * Allocate a security structure to the x->security field; the security
* field is initialized to NULL when the xfrm_state is allocated. Set the * field is initialized to NULL when the xfrm_state is allocated. Set the
* context to correspond to either sec_ctx or polsec, with the mls portion * context to correspond to sec_ctx. Return 0 if operation was successful
* taken from secid in the latter case. * (memory to allocate, legal context).
* Return 0 if operation was successful (memory to allocate, legal context). * @xfrm_state_alloc_acquire:
* @x contains the xfrm_state being added to the Security Association
* Database by the XFRM system.
* @polsec contains the policy's security context.
* @secid contains the secid from which to take the mls portion of the
* context.
* Allocate a security structure to the x->security field; the security
* field is initialized to NULL when the xfrm_state is allocated. Set the
* context to correspond to secid. Return 0 if operation was successful
* (memory to allocate, legal context).
* @xfrm_state_free_security: * @xfrm_state_free_security:
* @x contains the xfrm_state. * @x contains the xfrm_state.
* Deallocate x->security. * Deallocate x->security.
...@@ -1679,9 +1687,11 @@ struct security_operations { ...@@ -1679,9 +1687,11 @@ struct security_operations {
int (*xfrm_policy_clone_security) (struct xfrm_sec_ctx *old_ctx, struct xfrm_sec_ctx **new_ctx); int (*xfrm_policy_clone_security) (struct xfrm_sec_ctx *old_ctx, struct xfrm_sec_ctx **new_ctx);
void (*xfrm_policy_free_security) (struct xfrm_sec_ctx *ctx); void (*xfrm_policy_free_security) (struct xfrm_sec_ctx *ctx);
int (*xfrm_policy_delete_security) (struct xfrm_sec_ctx *ctx); int (*xfrm_policy_delete_security) (struct xfrm_sec_ctx *ctx);
int (*xfrm_state_alloc_security) (struct xfrm_state *x, int (*xfrm_state_alloc) (struct xfrm_state *x,
struct xfrm_user_sec_ctx *sec_ctx, struct xfrm_user_sec_ctx *sec_ctx);
u32 secid); int (*xfrm_state_alloc_acquire) (struct xfrm_state *x,
struct xfrm_sec_ctx *polsec,
u32 secid);
void (*xfrm_state_free_security) (struct xfrm_state *x); void (*xfrm_state_free_security) (struct xfrm_state *x);
int (*xfrm_state_delete_security) (struct xfrm_state *x); int (*xfrm_state_delete_security) (struct xfrm_state *x);
int (*xfrm_policy_lookup) (struct xfrm_sec_ctx *ctx, u32 fl_secid, u8 dir); int (*xfrm_policy_lookup) (struct xfrm_sec_ctx *ctx, u32 fl_secid, u8 dir);
......
...@@ -777,9 +777,15 @@ static int cap_xfrm_policy_delete_security(struct xfrm_sec_ctx *ctx) ...@@ -777,9 +777,15 @@ static int cap_xfrm_policy_delete_security(struct xfrm_sec_ctx *ctx)
return 0; return 0;
} }
static int cap_xfrm_state_alloc_security(struct xfrm_state *x, static int cap_xfrm_state_alloc(struct xfrm_state *x,
struct xfrm_user_sec_ctx *sec_ctx, struct xfrm_user_sec_ctx *sec_ctx)
u32 secid) {
return 0;
}
static int cap_xfrm_state_alloc_acquire(struct xfrm_state *x,
struct xfrm_sec_ctx *polsec,
u32 secid)
{ {
return 0; return 0;
} }
...@@ -1101,7 +1107,8 @@ void __init security_fixup_ops(struct security_operations *ops) ...@@ -1101,7 +1107,8 @@ void __init security_fixup_ops(struct security_operations *ops)
set_to_cap_if_null(ops, xfrm_policy_clone_security); set_to_cap_if_null(ops, xfrm_policy_clone_security);
set_to_cap_if_null(ops, xfrm_policy_free_security); set_to_cap_if_null(ops, xfrm_policy_free_security);
set_to_cap_if_null(ops, xfrm_policy_delete_security); set_to_cap_if_null(ops, xfrm_policy_delete_security);
set_to_cap_if_null(ops, xfrm_state_alloc_security); set_to_cap_if_null(ops, xfrm_state_alloc);
set_to_cap_if_null(ops, xfrm_state_alloc_acquire);
set_to_cap_if_null(ops, xfrm_state_free_security); set_to_cap_if_null(ops, xfrm_state_free_security);
set_to_cap_if_null(ops, xfrm_state_delete_security); set_to_cap_if_null(ops, xfrm_state_delete_security);
set_to_cap_if_null(ops, xfrm_policy_lookup); set_to_cap_if_null(ops, xfrm_policy_lookup);
......
...@@ -1340,22 +1340,17 @@ int security_xfrm_policy_delete(struct xfrm_sec_ctx *ctx) ...@@ -1340,22 +1340,17 @@ int security_xfrm_policy_delete(struct xfrm_sec_ctx *ctx)
return security_ops->xfrm_policy_delete_security(ctx); return security_ops->xfrm_policy_delete_security(ctx);
} }
int security_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx) int security_xfrm_state_alloc(struct xfrm_state *x,
struct xfrm_user_sec_ctx *sec_ctx)
{ {
return security_ops->xfrm_state_alloc_security(x, sec_ctx, 0); return security_ops->xfrm_state_alloc(x, sec_ctx);
} }
EXPORT_SYMBOL(security_xfrm_state_alloc); EXPORT_SYMBOL(security_xfrm_state_alloc);
int security_xfrm_state_alloc_acquire(struct xfrm_state *x, int security_xfrm_state_alloc_acquire(struct xfrm_state *x,
struct xfrm_sec_ctx *polsec, u32 secid) struct xfrm_sec_ctx *polsec, u32 secid)
{ {
if (!polsec) return security_ops->xfrm_state_alloc_acquire(x, polsec, secid);
return 0;
/*
* We want the context to be taken from secid which is usually
* from the sock.
*/
return security_ops->xfrm_state_alloc_security(x, NULL, secid);
} }
int security_xfrm_state_delete(struct xfrm_state *x) int security_xfrm_state_delete(struct xfrm_state *x)
......
This diff is collapsed.
...@@ -58,8 +58,8 @@ struct superblock_security_struct { ...@@ -58,8 +58,8 @@ struct superblock_security_struct {
u32 sid; /* SID of file system superblock */ u32 sid; /* SID of file system superblock */
u32 def_sid; /* default SID for labeling */ u32 def_sid; /* default SID for labeling */
u32 mntpoint_sid; /* SECURITY_FS_USE_MNTPOINT context for files */ u32 mntpoint_sid; /* SECURITY_FS_USE_MNTPOINT context for files */
unsigned int behavior; /* labeling behavior */ unsigned short behavior; /* labeling behavior */
unsigned char flags; /* which mount options were specified */ unsigned short flags; /* which mount options were specified */
struct mutex lock; struct mutex lock;
struct list_head isec_head; struct list_head isec_head;
spinlock_t isec_lock; spinlock_t isec_lock;
......
...@@ -45,14 +45,15 @@ ...@@ -45,14 +45,15 @@
/* Mask for just the mount related flags */ /* Mask for just the mount related flags */
#define SE_MNTMASK 0x0f #define SE_MNTMASK 0x0f
/* Super block security struct flags for mount options */ /* 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 CONTEXT_MNT 0x01
#define FSCONTEXT_MNT 0x02 #define FSCONTEXT_MNT 0x02
#define ROOTCONTEXT_MNT 0x04 #define ROOTCONTEXT_MNT 0x04
#define DEFCONTEXT_MNT 0x08 #define DEFCONTEXT_MNT 0x08
#define SBLABEL_MNT 0x10
/* Non-mount related flags */ /* Non-mount related flags */
#define SE_SBINITIALIZED 0x10 #define SE_SBINITIALIZED 0x0100
#define SE_SBPROC 0x20 #define SE_SBPROC 0x0200
#define SE_SBLABELSUPP 0x40
#define CONTEXT_STR "context=" #define CONTEXT_STR "context="
#define FSCONTEXT_STR "fscontext=" #define FSCONTEXT_STR "fscontext="
...@@ -68,12 +69,15 @@ extern int selinux_enabled; ...@@ -68,12 +69,15 @@ extern int selinux_enabled;
enum { enum {
POLICYDB_CAPABILITY_NETPEER, POLICYDB_CAPABILITY_NETPEER,
POLICYDB_CAPABILITY_OPENPERM, POLICYDB_CAPABILITY_OPENPERM,
POLICYDB_CAPABILITY_REDHAT1,
POLICYDB_CAPABILITY_ALWAYSNETWORK,
__POLICYDB_CAPABILITY_MAX __POLICYDB_CAPABILITY_MAX
}; };
#define POLICYDB_CAPABILITY_MAX (__POLICYDB_CAPABILITY_MAX - 1) #define POLICYDB_CAPABILITY_MAX (__POLICYDB_CAPABILITY_MAX - 1)
extern int selinux_policycap_netpeer; extern int selinux_policycap_netpeer;
extern int selinux_policycap_openperm; extern int selinux_policycap_openperm;
extern int selinux_policycap_alwaysnetwork;
/* /*
* type_datum properties * type_datum properties
...@@ -172,8 +176,7 @@ int security_get_allow_unknown(void); ...@@ -172,8 +176,7 @@ int security_get_allow_unknown(void);
#define SECURITY_FS_USE_NATIVE 7 /* use native label support */ #define SECURITY_FS_USE_NATIVE 7 /* use native label support */
#define SECURITY_FS_USE_MAX 7 /* Highest SECURITY_FS_USE_XXX */ #define SECURITY_FS_USE_MAX 7 /* Highest SECURITY_FS_USE_XXX */
int security_fs_use(const char *fstype, unsigned int *behavior, int security_fs_use(struct super_block *sb);
u32 *sid);
int security_genfs_sid(const char *fstype, char *name, u16 sclass, int security_genfs_sid(const char *fstype, char *name, u16 sclass,
u32 *sid); u32 *sid);
......
...@@ -10,29 +10,21 @@ ...@@ -10,29 +10,21 @@
#include <net/flow.h> #include <net/flow.h>
int selinux_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp, int selinux_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp,
struct xfrm_user_sec_ctx *sec_ctx); struct xfrm_user_sec_ctx *uctx);
int selinux_xfrm_policy_clone(struct xfrm_sec_ctx *old_ctx, int selinux_xfrm_policy_clone(struct xfrm_sec_ctx *old_ctx,
struct xfrm_sec_ctx **new_ctxp); struct xfrm_sec_ctx **new_ctxp);
void selinux_xfrm_policy_free(struct xfrm_sec_ctx *ctx); void selinux_xfrm_policy_free(struct xfrm_sec_ctx *ctx);
int selinux_xfrm_policy_delete(struct xfrm_sec_ctx *ctx); int selinux_xfrm_policy_delete(struct xfrm_sec_ctx *ctx);
int selinux_xfrm_state_alloc(struct xfrm_state *x, 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); void selinux_xfrm_state_free(struct xfrm_state *x);
int selinux_xfrm_state_delete(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_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid, u8 dir);
int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x, int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x,
struct xfrm_policy *xp, const struct flowi *fl); struct xfrm_policy *xp,
const 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;
}
#ifdef CONFIG_SECURITY_NETWORK_XFRM #ifdef CONFIG_SECURITY_NETWORK_XFRM
extern atomic_t selinux_xfrm_refcount; extern atomic_t selinux_xfrm_refcount;
...@@ -42,10 +34,10 @@ static inline int selinux_xfrm_enabled(void) ...@@ -42,10 +34,10 @@ static inline int selinux_xfrm_enabled(void)
return (atomic_read(&selinux_xfrm_refcount) > 0); return (atomic_read(&selinux_xfrm_refcount) > 0);
} }
int selinux_xfrm_sock_rcv_skb(u32 sid, struct sk_buff *skb, int selinux_xfrm_sock_rcv_skb(u32 sk_sid, struct sk_buff *skb,
struct common_audit_data *ad); struct common_audit_data *ad);
int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb, int selinux_xfrm_postroute_last(u32 sk_sid, struct sk_buff *skb,
struct common_audit_data *ad, u8 proto); struct common_audit_data *ad, u8 proto);
int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall); int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall);
static inline void selinux_xfrm_notify_policyload(void) static inline void selinux_xfrm_notify_policyload(void)
...@@ -64,19 +56,21 @@ static inline int selinux_xfrm_enabled(void) ...@@ -64,19 +56,21 @@ static inline int selinux_xfrm_enabled(void)
return 0; return 0;
} }
static inline int selinux_xfrm_sock_rcv_skb(u32 isec_sid, struct sk_buff *skb, static inline int selinux_xfrm_sock_rcv_skb(u32 sk_sid, struct sk_buff *skb,
struct common_audit_data *ad) struct common_audit_data *ad)
{ {
return 0; return 0;
} }
static inline int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb, static inline int selinux_xfrm_postroute_last(u32 sk_sid, struct sk_buff *skb,
struct common_audit_data *ad, u8 proto) struct common_audit_data *ad,
u8 proto)
{ {
return 0; 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; *sid = SECSID_NULL;
return 0; return 0;
...@@ -87,10 +81,9 @@ static inline void selinux_xfrm_notify_policyload(void) ...@@ -87,10 +81,9 @@ static inline void selinux_xfrm_notify_policyload(void)
} }
#endif #endif
static inline void selinux_skb_xfrm_sid(struct sk_buff *skb, u32 *sid) static inline int selinux_skb_xfrm_sid(struct sk_buff *skb, u32 *sid)
{ {
int err = selinux_xfrm_decode_session(skb, sid, 0); return selinux_xfrm_decode_session(skb, sid, 0);
BUG_ON(err);
} }
#endif /* _SELINUX_XFRM_H_ */ #endif /* _SELINUX_XFRM_H_ */
...@@ -442,8 +442,7 @@ int selinux_netlbl_socket_connect(struct sock *sk, struct sockaddr *addr) ...@@ -442,8 +442,7 @@ int selinux_netlbl_socket_connect(struct sock *sk, struct sockaddr *addr)
sksec->nlbl_state != NLBL_CONNLABELED) sksec->nlbl_state != NLBL_CONNLABELED)
return 0; return 0;
local_bh_disable(); lock_sock(sk);
bh_lock_sock_nested(sk);
/* connected sockets are allowed to disconnect when the address family /* connected sockets are allowed to disconnect when the address family
* is set to AF_UNSPEC, if that is what is happening we want to reset * is set to AF_UNSPEC, if that is what is happening we want to reset
...@@ -464,7 +463,6 @@ int selinux_netlbl_socket_connect(struct sock *sk, struct sockaddr *addr) ...@@ -464,7 +463,6 @@ int selinux_netlbl_socket_connect(struct sock *sk, struct sockaddr *addr)
sksec->nlbl_state = NLBL_CONNLABELED; sksec->nlbl_state = NLBL_CONNLABELED;
socket_connect_return: socket_connect_return:
bh_unlock_sock(sk); release_sock(sk);
local_bh_enable();
return rc; return rc;
} }
...@@ -166,6 +166,7 @@ static void sel_netnode_insert(struct sel_netnode *node) ...@@ -166,6 +166,7 @@ static void sel_netnode_insert(struct sel_netnode *node)
break; break;
default: default:
BUG(); BUG();
return;
} }
/* we need to impose a limit on the growth of the hash table so check /* we need to impose a limit on the growth of the hash table so check
...@@ -225,6 +226,7 @@ static int sel_netnode_sid_slow(void *addr, u16 family, u32 *sid) ...@@ -225,6 +226,7 @@ static int sel_netnode_sid_slow(void *addr, u16 family, u32 *sid)
break; break;
default: default:
BUG(); BUG();
ret = -EINVAL;
} }
if (ret != 0) if (ret != 0)
goto out; goto out;
......
...@@ -44,7 +44,9 @@ ...@@ -44,7 +44,9 @@
/* Policy capability filenames */ /* Policy capability filenames */
static char *policycap_names[] = { static char *policycap_names[] = {
"network_peer_controls", "network_peer_controls",
"open_perms" "open_perms",
"redhat1",
"always_check_network"
}; };
unsigned int selinux_checkreqprot = CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE; unsigned int selinux_checkreqprot = CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE;
......
...@@ -213,7 +213,12 @@ int ebitmap_netlbl_import(struct ebitmap *ebmap, ...@@ -213,7 +213,12 @@ int ebitmap_netlbl_import(struct ebitmap *ebmap,
} }
#endif /* CONFIG_NETLABEL */ #endif /* CONFIG_NETLABEL */
int ebitmap_contains(struct ebitmap *e1, struct ebitmap *e2) /*
* Check to see if all the bits set in e2 are also set in e1. Optionally,
* if last_e2bit is non-zero, the highest set bit in e2 cannot exceed
* last_e2bit.
*/
int ebitmap_contains(struct ebitmap *e1, struct ebitmap *e2, u32 last_e2bit)
{ {
struct ebitmap_node *n1, *n2; struct ebitmap_node *n1, *n2;
int i; int i;
...@@ -223,14 +228,25 @@ int ebitmap_contains(struct ebitmap *e1, struct ebitmap *e2) ...@@ -223,14 +228,25 @@ int ebitmap_contains(struct ebitmap *e1, struct ebitmap *e2)
n1 = e1->node; n1 = e1->node;
n2 = e2->node; n2 = e2->node;
while (n1 && n2 && (n1->startbit <= n2->startbit)) { while (n1 && n2 && (n1->startbit <= n2->startbit)) {
if (n1->startbit < n2->startbit) { if (n1->startbit < n2->startbit) {
n1 = n1->next; n1 = n1->next;
continue; continue;
} }
for (i = 0; i < EBITMAP_UNIT_NUMS; i++) { for (i = EBITMAP_UNIT_NUMS - 1; (i >= 0) && !n2->maps[i]; )
i--; /* Skip trailing NULL map entries */
if (last_e2bit && (i >= 0)) {
u32 lastsetbit = n2->startbit + i * EBITMAP_UNIT_SIZE +
__fls(n2->maps[i]);
if (lastsetbit > last_e2bit)
return 0;
}
while (i >= 0) {
if ((n1->maps[i] & n2->maps[i]) != n2->maps[i]) if ((n1->maps[i] & n2->maps[i]) != n2->maps[i])
return 0; return 0;
i--;
} }
n1 = n1->next; n1 = n1->next;
......
...@@ -16,7 +16,13 @@ ...@@ -16,7 +16,13 @@
#include <net/netlabel.h> #include <net/netlabel.h>
#define EBITMAP_UNIT_NUMS ((32 - sizeof(void *) - sizeof(u32)) \ #ifdef CONFIG_64BIT
#define EBITMAP_NODE_SIZE 64
#else
#define EBITMAP_NODE_SIZE 32
#endif
#define EBITMAP_UNIT_NUMS ((EBITMAP_NODE_SIZE-sizeof(void *)-sizeof(u32))\
/ sizeof(unsigned long)) / sizeof(unsigned long))
#define EBITMAP_UNIT_SIZE BITS_PER_LONG #define EBITMAP_UNIT_SIZE BITS_PER_LONG
#define EBITMAP_SIZE (EBITMAP_UNIT_NUMS * EBITMAP_UNIT_SIZE) #define EBITMAP_SIZE (EBITMAP_UNIT_NUMS * EBITMAP_UNIT_SIZE)
...@@ -117,7 +123,7 @@ static inline void ebitmap_node_clr_bit(struct ebitmap_node *n, ...@@ -117,7 +123,7 @@ static inline void ebitmap_node_clr_bit(struct ebitmap_node *n,
int ebitmap_cmp(struct ebitmap *e1, struct ebitmap *e2); int ebitmap_cmp(struct ebitmap *e1, struct ebitmap *e2);
int ebitmap_cpy(struct ebitmap *dst, struct ebitmap *src); int ebitmap_cpy(struct ebitmap *dst, struct ebitmap *src);
int ebitmap_contains(struct ebitmap *e1, struct ebitmap *e2); int ebitmap_contains(struct ebitmap *e1, struct ebitmap *e2, u32 last_e2bit);
int ebitmap_get_bit(struct ebitmap *e, unsigned long bit); int ebitmap_get_bit(struct ebitmap *e, unsigned long bit);
int ebitmap_set_bit(struct ebitmap *e, unsigned long bit, int value); int ebitmap_set_bit(struct ebitmap *e, unsigned long bit, int value);
void ebitmap_destroy(struct ebitmap *e); void ebitmap_destroy(struct ebitmap *e);
......
...@@ -160,8 +160,6 @@ void mls_sid_to_context(struct context *context, ...@@ -160,8 +160,6 @@ void mls_sid_to_context(struct context *context,
int mls_level_isvalid(struct policydb *p, struct mls_level *l) int mls_level_isvalid(struct policydb *p, struct mls_level *l)
{ {
struct level_datum *levdatum; struct level_datum *levdatum;
struct ebitmap_node *node;
int i;
if (!l->sens || l->sens > p->p_levels.nprim) if (!l->sens || l->sens > p->p_levels.nprim)
return 0; return 0;
...@@ -170,19 +168,13 @@ int mls_level_isvalid(struct policydb *p, struct mls_level *l) ...@@ -170,19 +168,13 @@ int mls_level_isvalid(struct policydb *p, struct mls_level *l)
if (!levdatum) if (!levdatum)
return 0; return 0;
ebitmap_for_each_positive_bit(&l->cat, node, i) { /*
if (i > p->p_cats.nprim) * Return 1 iff all the bits set in l->cat are also be set in
return 0; * levdatum->level->cat and no bit in l->cat is larger than
if (!ebitmap_get_bit(&levdatum->level->cat, i)) { * p->p_cats.nprim.
/* */
* Category may not be associated with return ebitmap_contains(&levdatum->level->cat, &l->cat,
* sensitivity. p->p_cats.nprim);
*/
return 0;
}
}
return 1;
} }
int mls_range_isvalid(struct policydb *p, struct mls_range *r) int mls_range_isvalid(struct policydb *p, struct mls_range *r)
......
...@@ -35,7 +35,7 @@ static inline int mls_level_eq(struct mls_level *l1, struct mls_level *l2) ...@@ -35,7 +35,7 @@ static inline int mls_level_eq(struct mls_level *l1, struct mls_level *l2)
static inline int mls_level_dom(struct mls_level *l1, struct mls_level *l2) static inline int mls_level_dom(struct mls_level *l1, struct mls_level *l2)
{ {
return ((l1->sens >= l2->sens) && return ((l1->sens >= l2->sens) &&
ebitmap_contains(&l1->cat, &l2->cat)); ebitmap_contains(&l1->cat, &l2->cat, 0));
} }
#define mls_level_incomp(l1, l2) \ #define mls_level_incomp(l1, l2) \
......
...@@ -3203,9 +3203,8 @@ static int range_write_helper(void *key, void *data, void *ptr) ...@@ -3203,9 +3203,8 @@ static int range_write_helper(void *key, void *data, void *ptr)
static int range_write(struct policydb *p, void *fp) static int range_write(struct policydb *p, void *fp)
{ {
size_t nel;
__le32 buf[1]; __le32 buf[1];
int rc; int rc, nel;
struct policy_data pd; struct policy_data pd;
pd.p = p; pd.p = p;
......
...@@ -72,6 +72,7 @@ ...@@ -72,6 +72,7 @@
int selinux_policycap_netpeer; int selinux_policycap_netpeer;
int selinux_policycap_openperm; int selinux_policycap_openperm;
int selinux_policycap_alwaysnetwork;
static DEFINE_RWLOCK(policy_rwlock); static DEFINE_RWLOCK(policy_rwlock);
...@@ -1812,6 +1813,8 @@ static void security_load_policycaps(void) ...@@ -1812,6 +1813,8 @@ static void security_load_policycaps(void)
POLICYDB_CAPABILITY_NETPEER); POLICYDB_CAPABILITY_NETPEER);
selinux_policycap_openperm = ebitmap_get_bit(&policydb.policycaps, selinux_policycap_openperm = ebitmap_get_bit(&policydb.policycaps,
POLICYDB_CAPABILITY_OPENPERM); POLICYDB_CAPABILITY_OPENPERM);
selinux_policycap_alwaysnetwork = ebitmap_get_bit(&policydb.policycaps,
POLICYDB_CAPABILITY_ALWAYSNETWORK);
} }
static int security_preserve_bools(struct policydb *p); static int security_preserve_bools(struct policydb *p);
...@@ -2323,43 +2326,74 @@ int security_genfs_sid(const char *fstype, ...@@ -2323,43 +2326,74 @@ int security_genfs_sid(const char *fstype,
/** /**
* security_fs_use - Determine how to handle labeling for a filesystem. * security_fs_use - Determine how to handle labeling for a filesystem.
* @fstype: filesystem type * @sb: superblock in question
* @behavior: labeling behavior
* @sid: SID for filesystem (superblock)
*/ */
int security_fs_use( int security_fs_use(struct super_block *sb)
const char *fstype,
unsigned int *behavior,
u32 *sid)
{ {
int rc = 0; int rc = 0;
struct ocontext *c; struct ocontext *c;
struct superblock_security_struct *sbsec = sb->s_security;
const char *fstype = sb->s_type->name;
const char *subtype = (sb->s_subtype && sb->s_subtype[0]) ? sb->s_subtype : NULL;
struct ocontext *base = NULL;
read_lock(&policy_rwlock); read_lock(&policy_rwlock);
c = policydb.ocontexts[OCON_FSUSE]; for (c = policydb.ocontexts[OCON_FSUSE]; c; c = c->next) {
while (c) { char *sub;
if (strcmp(fstype, c->u.name) == 0) int baselen;
baselen = strlen(fstype);
/* if base does not match, this is not the one */
if (strncmp(fstype, c->u.name, baselen))
continue;
/* if there is no subtype, this is the one! */
if (!subtype)
break;
/* skip past the base in this entry */
sub = c->u.name + baselen;
/* entry is only a base. save it. keep looking for subtype */
if (sub[0] == '\0') {
base = c;
continue;
}
/* entry is not followed by a subtype, so it is not a match */
if (sub[0] != '.')
continue;
/* whew, we found a subtype of this fstype */
sub++; /* move past '.' */
/* exact match of fstype AND subtype */
if (!strcmp(subtype, sub))
break; break;
c = c->next;
} }
/* in case we had found an fstype match but no subtype match */
if (!c)
c = base;
if (c) { if (c) {
*behavior = c->v.behavior; sbsec->behavior = c->v.behavior;
if (!c->sid[0]) { if (!c->sid[0]) {
rc = sidtab_context_to_sid(&sidtab, &c->context[0], rc = sidtab_context_to_sid(&sidtab, &c->context[0],
&c->sid[0]); &c->sid[0]);
if (rc) if (rc)
goto out; goto out;
} }
*sid = c->sid[0]; sbsec->sid = c->sid[0];
} else { } else {
rc = security_genfs_sid(fstype, "/", SECCLASS_DIR, sid); rc = security_genfs_sid(fstype, "/", SECCLASS_DIR, &sbsec->sid);
if (rc) { if (rc) {
*behavior = SECURITY_FS_USE_NONE; sbsec->behavior = SECURITY_FS_USE_NONE;
rc = 0; rc = 0;
} else { } else {
*behavior = SECURITY_FS_USE_GENFS; sbsec->behavior = SECURITY_FS_USE_GENFS;
} }
} }
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment