Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 80890
b: refs/heads/master
c: d621d35
h: refs/heads/master
v: v3
  • Loading branch information
Paul Moore authored and James Morris committed Jan 29, 2008
1 parent 7ad66a6 commit 254b427
Show file tree
Hide file tree
Showing 7 changed files with 133 additions and 23 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 220deb966ea51e0dedb6a187c0763120809f3e64
refs/heads/master: d621d35e576aa20a0ddae8022c3810f38357c8ff
45 changes: 37 additions & 8 deletions trunk/include/linux/selinux.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,16 +120,35 @@ void selinux_get_task_sid(struct task_struct *tsk, u32 *sid);
int selinux_string_to_sid(char *str, u32 *sid);

/**
* selinux_relabel_packet_permission - check permission to relabel a packet
* @sid: ID value to be applied to network packet (via SECMARK, most likely)
* selinux_secmark_relabel_packet_permission - secmark permission check
* @sid: SECMARK ID value to be applied to network packet
*
* Returns 0 if the current task is allowed to label packets with the
* supplied security ID. Note that it is implicit that the packet is always
* being relabeled from the default unlabled value, and that the access
* control decision is made in the AVC.
* Returns 0 if the current task is allowed to set the SECMARK label of
* packets with the supplied security ID. Note that it is implicit that
* the packet is always being relabeled from the default unlabeled value,
* and that the access control decision is made in the AVC.
*/
int selinux_relabel_packet_permission(u32 sid);
int selinux_secmark_relabel_packet_permission(u32 sid);

/**
* selinux_secmark_refcount_inc - increments the secmark use counter
*
* SELinux keeps track of the current SECMARK targets in use so it knows
* when to apply SECMARK label access checks to network packets. This
* function incements this reference count to indicate that a new SECMARK
* target has been configured.
*/
void selinux_secmark_refcount_inc(void);

/**
* selinux_secmark_refcount_dec - decrements the secmark use counter
*
* SELinux keeps track of the current SECMARK targets in use so it knows
* when to apply SECMARK label access checks to network packets. This
* function decements this reference count to indicate that one of the
* existing SECMARK targets has been removed/flushed.
*/
void selinux_secmark_refcount_dec(void);
#else

static inline int selinux_audit_rule_init(u32 field, u32 op,
Expand Down Expand Up @@ -184,11 +203,21 @@ static inline int selinux_string_to_sid(const char *str, u32 *sid)
return 0;
}

static inline int selinux_relabel_packet_permission(u32 sid)
static inline int selinux_secmark_relabel_packet_permission(u32 sid)
{
return 0;
}

static inline void selinux_secmark_refcount_inc(void)
{
return;
}

static inline void selinux_secmark_refcount_dec(void)
{
return;
}

#endif /* CONFIG_SECURITY_SELINUX */

#endif /* _LINUX_SELINUX_H */
13 changes: 12 additions & 1 deletion trunk/net/netfilter/xt_SECMARK.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,13 @@ static bool checkentry_selinux(struct xt_secmark_target_info *info)
return false;
}

err = selinux_relabel_packet_permission(sel->selsid);
err = selinux_secmark_relabel_packet_permission(sel->selsid);
if (err) {
printk(KERN_INFO PFX "unable to obtain relabeling permission\n");
return false;
}

selinux_secmark_refcount_inc();
return true;
}

Expand Down Expand Up @@ -110,11 +111,20 @@ secmark_tg_check(const char *tablename, const void *entry,
return true;
}

void secmark_tg_destroy(const struct xt_target *target, void *targinfo)
{
switch (mode) {
case SECMARK_MODE_SEL:
selinux_secmark_refcount_dec();
}
}

