selinuxns: extend namespace support to security.selinux xattrs
Subsystems (6)
RFC PATCH 1/1 selinuxns: extend namespace support to security.selinux xattrs
This is an updated version of the patch which I first posted here:
http://kernsec.org/pipermail/linux-security-module-archive/2017-October/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!
Next TODO items:
- Perform labeling of files in ancestor namespaces upon creation in a child namespace.
- Label inheritence & label sharing (both ro/rw).
---
Quoted 1 line
From
91bcb0b9fe058d9b7b0de1d5a1c22e5e7303989aMon Sep 17 00:00:00 2001
From: James Morris <[email protected]>
Date: Tue, 21 Nov 2017 19:45:22 +1100
Subject: [PATCH] selinuxns: extend namespace support to security.selinux
xattrs
RFC v0.2
---
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(-)
fs/xattr.c +9 -3
@@ -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;
include/linux/lsm_hooks.h +2 -0
@@ -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;
include/linux/security.h +6 -0
@@ -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 ;
include/linux/xattr.h +1 -1
@@ -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 *);
security/integrity/evm/evm_crypto.c +1 -1
@@ -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 );
security/integrity/ima/ima_appraise.c +1 -1
@@ -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;
security/security.c +6 -0
@@ -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;
security/selinux/hooks.c +86 -9
207 lines not on this page · raw message
security/selinux/include/security.h +6 -1
@@ -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);
security/selinux/selinuxfs.c +40 -23
94 lines not on this page · raw message
security/smack/smack_lsm.c +1 -1
@@ -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)
Signature · 6 lines
1.8.3.1 -- 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
RFC PATCH 1/1 selinuxns: extend namespace support to security.selinux xattrs
Quoted 103 lines · James Morris
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.htmlI'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(quoted diff) +0
-3-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(quoted diff) +0
-4-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:
Quoted 8 lines
# 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.
Quoted 654 lines
Next TODO items:
- Perform labeling of files in ancestor namespaces upon creation in a?
? child namespace.
- Label inheritence & label sharing (both ro/rw).---
Quoted 2 lines
From
91bcb0b9fe058d9b7b0de1d5a1c22e5e7303989aMon Sep 17 00:00:00 2001From: James Morris <[email protected]>
Date: Tue, 21 Nov 2017 19:45:22 +1100
Subject: [PATCH] selinuxns: extend namespace support to security.selinux
?xattrsRFC v0.2
Signed-off-by James Morris <[email protected]>---
?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(-)
fs/xattr.c +0
-0@@ -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 operationsfs/xattr.c +0
-0@@ -168,7 +169,7 @@? *??permission checks.
? */
?int __vfs_setxattr_noperm(struct dentry *dentry, const char *name,fs/xattr.c +1
-1- 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;fs/xattr.c +2
-1@@ -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,fs/xattr.c +1
-0@@ -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)fs/xattr.c +0
-0@@ -221,8 +224,11 @@ int __vfs_setxattr_noperm(struct dentry *dentry,const char *name, ? if (error) ? goto out;?
fs/xattr.c +0
-1- error = __vfs_setxattr_noperm(dentry, name, value, size,flags);
fs/xattr.c +3
-0+ error =security_inode_translate_xattr_to_ns (name, &nsname); +if (error) + goto out;?
fs/xattr.c +1
-0+ error = __vfs_setxattr_noperm(dentry, name, nsname, value,size, flags);
?out:
?inode_unlock(inode);
? return error;include/linux/lsm_hooks.h +1
-0@@ -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);include/linux/lsm_hooks.h +1
-0@@ -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;include/linux/security.h +1
-0@@ -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);
?voidsecurity_file_free(struct file *file);include/linux/security.h +0
-0@@ -808,6 +809,11 @@ static inline int security_inode_copy_up_xattr(const char *name) ? return -EOPNOTSUPP; ?}?
+static inline intsecurity_inode_translate_xattr_to_ns(const char *name, char **tr)include/linux/security.h +4
-0+{ +return 0 ; +} +?static inline int
security_file_permission(struct file *file, int mask)
?{
? return 0;include/linux/xattr.h +1
-1@@ -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 *); ?intvfs_removexattr(struct dentry *, const char *);security/integrity/evm/evm_crypto.c +1
-1@@ -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);security/integrity/ima/ima_appraise.c +1
-1@@ -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;security/security.c +0
-0@@ -856,6 +856,12 @@ int security_inode_copy_up_xattr(const char *name) ?} ?EXPORT_SYMBOL(security_inode_copy_up_xattr);?
+intsecurity_inode_translate_xattr_to_ns(const char *name, char **tr)security/security.c +2
-0+{ + return call_int_hook(inode_translate_xattr_to_ns, 0, name,tr);
security/security.c +3
-0+} +EXPORT_SYMBOL (security_inode_translate_xattr_to_ns); +?int
security_file_permission(struct file *file, int mask)?{
? int ret;security/selinux/hooks.c +0
-0@@ -646,6 +646,16 @@ static int selinux_is_sblabel_mnt(struct super_block *sb) ? ??!strcmp(sb->s_type->name, "cgroup2"))); ?}?
security/selinux/hooks.c +3
-0+static char *current_xattr_suffix (void ) +{ + return current_selinux_ns->xattr_name +
XATTR_SECURITY_PREFIX_LEN;security/selinux/hooks.c +7
-0+} + +static char *current_xattr_name (void ) +{ +return current_selinux_ns->xattr_name; +} +?static int
sb_finish_set_opts(struct super_block *sb)?{
? structsuperblock_security_struct*sbsec =superblock_security(sb);security/selinux/hooks.c +0
-0@@ -654,6 +664,8 @@ static int sb_finish_set_opts(struct super_block *sb) ? int rc = 0;?
? if (sbsec->behavior==SECURITY_FS_USE_XATTR) {security/selinux/hooks.c +2
-0+char *name; +? /* Make sure that the xattr handler exists and that
no
? ???error other than-ENODATAis returned by getxattr
on
? ???the root directory.??-ENODATA is ok, as this may
besecurity/selinux/hooks.c +0
-0@@ -666,7 +678,9 @@ static int sb_finish_set_opts(struct super_block *sb) ? goto out; ? }?
security/selinux/hooks.c +0
-1- rc = __vfs_getxattr(root, root_inode,
XATTR_NAME_SELINUX, NULL, 0);security/selinux/hooks.c +3
-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 "security/selinux/hooks.c +1
-0@@ -1660,6 +1674,7 @@ static int inode_doinit_with_dentry(structinode *inode, ? char *context = NULL; ? unsigned len = 0; ? int rc = 0; +char *name;?
? if (isec->initialized==LABEL_INITIALIZED)
? return 0;security/selinux/hooks.c +3
-1@@ -1729,12 +1744,14 @@ static int inode_doinit_with_dentry(structinode *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. */security/selinux/hooks.c +0
-1- rc = __vfs_getxattr(dentry, inode,
XATTR_NAME_SELINUX, NULL, 0);security/selinux/hooks.c +1
-0+ rc = __vfs_getxattr(dentry, inode, name,NULL, 0);
? if (rc < 0) {
? dput(dentry);
? goto out;security/selinux/hooks.c +1
-1@@ -1747,7 +1764,7 @@ static int inode_doinit_with_dentry(structinode *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) {security/selinux/hooks.c +0
-0@@ -3167,7 +3184,7 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir, ? return -EOPNOTSUPP;?
? if (name)security/selinux/hooks.c +1
-1- *name =XATTR_SELINUX_SUFFIX ; + *name =current_xattr_suffix ();?
? if (value && len) {
? rc =
security_sid_to_context_force(current_selinux_ns, newsid,security/selinux/hooks.c +0
-0@@ -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_tsize,
int flags)
?{security/selinux/hooks.c +0
-0@@ -3392,8 +3413,12 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name, ? u32 newsid, sid = current_sid(); ? int rc = 0;?
security/selinux/hooks.c +3
-1-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)))security/selinux/hooks.c +1
-0+return -EACCES ;? return
selinux_inode_setotherxattr(dentry, name);security/selinux/hooks.c +1
-0+ }?
? sbsec =superblock_security(inode->i_sb);
? if (!(sbsec->flags &SBLABEL_MNT))security/selinux/hooks.c +0
-0@@ -3640,6 +3665,13 @@ static int selinux_inode_copy_up_xattr(const char *name) ? return -EOPNOTSUPP; ?}?
+static intselinux_inode_translate_xattr_to_ns(const char *name, char **tr)security/selinux/hooks.c +6
-0+{ +if (!strcmp (name,XATTR_NAME_SELINUX )) + *tr =current_xattr_name (); +return 0 ; +} +?/* file security operations */
?
?static intselinux_revalidate_file_permission(struct file *file, int mask)security/selinux/hooks.c +0
-0@@ -6430,10 +6462,11 @@ static int selinux_inode_notifysecctx(structinode *inode, void *ctx, u32 ctxlen
?
?/*
? * called withinode->i_mutexlocked
+ * TODO: namespace translation
? */
?static intselinux_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen)
?{security/selinux/hooks.c +0
-1- return __vfs_setxattr_noperm(dentry, XATTR_NAME_SELINUX,ctx, ctxlen, 0);
security/selinux/hooks.c +1
-0+ return __vfs_setxattr_noperm(dentry, XATTR_NAME_SELINUX,NULL, ctx, ctxlen, 0);
?}
?
?static intselinux_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen)security/selinux/hooks.c +1
-0@@ -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),security/selinux/hooks.c +0
-0@@ -6805,7 +6839,37 @@ static void selinux_ib_free_security(void *ib_sec)?
?static voidselinux_ns_free(struct work_struct *work);
?
-intselinux_ns_create(struct selinux_ns *parent, struct selinux_ns **ns)
+static intselinux_ns_create_name(struct selinux_ns *parent, struct selinux_ns *newns, const char *name)security/selinux/hooks.c +5
-0+{ +int rc =0 ; + +if (parent && parent->parent) + newns->name = kasprintf(GFP_KERNEL, "%s.%s", parent-Quoted 1 line
name, name);
security/selinux/hooks.c +10
-0+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)security/selinux/hooks.c +5
-0+{ +int rc =0 ; + +if (!parent) + newns->xattr_name = kstrdup(XATTR_NAME_SELINUX,
GFP_KERNEL);security/selinux/hooks.c +2
-0+ else? + newns->xattr_name = kasprintf(GFP_KERNEL, "%s.%s",
XATTR_NAME_SELINUX,newns->name);security/selinux/hooks.c +8
-0+ +if (!newns->xattr_name) + rc = -ENOMEM ; + +return rc; +} + +int selinux_ns_create(struct selinux_ns *parent, struct selinux_ns**ns, const char *name)
?{
? structselinux_ns*newns;
? int rc;security/selinux/hooks.c +0
-0@@ -6825,14 +6889,25 @@ int selinux_ns_create(struct selinux_ns *parent, struct selinux_ns **ns) ? if (rc) ? goto err;?
security/selinux/hooks.c +8
-0+ 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;security/selinux/hooks.c +2
-0+err_avc: +selinux_avc_free (newns->avc);?err:
?selinux_ss_free(newns->ss);
? kfree(newns);security/selinux/hooks.c +1
-0+kfree (newns->name);? return rc;
?}
?security/selinux/hooks.c +2
-0@@ -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));security/selinux/hooks.c +0
-0@@ -6869,7 +6946,7 @@ static __init int selinux_init(void)?
?printk(KERN_INFO "SELinux:??Initializing.\n");
?security/selinux/hooks.c +1
-1-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);security/selinux/include/security.h +0
-0@@ -92,6 +92,9 @@ enum {?/* limitation of boundary depth??*/
?#definePOLICYDB_BOUNDS_MAXDEPTH4
?security/selinux/include/security.h +3
-0+/* Name of SELinux initial namespace */ +#define SELINUX_NS_INIT_NAME "" +?struct
selinux_avc;
?structselinux_ss;
?security/selinux/include/security.h +2
-0@@ -108,9 +111,11 @@ struct selinux_ns { ? struct selinux_avc *avc; ? struct selinux_ss *ss; ? struct selinux_ns *parent; +char *name; +char *xattr_name; ?};?
-intselinux_ns_create(struct selinux_ns *parent, struct selinux_ns **ns);
+intselinux_ns_create(struct selinux_ns *parent, struct selinux_ns **ns, const char *name);
?void__put_selinux_ns(struct selinux_ns *ns);
?
?intselinux_ss_create(struct selinux_ss **ss);security/selinux/selinuxfs.c +0
-0@@ -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-Quoted 1 line
s_fs_info;? struct
selinux_ns*ns =fsi->ns;security/selinux/selinuxfs.c +2
-0+struct cred *cred; +struct task_security_struct *tsec;? char *page;
?ssize_tlength;security/selinux/selinuxfs.c +0
-1-bool set;? int rc;
?
? if (ns !=current_selinux_ns)security/selinux/selinuxfs.c +0
-0@@ -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);?
security/selinux/selinuxfs.c +3
-3- length = -EINVAL ; -if (kstrtobool (page, &set)) - goto out; +/* strip any trailing newline */ +if (page[strlen (page) -1 ] =='\n' ) + page[strlen (page) -1 ] =0 ;?
security/selinux/selinuxfs.c +5
-3-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; + }?
security/selinux/selinuxfs.c +0
-12-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-Quoted 1 line
keycreate_sid=security/selinux/selinuxfs.c +10
-3- 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;? }
security/selinux/selinuxfs.c +5
-0+ 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:security/selinux/selinuxfs.c +0
-0@@ -390,8 +393,22 @@ static ssize_t sel_write_unshare(struct file *file, const char __user *buf, ? return length; ?}?
security/selinux/selinuxfs.c +4
-0+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-Quoted 1 line
s_fs_info;security/selinux/selinuxfs.c +7
-0+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));
security/selinux/selinuxfs.c +2
-0+} +?static const struct
file_operationssel_unshare_ops= {
? .write =sel_write_unshare,security/selinux/selinuxfs.c +1
-0+ .read = sel_read_unshare,? .llseek =
generic_file_llseek,
?};
?security/selinux/selinuxfs.c +1
-1@@ -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 */ {""}? };
?security/smack/smack_lsm.c +0
-0@@ -4591,7 +4591,7 @@ static int smack_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen)?
?static intsmack_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen)
?{security/smack/smack_lsm.c +0
-1- return __vfs_setxattr_noperm(dentry, XATTR_NAME_SMACK, ctx,ctxlen, 0);
security/smack/smack_lsm.c +1
-0+ return __vfs_setxattr_noperm(dentry, XATTR_NAME_SMACK, NULL,
Quoted 5 lines
ctx, ctxlen, 0);
?}
?
?static intsmack_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