[RFC][PATCH][v0.2] selinuxns: extend namespace support to security.selinux xattrs
Stephen Smalley
sds at tycho.nsa.gov
Wed Nov 22 17:03:10 UTC 2017
On Tue, 2017-11-21 at 20:49 +1100, James Morris wrote:
> This is an updated version of the patch which I first posted here:
>
> http://kernsec.org/pipermail/linux-security-module-archive/2017-Octob
> er/004053.html
>
> I've incorporated some of the feedback provided, as follows:
>
> 1. The init namespace is now an empty string, rather than a hidden
> "init".
>
> 2. The ".ns." field for namespaced SELinux xattrs has been removed.
>
> 3. Namespace names are now hierarchical, and always include parent
> namespace names preceding the current namespace.
>
> As before, this works transparently for normal applications.
>
> Some usage examples with this patch:
>
> - Create a namespace "VM1":
>
> # echo VM1 > /sys/fs/selinux/unshare
> # unshare -m -n
> # umount /sys/fs/selinux && mount -t selinuxfs none /sys/fs/selinux
> && load_policy
> # runcon unconfined_u:unconfined_r:unconfined_t:s0:c0.c1023 /bin/bash
> # setenforce 1
> # cat /sys/fs/selinux/unshare
> VM1
>
>
> - Note that the current directory appears unlabeled:
>
> # ls -dZ
> drwxr-xr-x. root root system_u:object_r:unlabeled_t:s0 .
>
>
> - If you create a file, it will also thus be unlabeled:
>
> # touch b
> # ls -Z
> -rw-r--r--. root root unconfined_u:object_r:unlabeled_t:s0 b
>
>
> - With the current code, you need to manually label the current
> directory
> if you want labeling to work correctly:
>
> # restorecon -v .
> restorecon reset /root/selinux/test context
> system_u:object_r:unlabeled_t:s0->system_u:object_r:admin_home_t:s0
>
> # touch c
> # ls -lZ
> -rw-r--r--. root root unconfined_u:object_r:unlabeled_t:s0 b
> -rw-r--r--. root root unconfined_u:object_r:admin_home_t:s0 c
>
>
> - The on-disk label looks like this:
>
> # getfattr -d -m . c
> # file: c
> security.selinux.VM1="unconfined_u:object_r:admin_home_t:s0"
>
>
> - Now, create a nested namespace, "VM2":
>
> # echo VM2 > /sys/fs/selinux/unshare
> # unshare -m -n
> # umount /sys/fs/selinux && mount -t selinuxfs none /sys/fs/selinux
> && load_policy
> # runcon unconfined_u:unconfined_r:unconfined_t:s0:c0.c1023 /bin/bash
> # setenforce 1
> # cat /sys/fs/selinux/unshare
> VM1.VM2
>
> - Label .:
>
> # restorecon -v .
> restorecon reset /root/selinux/test context
> system_u:object_r:unlabeled_t:s0->system_u:object_r:admin_home_t:s0
>
>
> - Create a new file (note files from parent namespace are unlabled in
> this
> one):
>
> # touch d
> # ls -Z
> -rw-r--r--. root root system_u:object_r:unlabeled_t:s0 b
> -rw-r--r--. root root system_u:object_r:unlabeled_t:s0 c
> -rw-r--r--. root root unconfined_u:object_r:admin_home_t:s0 d
>
>
> - Relabel the file:
>
> # chcon -t etc_t d
> # ls -Z d
> -rw-r--r--. root root unconfined_u:object_r:etc_t:s0 d
>
>
> - View the on-disk label:
>
> # getfattr -d -m . d
> # file: d
> security.selinux.VM1.VM2="unconfined_u:object_r:etc_t:s0"
>
>
> There's a lot more work to do but I figured it would be useful for
> folk to
> see the hierarchical namespacing changes. Feedback welcome!
Thanks, this looks good to me wrt the new naming scheme for namespaces
and xattrs.
>
> Next TODO items:
>
> - Perform labeling of files in ancestor namespaces upon creation in
> a
> child namespace.
> - Label inheritence & label sharing (both ro/rw).
>
>
> ---
>
> > From 91bcb0b9fe058d9b7b0de1d5a1c22e5e7303989a Mon Sep 17 00:00:00
> > 2001
>
> From: James Morris <james.l.morris at oracle.com>
> Date: Tue, 21 Nov 2017 19:45:22 +1100
> Subject: [PATCH] selinuxns: extend namespace support to
> security.selinux
> xattrs
>
> RFC v0.2
>
> Signed-off-by: James Morris <james.l.morris at oracle.com>
>
> ---
>
> fs/xattr.c | 12 +++--
> include/linux/lsm_hooks.h | 2 +
> include/linux/security.h | 6 +++
> include/linux/xattr.h | 2 +-
> security/integrity/evm/evm_crypto.c | 2 +-
> security/integrity/ima/ima_appraise.c | 2 +-
> security/security.c | 6 +++
> security/selinux/hooks.c | 95
> +++++++++++++++++++++++++++++++----
> security/selinux/include/security.h | 7 ++-
> security/selinux/selinuxfs.c | 63 ++++++++++++++---------
> security/smack/smack_lsm.c | 2 +-
> 11 files changed, 159 insertions(+), 40 deletions(-)
>
> diff --git a/fs/xattr.c b/fs/xattr.c
> index 4424f7f..d8107b7 100644
> --- a/fs/xattr.c
> +++ b/fs/xattr.c
> @@ -157,6 +157,7 @@
> *
> * @dentry - object to perform setxattr on
> * @name - xattr name to set
> + * @nsname - namespaced xattr name, use instead of @name if set
> * @value - value to set @name to
> * @size - size of @value
> * @flags - flags to pass into filesystem operations
> @@ -168,7 +169,7 @@
> * permission checks.
> */
> int __vfs_setxattr_noperm(struct dentry *dentry, const char *name,
> - const void *value, size_t size, int flags)
> + const char *nsname, const void *value, size_t size,
> int flags)
> {
> struct inode *inode = dentry->d_inode;
> int error = -EAGAIN;
> @@ -178,7 +179,8 @@ int __vfs_setxattr_noperm(struct dentry *dentry,
> const char *name,
> if (issec)
> inode->i_flags &= ~S_NOSEC;
> if (inode->i_opflags & IOP_XATTR) {
> - error = __vfs_setxattr(dentry, inode, name, value,
> size, flags);
> + error = __vfs_setxattr(dentry, inode, nsname?:name,
> value,
> + size, flags);
> if (!error) {
> fsnotify_xattr(dentry);
> security_inode_post_setxattr(dentry, name,
> value,
> @@ -211,6 +213,7 @@ int __vfs_setxattr_noperm(struct dentry *dentry,
> const char *name,
> {
> struct inode *inode = dentry->d_inode;
> int error;
> + char *nsname = NULL;
>
> error = xattr_permission(inode, name, MAY_WRITE);
> if (error)
> @@ -221,8 +224,11 @@ int __vfs_setxattr_noperm(struct dentry *dentry,
> const char *name,
> if (error)
> goto out;
>
> - error = __vfs_setxattr_noperm(dentry, name, value, size,
> flags);
> + error = security_inode_translate_xattr_to_ns(name, &nsname);
> + if (error)
> + goto out;
>
> + error = __vfs_setxattr_noperm(dentry, name, nsname, value,
> size, flags);
> out:
> inode_unlock(inode);
> return error;
> diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
> index c925812..e4eb43e 100644
> --- a/include/linux/lsm_hooks.h
> +++ b/include/linux/lsm_hooks.h
> @@ -1480,6 +1480,7 @@
> void (*inode_getsecid)(struct inode *inode, u32 *secid);
> int (*inode_copy_up)(struct dentry *src, struct cred **new);
> int (*inode_copy_up_xattr)(const char *name);
> + int (*inode_translate_xattr_to_ns)(const char *name, char
> **tr);
>
> int (*file_permission)(struct file *file, int mask);
> int (*file_alloc_security)(struct file *file);
> @@ -1760,6 +1761,7 @@ struct security_hook_heads {
> struct list_head inode_getsecid;
> struct list_head inode_copy_up;
> struct list_head inode_copy_up_xattr;
> + struct list_head inode_translate_xattr_to_ns;
> struct list_head file_permission;
> struct list_head file_alloc_security;
> struct list_head file_free_security;
> diff --git a/include/linux/security.h b/include/linux/security.h
> index ce62659..64297e1 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -302,6 +302,7 @@ void security_inode_post_setxattr(struct dentry
> *dentry, const char *name,
> void security_inode_getsecid(struct inode *inode, u32 *secid);
> int security_inode_copy_up(struct dentry *src, struct cred **new);
> int security_inode_copy_up_xattr(const char *name);
> +int security_inode_translate_xattr_to_ns(const char *name, char
> **tr);
> int security_file_permission(struct file *file, int mask);
> int security_file_alloc(struct file *file);
> void security_file_free(struct file *file);
> @@ -808,6 +809,11 @@ static inline int
> security_inode_copy_up_xattr(const char *name)
> return -EOPNOTSUPP;
> }
>
> +static inline int security_inode_translate_xattr_to_ns(const char
> *name, char **tr)
> +{
> + return 0;
> +}
> +
> static inline int security_file_permission(struct file *file, int
> mask)
> {
> return 0;
> diff --git a/include/linux/xattr.h b/include/linux/xattr.h
> index e77605a..c25eb8a 100644
> --- a/include/linux/xattr.h
> +++ b/include/linux/xattr.h
> @@ -50,7 +50,7 @@ struct xattr {
> ssize_t vfs_getxattr(struct dentry *, const char *, void *, size_t);
> ssize_t vfs_listxattr(struct dentry *d, char *list, size_t size);
> int __vfs_setxattr(struct dentry *, struct inode *, const char *,
> const void *, size_t, int);
> -int __vfs_setxattr_noperm(struct dentry *, const char *, const void
> *, size_t, int);
> +int __vfs_setxattr_noperm(struct dentry *, const char *, const char
> *, const void *, size_t, int);
> int vfs_setxattr(struct dentry *, const char *, const void *,
> size_t, int);
> int __vfs_removexattr(struct dentry *, const char *);
> int vfs_removexattr(struct dentry *, const char *);
> diff --git a/security/integrity/evm/evm_crypto.c
> b/security/integrity/evm/evm_crypto.c
> index 1d32cd2..2249186 100644
> --- a/security/integrity/evm/evm_crypto.c
> +++ b/security/integrity/evm/evm_crypto.c
> @@ -260,7 +260,7 @@ int evm_update_evmxattr(struct dentry *dentry,
> const char *xattr_name,
> if (rc == 0) {
> xattr_data.type = EVM_XATTR_HMAC;
> rc = __vfs_setxattr_noperm(dentry, XATTR_NAME_EVM,
> - &xattr_data,
> + NULL, &xattr_data,
> sizeof(xattr_data), 0);
> } else if (rc == -ENODATA && (inode->i_opflags & IOP_XATTR))
> {
> rc = __vfs_removexattr(dentry, XATTR_NAME_EVM);
> diff --git a/security/integrity/ima/ima_appraise.c
> b/security/integrity/ima/ima_appraise.c
> index 809ba70..914cf5f 100644
> --- a/security/integrity/ima/ima_appraise.c
> +++ b/security/integrity/ima/ima_appraise.c
> @@ -71,7 +71,7 @@ static int ima_fix_xattr(struct dentry *dentry,
> iint->ima_hash->xattr.ng.algo = algo;
> }
> rc = __vfs_setxattr_noperm(dentry, XATTR_NAME_IMA,
> - &iint->ima_hash-
> >xattr.data[offset],
> + NULL, &iint->ima_hash-
> >xattr.data[offset],
> (sizeof(iint->ima_hash->xattr) -
> offset) +
> iint->ima_hash->length, 0);
> return rc;
> diff --git a/security/security.c b/security/security.c
> index 4bf0f57..7fce259 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -856,6 +856,12 @@ int security_inode_copy_up_xattr(const char
> *name)
> }
> EXPORT_SYMBOL(security_inode_copy_up_xattr);
>
> +int security_inode_translate_xattr_to_ns(const char *name, char
> **tr)
> +{
> + return call_int_hook(inode_translate_xattr_to_ns, 0, name,
> tr);
> +}
> +EXPORT_SYMBOL(security_inode_translate_xattr_to_ns);
> +
> int security_file_permission(struct file *file, int mask)
> {
> int ret;
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index 3daad14..e439ce2 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -646,6 +646,16 @@ static int selinux_is_sblabel_mnt(struct
> super_block *sb)
> !strcmp(sb->s_type->name, "cgroup2")));
> }
>
> +static char *current_xattr_suffix(void)
> +{
> + return current_selinux_ns->xattr_name +
> XATTR_SECURITY_PREFIX_LEN;
> +}
> +
> +static char *current_xattr_name(void)
> +{
> + return current_selinux_ns->xattr_name;
> +}
> +
> static int sb_finish_set_opts(struct super_block *sb)
> {
> struct superblock_security_struct *sbsec =
> superblock_security(sb);
> @@ -654,6 +664,8 @@ static int sb_finish_set_opts(struct super_block
> *sb)
> int rc = 0;
>
> if (sbsec->behavior == SECURITY_FS_USE_XATTR) {
> + char *name;
> +
> /* Make sure that the xattr handler exists and that
> no
> error other than -ENODATA is returned by getxattr
> on
> the root directory. -ENODATA is ok, as this may
> be
> @@ -666,7 +678,9 @@ static int sb_finish_set_opts(struct super_block
> *sb)
> goto out;
> }
>
> - rc = __vfs_getxattr(root, root_inode,
> XATTR_NAME_SELINUX, NULL, 0);
> + name = current_xattr_name();
> +
> + rc = __vfs_getxattr(root, root_inode, name, NULL,
> 0);
> if (rc < 0 && rc != -ENODATA) {
> if (rc == -EOPNOTSUPP)
> printk(KERN_WARNING "SELinux: (dev
> %s, type "
> @@ -1660,6 +1674,7 @@ static int inode_doinit_with_dentry(struct
> inode *inode,
> char *context = NULL;
> unsigned len = 0;
> int rc = 0;
> + char *name;
>
> if (isec->initialized == LABEL_INITIALIZED)
> return 0;
> @@ -1729,12 +1744,14 @@ static int inode_doinit_with_dentry(struct
> inode *inode,
> goto out;
> }
> context[len] = '\0';
> - rc = __vfs_getxattr(dentry, inode,
> XATTR_NAME_SELINUX, context, len);
> +
> + name = current_xattr_name();
> + rc = __vfs_getxattr(dentry, inode, name, context,
> len);
> if (rc == -ERANGE) {
> kfree(context);
>
> /* Need a larger buffer. Query for the
> right size. */
> - rc = __vfs_getxattr(dentry, inode,
> XATTR_NAME_SELINUX, NULL, 0);
> + rc = __vfs_getxattr(dentry, inode, name,
> NULL, 0);
> if (rc < 0) {
> dput(dentry);
> goto out;
> @@ -1747,7 +1764,7 @@ static int inode_doinit_with_dentry(struct
> inode *inode,
> goto out;
> }
> context[len] = '\0';
> - rc = __vfs_getxattr(dentry, inode,
> XATTR_NAME_SELINUX, context, len);
> + rc = __vfs_getxattr(dentry, inode, name,
> context, len);
> }
> dput(dentry);
> if (rc < 0) {
> @@ -3167,7 +3184,7 @@ static int selinux_inode_init_security(struct
> inode *inode, struct inode *dir,
> return -EOPNOTSUPP;
>
> if (name)
> - *name = XATTR_SELINUX_SUFFIX;
> + *name = current_xattr_suffix();
>
> if (value && len) {
> rc =
> security_sid_to_context_force(current_selinux_ns, newsid,
> @@ -3382,6 +3399,10 @@ static bool has_cap_mac_admin(bool audit)
> return true;
> }
>
> +/* TODO:
> + * - audit
> + * - handle raw namespaced xattrs
> + */
> static int selinux_inode_setxattr(struct dentry *dentry, const char
> *name,
> const void *value, size_t size,
> int flags)
> {
> @@ -3392,8 +3413,12 @@ static int selinux_inode_setxattr(struct
> dentry *dentry, const char *name,
> u32 newsid, sid = current_sid();
> int rc = 0;
>
> - if (strcmp(name, XATTR_NAME_SELINUX))
> + if (strcmp(name, XATTR_NAME_SELINUX)) {
> + /* No raw namespaced xattrs, yet */
> + if (!strncmp(name, XATTR_NAME_SELINUX,
> strlen(XATTR_NAME_SELINUX)))
> + return -EACCES;
> return selinux_inode_setotherxattr(dentry, name);
> + }
>
> sbsec = superblock_security(inode->i_sb);
> if (!(sbsec->flags & SBLABEL_MNT))
> @@ -3640,6 +3665,13 @@ static int selinux_inode_copy_up_xattr(const
> char *name)
> return -EOPNOTSUPP;
> }
>
> +static int selinux_inode_translate_xattr_to_ns(const char *name,
> char **tr)
> +{
> + if(!strcmp(name, XATTR_NAME_SELINUX))
> + *tr = current_xattr_name();
> + return 0;
> +}
> +
> /* file security operations */
>
> static int selinux_revalidate_file_permission(struct file *file, int
> mask)
> @@ -6430,10 +6462,11 @@ static int selinux_inode_notifysecctx(struct
> inode *inode, void *ctx, u32 ctxlen
>
> /*
> * called with inode->i_mutex locked
> + * TODO: namespace translation
> */
> static int selinux_inode_setsecctx(struct dentry *dentry, void *ctx,
> u32 ctxlen)
> {
> - return __vfs_setxattr_noperm(dentry, XATTR_NAME_SELINUX,
> ctx, ctxlen, 0);
> + return __vfs_setxattr_noperm(dentry, XATTR_NAME_SELINUX,
> NULL, ctx, ctxlen, 0);
> }
>
> static int selinux_inode_getsecctx(struct inode *inode, void **ctx,
> u32 *ctxlen)
> @@ -6647,6 +6680,7 @@ static void selinux_ib_free_security(void
> *ib_sec)
> LSM_HOOK_INIT(inode_getsecid, selinux_inode_getsecid),
> LSM_HOOK_INIT(inode_copy_up, selinux_inode_copy_up),
> LSM_HOOK_INIT(inode_copy_up_xattr,
> selinux_inode_copy_up_xattr),
> + LSM_HOOK_INIT(inode_translate_xattr_to_ns,
> selinux_inode_translate_xattr_to_ns),
>
> LSM_HOOK_INIT(file_permission, selinux_file_permission),
> LSM_HOOK_INIT(file_alloc_security,
> selinux_file_alloc_security),
> @@ -6805,7 +6839,37 @@ static void selinux_ib_free_security(void
> *ib_sec)
>
> static void selinux_ns_free(struct work_struct *work);
>
> -int selinux_ns_create(struct selinux_ns *parent, struct selinux_ns
> **ns)
> +static int selinux_ns_create_name(struct selinux_ns *parent, struct
> selinux_ns *newns, const char *name)
> +{
> + int rc = 0;
> +
> + if (parent && parent->parent)
> + newns->name = kasprintf(GFP_KERNEL, "%s.%s", parent-
> >name, name);
> + else
> + newns->name = kstrdup(name, GFP_KERNEL);
> +
> + if (!newns->name)
> + rc = -ENOMEM;
> +
> + return rc;
> +}
> +
> +static int selinux_ns_create_xattr_name(struct selinux_ns *parent,
> struct selinux_ns *newns)
> +{
> + int rc = 0;
> +
> + if (!parent)
> + newns->xattr_name = kstrdup(XATTR_NAME_SELINUX,
> GFP_KERNEL);
> + else
> + newns->xattr_name = kasprintf(GFP_KERNEL, "%s.%s",
> XATTR_NAME_SELINUX, newns->name);
> +
> + if (!newns->xattr_name)
> + rc = -ENOMEM;
> +
> + return rc;
> +}
> +
> +int selinux_ns_create(struct selinux_ns *parent, struct selinux_ns
> **ns, const char *name)
> {
> struct selinux_ns *newns;
> int rc;
> @@ -6825,14 +6889,25 @@ int selinux_ns_create(struct selinux_ns
> *parent, struct selinux_ns **ns)
> if (rc)
> goto err;
>
> + rc = selinux_ns_create_name(parent, newns, name);
> + if (rc)
> + goto err_avc;
> +
> + rc = selinux_ns_create_xattr_name(parent, newns);
> + if (rc)
> + goto err_avc;
> +
> if (parent)
> newns->parent = get_selinux_ns(parent);
>
> *ns = newns;
> return 0;
> +err_avc:
> + selinux_avc_free(newns->avc);
> err:
> selinux_ss_free(newns->ss);
> kfree(newns);
> + kfree(newns->name);
> return rc;
> }
>
> @@ -6845,6 +6920,8 @@ static void selinux_ns_free(struct work_struct
> *work)
> parent = ns->parent;
> selinux_ss_free(ns->ss);
> selinux_avc_free(ns->avc);
> + kfree(ns->name);
> + kfree(ns->xattr_name);
> kfree(ns);
> ns = parent;
> } while (ns && refcount_dec_and_test(&ns->count));
> @@ -6869,7 +6946,7 @@ static __init int selinux_init(void)
>
> printk(KERN_INFO "SELinux: Initializing.\n");
>
> - if (selinux_ns_create(NULL, &init_selinux_ns))
> + if (selinux_ns_create(NULL, &init_selinux_ns,
> SELINUX_NS_INIT_NAME))
> panic("SELinux: Could not create initial
> namespace\n");
>
> set_ns_enforcing(init_selinux_ns, selinux_enforcing_boot);
> diff --git a/security/selinux/include/security.h
> b/security/selinux/include/security.h
> index b80f9bd..300cc8a 100644
> --- a/security/selinux/include/security.h
> +++ b/security/selinux/include/security.h
> @@ -92,6 +92,9 @@ enum {
> /* limitation of boundary depth */
> #define POLICYDB_BOUNDS_MAXDEPTH 4
>
> +/* Name of SELinux initial namespace */
> +#define SELINUX_NS_INIT_NAME ""
> +
> struct selinux_avc;
> struct selinux_ss;
>
> @@ -108,9 +111,11 @@ struct selinux_ns {
> struct selinux_avc *avc;
> struct selinux_ss *ss;
> struct selinux_ns *parent;
> + char *name;
> + char *xattr_name;
> };
>
> -int selinux_ns_create(struct selinux_ns *parent, struct selinux_ns
> **ns);
> +int selinux_ns_create(struct selinux_ns *parent, struct selinux_ns
> **ns, const char *name);
> void __put_selinux_ns(struct selinux_ns *ns);
>
> int selinux_ss_create(struct selinux_ss **ss);
> diff --git a/security/selinux/selinuxfs.c
> b/security/selinux/selinuxfs.c
> index 6c52d24..d190213 100644
> --- a/security/selinux/selinuxfs.c
> +++ b/security/selinux/selinuxfs.c
> @@ -334,9 +334,10 @@ static ssize_t sel_write_unshare(struct file
> *file, const char __user *buf,
> {
> struct selinux_fs_info *fsi = file_inode(file)->i_sb-
> >s_fs_info;
> struct selinux_ns *ns = fsi->ns;
> + struct cred *cred;
> + struct task_security_struct *tsec;
> char *page;
> ssize_t length;
> - bool set;
> int rc;
>
> if (ns != current_selinux_ns)
> @@ -359,30 +360,32 @@ static ssize_t sel_write_unshare(struct file
> *file, const char __user *buf,
> if (IS_ERR(page))
> return PTR_ERR(page);
>
> - length = -EINVAL;
> - if (kstrtobool(page, &set))
> - goto out;
> + /* strip any trailing newline */
> + if (page[strlen(page) - 1] == '\n')
> + page[strlen(page) - 1] = 0;
>
> - if (set) {
> - struct cred *cred = prepare_creds();
> - struct task_security_struct *tsec;
> + /* TODO: check for uniqueness! */
> + if (!strcmp(SELINUX_NS_INIT_NAME, page)) {
> + length = -EINVAL;
> + goto out;
> + }
>
> - if (!cred) {
> - length = -ENOMEM;
> - goto out;
> - }
> - tsec = cred->security;
> - if (selinux_ns_create(ns, &tsec->ns)) {
> - abort_creds(cred);
> - length = -ENOMEM;
> - goto out;
> - }
> - tsec->osid = tsec->sid = SECINITSID_KERNEL;
> - tsec->exec_sid = tsec->create_sid = tsec-
> >keycreate_sid =
> - tsec->sockcreate_sid = SECSID_NULL;
> - tsec->parent_cred = get_current_cred();
> - commit_creds(cred);
> + cred = prepare_creds();
> + if (!cred) {
> + length = -ENOMEM;
> + goto out;
> + }
> + tsec = cred->security;
> + if (selinux_ns_create(ns, &tsec->ns, page)) {
> + abort_creds(cred);
> + length = -ENOMEM;
> + goto out;
> }
> + tsec->osid = tsec->sid = SECINITSID_KERNEL;
> + tsec->exec_sid = tsec->create_sid = tsec->keycreate_sid =
> + tsec->sockcreate_sid = SECSID_NULL;
> + tsec->parent_cred = get_current_cred();
> + commit_creds(cred);
>
> length = count;
> out:
> @@ -390,8 +393,22 @@ static ssize_t sel_write_unshare(struct file
> *file, const char __user *buf,
> return length;
> }
>
> +static ssize_t sel_read_unshare(struct file *file, char __user *buf,
> + size_t count, loff_t *ppos)
> +{
> + struct selinux_fs_info *fsi = file_inode(file)->i_sb-
> >s_fs_info;
> + struct selinux_ns *ns = fsi->ns;
> + char *name = ns->name;
> +
> + if (ns != current_selinux_ns)
> + return -EPERM;
> +
> + return simple_read_from_buffer(buf, count, ppos, name,
> strlen(name));
> +}
> +
> static const struct file_operations sel_unshare_ops = {
> .write = sel_write_unshare,
> + .read = sel_read_unshare,
> .llseek = generic_file_llseek,
> };
>
> @@ -2021,7 +2038,7 @@ static int sel_fill_super(struct super_block
> *sb, void *data, int silent)
> [SEL_POLICY] = {"policy", &sel_policy_ops, S_IRUGO},
> [SEL_VALIDATE_TRANS] = {"validatetrans",
> &sel_transition_ops,
> S_IWUGO},
> - [SEL_UNSHARE] = {"unshare", &sel_unshare_ops, 0222},
> + [SEL_UNSHARE] = {"unshare", &sel_unshare_ops, 0666},
> /* last one */ {""}
> };
>
> diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
> index 319add3..5ea841f 100644
> --- a/security/smack/smack_lsm.c
> +++ b/security/smack/smack_lsm.c
> @@ -4591,7 +4591,7 @@ static int smack_inode_notifysecctx(struct
> inode *inode, void *ctx, u32 ctxlen)
>
> static int smack_inode_setsecctx(struct dentry *dentry, void *ctx,
> u32 ctxlen)
> {
> - return __vfs_setxattr_noperm(dentry, XATTR_NAME_SMACK, ctx,
> ctxlen, 0);
> + return __vfs_setxattr_noperm(dentry, XATTR_NAME_SMACK, NULL,
> ctx, ctxlen, 0);
> }
>
> static int smack_inode_getsecctx(struct inode *inode, void **ctx,
> u32 *ctxlen)
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
More information about the Linux-security-module-archive
mailing list