diff options
author | Eric Paris <eparis@redhat.com> | 2008-06-18 09:50:04 -0400 |
---|---|---|
committer | James Morris <jmorris@namei.org> | 2008-07-14 01:02:04 -0400 |
commit | 811f3799279e567aa354c649ce22688d949ac7a9 (patch) | |
tree | 2a4d8c30821de84d5adcf37a09562ebba92f9f23 /security/selinux | |
parent | 65fc7668006b537f7ae8451990c0ed9ec882544e (diff) |
SELinux: allow fstype unknown to policy to use xattrs if present
Currently if a FS is mounted for which SELinux policy does not define an
fs_use_* that FS will either be genfs labeled or not labeled at all.
This decision is based on the existence of a genfscon rule in policy and
is irrespective of the capabilities of the filesystem itself. This
patch allows the kernel to check if the filesystem supports security
xattrs and if so will use those if there is no fs_use_* rule in policy.
An fstype with a no fs_use_* rule but with a genfs rule will use xattrs
if available and will follow the genfs rule.
This can be particularly interesting for things like ecryptfs which
actually overlays a real underlying FS. If we define excryptfs in
policy to use xattrs we will likely get this wrong at times, so with
this path we just don't need to define it!
Overlay ecryptfs on top of NFS with no xattr support:
SELinux: initialized (dev ecryptfs, type ecryptfs), uses genfs_contexts
Overlay ecryptfs on top of ext4 with xattr support:
SELinux: initialized (dev ecryptfs, type ecryptfs), uses xattr
It is also useful as the kernel adds new FS we don't need to add them in
policy if they support xattrs and that is how we want to handle them.
Signed-off-by: Eric Paris <eparis@redhat.com>
Acked-by: Stephen Smalley <sds@tycho.nsa.gov>
Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security/selinux')
-rw-r--r-- | security/selinux/hooks.c | 22 | ||||
-rw-r--r-- | security/selinux/include/security.h | 2 | ||||
-rw-r--r-- | security/selinux/ss/services.c | 27 |
3 files changed, 37 insertions, 14 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 4130d64359a3..85f74f665765 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -556,13 +556,15 @@ static int selinux_set_mnt_opts(struct super_block *sb, | |||
556 | struct task_security_struct *tsec = current->security; | 556 | struct task_security_struct *tsec = current->security; |
557 | struct superblock_security_struct *sbsec = sb->s_security; | 557 | struct superblock_security_struct *sbsec = sb->s_security; |
558 | const char *name = sb->s_type->name; | 558 | const char *name = sb->s_type->name; |
559 | struct inode *inode = sbsec->sb->s_root->d_inode; | 559 | struct dentry *root = sb->s_root; |
560 | struct inode_security_struct *root_isec = inode->i_security; | 560 | struct inode *root_inode = root->d_inode; |
561 | struct inode_security_struct *root_isec = root_inode->i_security; | ||
561 | u32 fscontext_sid = 0, context_sid = 0, rootcontext_sid = 0; | 562 | u32 fscontext_sid = 0, context_sid = 0, rootcontext_sid = 0; |
562 | u32 defcontext_sid = 0; | 563 | u32 defcontext_sid = 0; |
563 | char **mount_options = opts->mnt_opts; | 564 | char **mount_options = opts->mnt_opts; |
564 | int *flags = opts->mnt_opts_flags; | 565 | int *flags = opts->mnt_opts_flags; |
565 | int num_opts = opts->num_mnt_opts; | 566 | int num_opts = opts->num_mnt_opts; |
567 | bool can_xattr = false; | ||
566 | 568 | ||
567 | mutex_lock(&sbsec->lock); | 569 | mutex_lock(&sbsec->lock); |
568 | 570 | ||
@@ -666,14 +668,24 @@ static int selinux_set_mnt_opts(struct super_block *sb, | |||
666 | goto out; | 668 | goto out; |
667 | } | 669 | } |
668 | 670 | ||
669 | if (strcmp(sb->s_type->name, "proc") == 0) | 671 | if (strcmp(name, "proc") == 0) |
670 | sbsec->proc = 1; | 672 | sbsec->proc = 1; |
671 | 673 | ||
674 | /* | ||
675 | * test if the fs supports xattrs, fs_use might make use of this if the | ||
676 | * fs has no definition in policy. | ||
677 | */ | ||
678 | if (root_inode->i_op->getxattr) { | ||
679 | rc = root_inode->i_op->getxattr(root, XATTR_NAME_SELINUX, NULL, 0); | ||
680 | if (rc >= 0 || rc == -ENODATA) | ||
681 | can_xattr = true; | ||
682 | } | ||
683 | |||
672 | /* Determine the labeling behavior to use for this filesystem type. */ | 684 | /* Determine the labeling behavior to use for this filesystem type. */ |
673 | rc = security_fs_use(sb->s_type->name, &sbsec->behavior, &sbsec->sid); | 685 | rc = security_fs_use(name, &sbsec->behavior, &sbsec->sid, can_xattr); |
674 | if (rc) { | 686 | if (rc) { |
675 | printk(KERN_WARNING "%s: security_fs_use(%s) returned %d\n", | 687 | printk(KERN_WARNING "%s: security_fs_use(%s) returned %d\n", |
676 | __func__, sb->s_type->name, rc); | 688 | __func__, name, rc); |
677 | goto out; | 689 | goto out; |
678 | } | 690 | } |
679 | 691 | ||
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index 7c543003d653..44cba2e21dcf 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h | |||
@@ -136,7 +136,7 @@ int security_get_allow_unknown(void); | |||
136 | #define SECURITY_FS_USE_MNTPOINT 6 /* use mountpoint labeling */ | 136 | #define SECURITY_FS_USE_MNTPOINT 6 /* use mountpoint labeling */ |
137 | 137 | ||
138 | int security_fs_use(const char *fstype, unsigned int *behavior, | 138 | int security_fs_use(const char *fstype, unsigned int *behavior, |
139 | u32 *sid); | 139 | u32 *sid, bool can_xattr); |
140 | 140 | ||
141 | int security_genfs_sid(const char *fstype, char *name, u16 sclass, | 141 | int security_genfs_sid(const char *fstype, char *name, u16 sclass, |
142 | u32 *sid); | 142 | u32 *sid); |
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index b52f923ce680..8e42da120101 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c | |||
@@ -1934,7 +1934,8 @@ out: | |||
1934 | int security_fs_use( | 1934 | int security_fs_use( |
1935 | const char *fstype, | 1935 | const char *fstype, |
1936 | unsigned int *behavior, | 1936 | unsigned int *behavior, |
1937 | u32 *sid) | 1937 | u32 *sid, |
1938 | bool can_xattr) | ||
1938 | { | 1939 | { |
1939 | int rc = 0; | 1940 | int rc = 0; |
1940 | struct ocontext *c; | 1941 | struct ocontext *c; |
@@ -1948,6 +1949,7 @@ int security_fs_use( | |||
1948 | c = c->next; | 1949 | c = c->next; |
1949 | } | 1950 | } |
1950 | 1951 | ||
1952 | /* look for labeling behavior defined in policy */ | ||
1951 | if (c) { | 1953 | if (c) { |
1952 | *behavior = c->v.behavior; | 1954 | *behavior = c->v.behavior; |
1953 | if (!c->sid[0]) { | 1955 | if (!c->sid[0]) { |
@@ -1958,14 +1960,23 @@ int security_fs_use( | |||
1958 | goto out; | 1960 | goto out; |
1959 | } | 1961 | } |
1960 | *sid = c->sid[0]; | 1962 | *sid = c->sid[0]; |
1963 | goto out; | ||
1964 | } | ||
1965 | |||
1966 | /* labeling behavior not in policy, use xattrs if possible */ | ||
1967 | if (can_xattr) { | ||
1968 | *behavior = SECURITY_FS_USE_XATTR; | ||
1969 | *sid = SECINITSID_FS; | ||
1970 | goto out; | ||
1971 | } | ||
1972 | |||
1973 | /* no behavior in policy and can't use xattrs, try GENFS */ | ||
1974 | rc = security_genfs_sid(fstype, "/", SECCLASS_DIR, sid); | ||
1975 | if (rc) { | ||
1976 | *behavior = SECURITY_FS_USE_NONE; | ||
1977 | rc = 0; | ||
1961 | } else { | 1978 | } else { |
1962 | rc = security_genfs_sid(fstype, "/", SECCLASS_DIR, sid); | 1979 | *behavior = SECURITY_FS_USE_GENFS; |
1963 | if (rc) { | ||
1964 | *behavior = SECURITY_FS_USE_NONE; | ||
1965 | rc = 0; | ||
1966 | } else { | ||
1967 | *behavior = SECURITY_FS_USE_GENFS; | ||
1968 | } | ||
1969 | } | 1980 | } |
1970 | 1981 | ||
1971 | out: | 1982 | out: |