Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3bb56b25 authored by Paul Moore's avatar Paul Moore Committed by James Morris
Browse files

SELinux: Add a capabilities bitmap to SELinux policy version 22



Add a new policy capabilities bitmap to SELinux policy version 22.  This bitmap
will enable the security server to query the policy to determine which features
it supports.

Signed-off-by: default avatarPaul Moore <paul.moore@hp.com>
Signed-off-by: default avatarJames Morris <jmorris@namei.org>
parent 224dfbd8
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -145,7 +145,7 @@ config SECURITY_SELINUX_POLICYDB_VERSION_MAX
config SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE
	int "NSA SELinux maximum supported policy format version value"
	depends on SECURITY_SELINUX_POLICYDB_VERSION_MAX
	range 15 21
	range 15 22
	default 19
	help
	  This option sets the value for the maximum policy format version
+14 −1
Original line number Diff line number Diff line
@@ -25,13 +25,14 @@
#define POLICYDB_VERSION_MLS		19
#define POLICYDB_VERSION_AVTAB		20
#define POLICYDB_VERSION_RANGETRANS	21
#define POLICYDB_VERSION_POLCAP		22

/* 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_RANGETRANS
#define POLICYDB_VERSION_MAX	POLICYDB_VERSION_POLCAP
#endif

struct netlbl_lsm_secattr;
@@ -39,8 +40,19 @@ struct netlbl_lsm_secattr;
extern int selinux_enabled;
extern int selinux_mls_enabled;

/* Policy capabilities */
enum {
	POLICYDB_CAPABILITY_NETPEER,
	__POLICYDB_CAPABILITY_MAX
};
#define POLICYDB_CAPABILITY_MAX (__POLICYDB_CAPABILITY_MAX - 1)

extern int selinux_policycap_netpeer;

int security_load_policy(void * data, size_t len);

int security_policycap_supported(unsigned int req_cap);

