From: Joshua Brindle <method@manicmethod.com>
To: Paul Moore <paul.moore@hp.com>
Cc: selinux@tycho.nsa.gov
Subject: Re: [RFC PATCH v2 1/2] [SELINUX] Add a capabilities bitmap to SELinux policy version 22
Date: Wed, 26 Sep 2007 18:24:23 -0400 [thread overview]
Message-ID: <46FADC17.8070606@manicmethod.com> (raw)
In-Reply-To: <20070926213218.15998.48463.stgit@flek.americas.hpqcorp.net>
Paul Moore wrote:
> 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.
> ---
>
> security/selinux/include/security.h | 15 +++++-
> security/selinux/selinuxfs.c | 90 +++++++++++++++++++++++++++++++++--
> security/selinux/ss/policydb.c | 18 +++++++
> security/selinux/ss/policydb.h | 2 +
> security/selinux/ss/services.c | 39 +++++++++++++++
> 5 files changed, 158 insertions(+), 6 deletions(-)
>
> diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
> index 83bdd4d..d7e6ed2 100644
> --- a/security/selinux/include/security.h
> +++ b/security/selinux/include/security.h
> @@ -25,13 +25,14 @@
> #define POLICYDB_VERSION_MLS 19
> #define POLICYDB_VERSION_AVTAB 20
> #define POLICYDB_VERSION_RANGETRANS 21
> +#define POLICYDB_VERSION_CAPBITMAP 22
>
>
I didn't like this name (I almost used it myself) because it sounds like
we are doing something with linux capabilities, I ended up using
POLICYDB_VERSION_PCAPS (for policy capabilities)
> /* 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_CAPBITMAP
> #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)
> +
>
Hrm, I just used an ebitmap and didn't set a max at all.
> +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;
> @@ -90,6 +102,7 @@ int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid);
>
> int security_get_classes(char ***classes, int *nclasses);
> int security_get_permissions(char *class, char ***perms, int *nperms);
> +int security_get_policycaps(int *len, int **values);
>
>
We can fill in an array but I thought it'd be better just to use an
ebitmap and ebitmap_get_bit()
> #define SECURITY_FS_USE_XATTR 1 /* use xattr */
> #define SECURITY_FS_USE_TRANS 2 /* use transition SIDs, e.g. devpts/tmpfs */
> diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
> index c9e92da..c3e6f06 100644
> --- a/security/selinux/selinuxfs.c
> +++ b/security/selinux/selinuxfs.c
> @@ -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
> @@ -71,6 +81,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. */
> @@ -108,10 +121,11 @@ enum sel_inos {
>
> 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_INO_MASK 0x00ffffff
> +#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
>
whitespace changes?
>
> #define TMPBUFLEN 12
> static ssize_t sel_read_enforce(struct file *filp, char __user *buf,
> @@ -243,6 +257,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,
> @@ -303,6 +318,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
> @@ -1384,6 +1405,25 @@ 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 inode = file->f_path.dentry->d_inode->i_ino;
> +
> + value = security_policycap_supported(inode &
> + (SEL_POLICYCAP_INO_OFFSET - 1));
> + 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,
> +};
> +
>
Yea, I wondered how we were going to do this, we could have symbolic
names for each of them or we could just output offsets and let userspace
decipher it. I guess having symbolic names in a directory is better
(eg., /selinux/policy_caps/peersid_reconciliation)
> static int sel_make_perm_files(char *objclass, int classvalue,
> struct dentry *dir)
> {
> @@ -1530,6 +1570,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;
> +}
> +
>
err, yea, agreed :)
> static int sel_make_dir(struct inode *dir, struct dentry *dentry,
> unsigned long *ino)
> {
> @@ -1656,6 +1726,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:
> diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
> index f05f97a..e85a479 100644
> --- a/security/selinux/ss/policydb.c
> +++ b/security/selinux/ss/policydb.c
> @@ -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_CAPBITMAP,
> + .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_avtab;
>
> + ebitmap_init(&p->policycaps);
> +
> out:
> return rc;
>
> @@ -677,6 +689,8 @@ void policydb_destroy(struct policydb *p)
> }
> kfree(p->type_attr_map);
>
> + ebitmap_destroy(&p->policycaps);
> +
> return;
> }
>
> @@ -1531,6 +1545,10 @@ int policydb_read(struct policydb *p, void *fp)
> }
> }
>
> + if (p->policyvers >= POLICYDB_VERSION_CAPBITMAP &&
> + 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 "
> diff --git a/security/selinux/ss/policydb.h b/security/selinux/ss/policydb.h
> index 8319d5f..e621048 100644
> --- a/security/selinux/ss/policydb.h
> +++ b/security/selinux/ss/policydb.h
> @@ -241,6 +241,8 @@ struct policydb {
> /* type -> attribute reverse mapping */
> struct ebitmap *type_attr_map;
>
> + struct ebitmap policycaps;
> +
> unsigned int policyvers;
> };
>
> diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
> index 6100fc0..7d8c656 100644
> --- a/security/selinux/ss/services.c
> +++ b/security/selinux/ss/services.c
> @@ -16,12 +16,13 @@
> * Updated: Hewlett-Packard <paul.moore@hp.com>
> *
> * Added support for NetLabel
> + * Added support for the policy capability bitmap
> *
> * Updated: Chad Sellers <csellers@tresys.com>
> *
> * Added validation of kernel classes and permissions
> *
> - * Copyright (C) 2006 Hewlett-Packard Development Company, L.P.
> + * Copyright (C) 2006 - 2007 Hewlett-Packard Development Company, L.P.
> * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc.
> * Copyright (C) 2003 - 2004, 2006 Tresys Technology, LLC
> * Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com>
> @@ -59,6 +60,8 @@
> extern void selnl_notify_policyload(u32 seqno);
> unsigned int policydb_loaded_version;
>
> +int selinux_policycap_netpeer;
> +
> /*
> * This is declared in avc.c
> */
> @@ -1304,6 +1307,9 @@ int security_load_policy(void *data, size_t len)
> return -EINVAL;
> }
> policydb_loaded_version = policydb.policyvers;
> + selinux_policycap_netpeer =
> + ebitmap_get_bit(&policydb.policycaps,
> + POLICYDB_CAPABILITY_NETPEER);
> ss_initialized = 1;
> seqno = ++latest_granting;
> LOAD_UNLOCK;
> @@ -2102,6 +2108,37 @@ err:
> return rc;
> }
>
> +int security_get_policycaps(int *len, int **values)
> +{
> + int rc = -ENOMEM;
> + unsigned int iter;
> +
> + POLICY_RDLOCK;
> +
> + *values = kcalloc(POLICYDB_CAPABILITY_MAX, sizeof(int), GFP_ATOMIC);
> + if (*values == NULL)
> + goto out;
> + for (iter = 0; iter < POLICYDB_CAPABILITY_MAX; iter++)
> + (*values)[iter] = ebitmap_get_bit(&policydb.policycaps, iter);
> +
> + *len = POLICYDB_CAPABILITY_MAX;
> +
> +out:
> + POLICY_RDUNLOCK;
> + return rc;
> +}
> +
>
Why do we want to write out to an array instead of just passing the
ebitmap around?
> +int security_policycap_supported(unsigned int req_cap)
> +{
> + int rc;
> +
> + POLICY_RDLOCK;
> + rc = ebitmap_get_bit(&policydb.policycaps, req_cap);
> + POLICY_RDUNLOCK;
> +
> + return rc;
> +}
> +
>
Shouldn't this just check if policyvers > POLICYDB_VERSION_CAPBITMAP? it
could be inlined too.
> struct selinux_audit_rule {
> u32 au_seqno;
> struct context au_ctxt;
>
>
> --
> This message was distributed to subscribers of the selinux mailing list.
> If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
> the words "unsubscribe selinux" without quotes as the message.
>
>
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
next prev parent reply other threads:[~2007-09-26 22:24 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-09-26 21:32 [RFC PATCH v2 0/2] Updated patches based on comments Paul Moore
2007-09-26 21:32 ` [RFC PATCH v2 1/2] [SELINUX] Add a capabilities bitmap to SELinux policy version 22 Paul Moore
2007-09-26 22:24 ` Joshua Brindle [this message]
2007-09-27 11:36 ` Stephen Smalley
2007-09-27 18:10 ` Joshua Brindle
2007-09-27 19:07 ` Paul Moore
2007-09-27 11:46 ` Paul Moore
2007-09-26 21:32 ` [RFC PATCH v2 2/2] [SELINUX] Better integration between peer labeling subsystems Paul Moore
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=46FADC17.8070606@manicmethod.com \
--to=method@manicmethod.com \
--cc=paul.moore@hp.com \
--cc=selinux@tycho.nsa.gov \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.