static struct xt_target secmark_tg_reg[] __read_mostly = {
{
.name = "SECMARK",
.family = AF_INET,
.checkentry = secmark_tg_check,
.destroy = secmark_tg_destroy,
.target = secmark_tg,
.targetsize = sizeof(struct xt_secmark_target_info),
.table = "mangle",
Expand All @@ -124,6 +134,7 @@ static struct xt_target secmark_tg_reg[] __read_mostly = {
.name = "SECMARK",
.family = AF_INET6,
.checkentry = secmark_tg_check,
.destroy = secmark_tg_destroy,
.target = secmark_tg,
.targetsize = sizeof(struct xt_secmark_target_info),
.table = "mangle",
Expand Down
20 changes: 18 additions & 2 deletions trunk/security/selinux/exports.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,14 @@
#include <linux/selinux.h>
#include <linux/fs.h>
#include <linux/ipc.h>
#include <asm/atomic.h>

#include "security.h"
#include "objsec.h"

/* SECMARK reference count */
extern atomic_t selinux_secmark_refcount;

int selinux_sid_to_string(u32 sid, char **ctx, u32 *ctxlen)
{
if (selinux_enabled)
Expand Down Expand Up @@ -74,7 +78,7 @@ int selinux_string_to_sid(char *str, u32 *sid)
}
EXPORT_SYMBOL_GPL(selinux_string_to_sid);

int selinux_relabel_packet_permission(u32 sid)
int selinux_secmark_relabel_packet_permission(u32 sid)
{
if (selinux_enabled) {
struct task_security_struct *tsec = current->security;
Expand All @@ -84,4 +88,16 @@ int selinux_relabel_packet_permission(u32 sid)
}
return 0;
}
EXPORT_SYMBOL_GPL(selinux_relabel_packet_permission);
EXPORT_SYMBOL_GPL(selinux_secmark_relabel_packet_permission);

void selinux_secmark_refcount_inc(void)
{
atomic_inc(&selinux_secmark_refcount);
}
EXPORT_SYMBOL_GPL(selinux_secmark_refcount_inc);

void selinux_secmark_refcount_dec(void)
{
atomic_dec(&selinux_secmark_refcount);
}
EXPORT_SYMBOL_GPL(selinux_secmark_refcount_dec);
46 changes: 37 additions & 9 deletions trunk/security/selinux/hooks.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,10 @@
#include <net/ip.h> /* for local_port_range[] */
#include <net/tcp.h> /* struct or_callable used in sock_rcv_skb */
#include <net/net_namespace.h>
#include <net/netlabel.h>
#include <asm/uaccess.h>
#include <asm/ioctls.h>
#include <asm/atomic.h>
#include <linux/bitops.h>
#include <linux/interrupt.h>
#include <linux/netdevice.h> /* for network interface checks */
Expand Down Expand Up @@ -91,6 +93,9 @@ extern int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm);
extern int selinux_compat_net;
extern struct security_operations *security_ops;

/* SECMARK reference count */
atomic_t selinux_secmark_refcount = ATOMIC_INIT(0);

#ifdef CONFIG_SECURITY_SELINUX_DEVELOP
int selinux_enforcing = 0;

Expand Down Expand Up @@ -157,6 +162,21 @@ static int selinux_getsecurity(u32 sid, void *buffer, size_t size)
return len;
}

/**
* selinux_secmark_enabled - Check to see if SECMARK is currently enabled
*
* Description:
* 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.
*
*/
static int selinux_secmark_enabled(void)
{
return (atomic_read(&selinux_secmark_refcount) > 0);
}

/* Allocate and free functions for each kind of security blob. */

static int task_alloc_security(struct task_struct *task)
Expand Down Expand Up @@ -3931,7 +3951,6 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
struct sk_security_struct *sksec = sk->sk_security;
u16 family = sk->sk_family;
u32 sk_sid = sksec->sid;
u32 peer_sid;
struct avc_audit_data ad;
char *addrp;

Expand All @@ -3957,15 +3976,24 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
return selinux_sock_rcv_skb_compat(sk, skb, &ad,
family, addrp);

err = avc_has_perm(sk_sid, skb->secmark, SECCLASS_PACKET,
PACKET__RECV, &ad);
if (err)
return err;
if (selinux_secmark_enabled()) {
err = avc_has_perm(sk_sid, skb->secmark, SECCLASS_PACKET,
PACKET__RECV, &ad);
if (err)
return err;
}

err = selinux_skb_peerlbl_sid(skb, family, &peer_sid);
if (err)
return err;
return avc_has_perm(sk_sid, peer_sid, SECCLASS_PEER, PEER__RECV, &ad);
if (netlbl_enabled() || selinux_xfrm_enabled()) {
u32 peer_sid;

err = selinux_skb_peerlbl_sid(skb, family, &peer_sid);
if (err)
return err;
err = avc_has_perm(sk_sid, peer_sid, SECCLASS_PEER,
PEER__RECV, &ad);
}

return err;
}

static int selinux_socket_getpeersec_stream(struct socket *sock, char __user *optval,
Expand Down
12 changes: 12 additions & 0 deletions trunk/security/selinux/include/xfrm.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@ static inline struct inode_security_struct *get_sock_isec(struct sock *sk)
}

#ifdef CONFIG_SECURITY_NETWORK_XFRM
extern atomic_t selinux_xfrm_refcount;

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 avc_audit_data *ad);
int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb,
Expand All @@ -43,6 +50,11 @@ static inline void selinux_xfrm_notify_policyload(void)
atomic_inc(&flow_cache_genid);
}
#else
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 avc_audit_data *ad)
{
Expand Down
18 changes: 16 additions & 2 deletions trunk/security/selinux/xfrm.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,14 @@
#include <net/checksum.h>
#include <net/udp.h>
#include <asm/semaphore.h>
#include <asm/atomic.h>

#include "avc.h"
#include "objsec.h"
#include "xfrm.h"

/* Labeled XFRM instance counter */
atomic_t selinux_xfrm_refcount = ATOMIC_INIT(0);

/*
* Returns true if an LSM/SELinux context
Expand Down Expand Up @@ -293,6 +296,9 @@ int selinux_xfrm_policy_alloc(struct xfrm_policy *xp,
BUG_ON(!uctx);

err = selinux_xfrm_sec_ctx_alloc(&xp->security, uctx, 0);
if (err == 0)
atomic_inc(&selinux_xfrm_refcount);

return err;
}

Expand Down Expand Up @@ -340,10 +346,13 @@ int selinux_xfrm_policy_delete(struct xfrm_policy *xp)
struct xfrm_sec_ctx *ctx = xp->security;
int rc = 0;

if (ctx)
if (ctx) {
rc = avc_has_perm(tsec->sid, ctx->ctx_sid,
SECCLASS_ASSOCIATION,
ASSOCIATION__SETCONTEXT, NULL);
if (rc == 0)
atomic_dec(&selinux_xfrm_refcount);
}

return rc;
}
Expand All @@ -360,6 +369,8 @@ int selinux_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *uct
BUG_ON(!x);

err = selinux_xfrm_sec_ctx_alloc(&x->security, uctx, secid);
if (err == 0)
atomic_inc(&selinux_xfrm_refcount);
return err;
}

Expand All @@ -382,10 +393,13 @@ int selinux_xfrm_state_delete(struct xfrm_state *x)
struct xfrm_sec_ctx *ctx = x->security;
int rc = 0;

if (ctx)
if (ctx) {
rc = avc_has_perm(tsec->sid, ctx->ctx_sid,
SECCLASS_ASSOCIATION,
ASSOCIATION__SETCONTEXT, NULL);
if (rc == 0)
atomic_dec(&selinux_xfrm_refcount);
}

return rc;
}
Expand Down

0 comments on commit 254b427

Please sign in to comment.