#define SEL_VEC_MAX 32
struct av_decision {
	u32 allowed;
@@ -91,6 +103,7 @@ 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_policycaps(int *len, int **values);

#define SECURITY_FS_USE_XATTR		1 /* use xattr */
#define SECURITY_FS_USE_TRANS		2 /* use transition SIDs, e.g. devpts/tmpfs */
+85 −4
Original line number Diff line number Diff line
@@ -2,6 +2,11 @@
 *
 * 	Added conditional policy language extensions
 *
 *  Updated: Hewlett-Packard <paul.moore@hp.com>
 *
 *      Added support for the policy capability bitmap
 *
 * Copyright (C) 2007 Hewlett-Packard Development Company, L.P.
 * Copyright (C) 2003 - 2004 Tresys Technology, LLC
 * Copyright (C) 2004 Red Hat, Inc., James Morris <jmorris@redhat.com>
 *	This program is free software; you can redistribute it and/or modify
@@ -35,6 +40,11 @@
#include "objsec.h"
#include "conditional.h"

/* Policy capability filenames */
static char *policycap_names[] = {
	"network_peer_controls"
};

unsigned int selinux_checkreqprot = CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE;

#ifdef CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT
@@ -72,6 +82,9 @@ static int *bool_pending_values = NULL;
static struct dentry *class_dir = NULL;
static unsigned long last_class_ino;

/* global data for policy capabilities */
static struct dentry *policycap_dir = NULL;

extern void selnl_notify_setenforce(int val);

/* Check whether a task is allowed to use a security operation. */
@@ -114,6 +127,7 @@ static unsigned long sel_last_ino = SEL_INO_NEXT - 1;
#define SEL_INITCON_INO_OFFSET		0x01000000
#define SEL_BOOL_INO_OFFSET		0x02000000
#define SEL_CLASS_INO_OFFSET		0x04000000
#define SEL_POLICYCAP_INO_OFFSET	0x08000000
#define SEL_INO_MASK			0x00ffffff

#define TMPBUFLEN	12
@@ -263,6 +277,7 @@ static const struct file_operations sel_policyvers_ops = {
/* declaration for sel_write_load */
static int sel_make_bools(void);
static int sel_make_classes(void);
static int sel_make_policycap(void);

/* declaration for sel_make_class_dirs */
static int sel_make_dir(struct inode *dir, struct dentry *dentry,
@@ -323,6 +338,12 @@ static ssize_t sel_write_load(struct file * file, const char __user * buf,
	}

	ret = sel_make_classes();
	if (ret) {
		length = ret;
		goto out1;
	}

	ret = sel_make_policycap();
	if (ret)
		length = ret;
	else
@@ -1399,6 +1420,24 @@ static const struct file_operations sel_perm_ops = {
	.read		= sel_read_perm,
};

static ssize_t sel_read_policycap(struct file *file, char __user *buf,
				  size_t count, loff_t *ppos)
{
	int value;
	char tmpbuf[TMPBUFLEN];
	ssize_t length;
	unsigned long i_ino = file->f_path.dentry->d_inode->i_ino;

	value = security_policycap_supported(i_ino & SEL_INO_MASK);
	length = scnprintf(tmpbuf, TMPBUFLEN, "%d", value);

	return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
}

static const struct file_operations sel_policycap_ops = {
	.read		= sel_read_policycap,
};

static int sel_make_perm_files(char *objclass, int classvalue,
				struct dentry *dir)
{
@@ -1545,6 +1584,36 @@ out:
	return rc;
}

static int sel_make_policycap(void)
{
	unsigned int iter;
	struct dentry *dentry = NULL;
	struct inode *inode = NULL;

	sel_remove_entries(policycap_dir);

	for (iter = 0; iter <= POLICYDB_CAPABILITY_MAX; iter++) {
		if (iter < ARRAY_SIZE(policycap_names))
			dentry = d_alloc_name(policycap_dir,
					      policycap_names[iter]);
		else
			dentry = d_alloc_name(policycap_dir, "unknown");

		if (dentry == NULL)
			return -ENOMEM;

		inode = sel_make_inode(policycap_dir->d_sb, S_IFREG | S_IRUGO);
		if (inode == NULL)
			return -ENOMEM;

		inode->i_fop = &sel_policycap_ops;
		inode->i_ino = iter | SEL_POLICYCAP_INO_OFFSET;
		d_add(dentry, inode);
	}

	return 0;
}

static int sel_make_dir(struct inode *dir, struct dentry *dentry,
			unsigned long *ino)
{
@@ -1673,6 +1742,18 @@ static int sel_fill_super(struct super_block * sb, void * data, int silent)

	class_dir = dentry;

	dentry = d_alloc_name(sb->s_root, "policy_capabilities");
	if (!dentry) {
		ret = -ENOMEM;
		goto err;
	}

	ret = sel_make_dir(root_inode, dentry, &sel_last_ino);
	if (ret)
		goto err;

	policycap_dir = dentry;

out:
	return ret;
err:
+17 −1
Original line number Diff line number Diff line
@@ -13,6 +13,11 @@
 *
 * 	Added conditional policy language extensions
 *
 * Updated: Hewlett-Packard <paul.moore@hp.com>
 *
 *      Added support for the policy capability bitmap
 *
 * Copyright (C) 2007 Hewlett-Packard Development Company, L.P.
 * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc.
 * Copyright (C) 2003 - 2004 Tresys Technology, LLC
 *	This program is free software; you can redistribute it and/or modify
@@ -102,6 +107,11 @@ static struct policydb_compat_info policydb_compat[] = {
		.sym_num        = SYM_NUM,
		.ocon_num       = OCON_NUM,
	},
	{
		.version	= POLICYDB_VERSION_POLCAP,
		.sym_num	= SYM_NUM,
		.ocon_num	= OCON_NUM,
	}
};

static struct policydb_compat_info *policydb_lookup_compat(int version)
@@ -183,6 +193,8 @@ static int policydb_init(struct policydb *p)
	if (rc)
		goto out_free_symtab;

	ebitmap_init(&p->policycaps);

out:
	return rc;

@@ -673,8 +685,8 @@ void policydb_destroy(struct policydb *p)
			ebitmap_destroy(&p->type_attr_map[i]);
	}
	kfree(p->type_attr_map);

	kfree(p->undefined_perms);
	ebitmap_destroy(&p->policycaps);

	return;
}
@@ -1554,6 +1566,10 @@ int policydb_read(struct policydb *p, void *fp)
	p->reject_unknown = !!(le32_to_cpu(buf[1]) & REJECT_UNKNOWN);
	p->allow_unknown = !!(le32_to_cpu(buf[1]) & ALLOW_UNKNOWN);

	if (p->policyvers >= POLICYDB_VERSION_POLCAP &&
	    ebitmap_read(&p->policycaps, fp) != 0)
		goto bad;

	info = policydb_lookup_compat(p->policyvers);
	if (!info) {
		printk(KERN_ERR "security:  unable to find policy compat info "
+2 −0
Original line number Diff line number Diff line
@@ -241,6 +241,8 @@ struct policydb {
	/* type -> attribute reverse mapping */
	struct ebitmap *type_attr_map;

	struct ebitmap policycaps;

	unsigned int policyvers;

	unsigned int reject_unknown : 1;
Loading