diff options
author | Eric Paris <eparis@redhat.com> | 2008-07-03 19:47:13 -0400 |
---|---|---|
committer | James Morris <jmorris@namei.org> | 2008-07-14 01:02:05 -0400 |
commit | 2069f457848f846cb31149c9aa29b330a6b66d1b (patch) | |
tree | 199e7bb15e7d7b5cf008cd6fdb6cefc0d6af7f13 | |
parent | 811f3799279e567aa354c649ce22688d949ac7a9 (diff) |
LSM/SELinux: show LSM mount options in /proc/mounts
This patch causes SELinux mount options to show up in /proc/mounts. As
with other code in the area seq_put errors are ignored. Other LSM's
will not have their mount options displayed until they fill in their own
security_sb_show_options() function.
Signed-off-by: Eric Paris <eparis@redhat.com>
Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
Signed-off-by: James Morris <jmorris@namei.org>
-rw-r--r-- | fs/namespace.c | 14 | ||||
-rw-r--r-- | include/linux/security.h | 9 | ||||
-rw-r--r-- | security/dummy.c | 6 | ||||
-rw-r--r-- | security/security.c | 5 | ||||
-rw-r--r-- | security/selinux/hooks.c | 55 |
5 files changed, 85 insertions, 4 deletions
diff --git a/fs/namespace.c b/fs/namespace.c index 4fc302c2a0e0..4f6f7635b59c 100644 --- a/fs/namespace.c +++ b/fs/namespace.c | |||
@@ -750,7 +750,7 @@ struct proc_fs_info { | |||
750 | const char *str; | 750 | const char *str; |
751 | }; | 751 | }; |
752 | 752 | ||
753 | static void show_sb_opts(struct seq_file *m, struct super_block *sb) | 753 | static int show_sb_opts(struct seq_file *m, struct super_block *sb) |
754 | { | 754 | { |
755 | static const struct proc_fs_info fs_info[] = { | 755 | static const struct proc_fs_info fs_info[] = { |
756 | { MS_SYNCHRONOUS, ",sync" }, | 756 | { MS_SYNCHRONOUS, ",sync" }, |
@@ -764,6 +764,8 @@ static void show_sb_opts(struct seq_file *m, struct super_block *sb) | |||
764 | if (sb->s_flags & fs_infop->flag) | 764 | if (sb->s_flags & fs_infop->flag) |
765 | seq_puts(m, fs_infop->str); | 765 | seq_puts(m, fs_infop->str); |
766 | } | 766 | } |
767 | |||
768 | return security_sb_show_options(m, sb); | ||
767 | } | 769 | } |
768 | 770 | ||
769 | static void show_mnt_opts(struct seq_file *m, struct vfsmount *mnt) | 771 | static void show_mnt_opts(struct seq_file *m, struct vfsmount *mnt) |
@@ -806,11 +808,14 @@ static int show_vfsmnt(struct seq_file *m, void *v) | |||
806 | seq_putc(m, ' '); | 808 | seq_putc(m, ' '); |
807 | show_type(m, mnt->mnt_sb); | 809 | show_type(m, mnt->mnt_sb); |
808 | seq_puts(m, __mnt_is_readonly(mnt) ? " ro" : " rw"); | 810 | seq_puts(m, __mnt_is_readonly(mnt) ? " ro" : " rw"); |
809 | show_sb_opts(m, mnt->mnt_sb); | 811 | err = show_sb_opts(m, mnt->mnt_sb); |
812 | if (err) | ||
813 | goto out; | ||
810 | show_mnt_opts(m, mnt); | 814 | show_mnt_opts(m, mnt); |
811 | if (mnt->mnt_sb->s_op->show_options) | 815 | if (mnt->mnt_sb->s_op->show_options) |
812 | err = mnt->mnt_sb->s_op->show_options(m, mnt); | 816 | err = mnt->mnt_sb->s_op->show_options(m, mnt); |
813 | seq_puts(m, " 0 0\n"); | 817 | seq_puts(m, " 0 0\n"); |
818 | out: | ||
814 | return err; | 819 | return err; |
815 | } | 820 | } |
816 | 821 | ||
@@ -865,10 +870,13 @@ static int show_mountinfo(struct seq_file *m, void *v) | |||
865 | seq_putc(m, ' '); | 870 | seq_putc(m, ' '); |
866 | mangle(m, mnt->mnt_devname ? mnt->mnt_devname : "none"); | 871 | mangle(m, mnt->mnt_devname ? mnt->mnt_devname : "none"); |
867 | seq_puts(m, sb->s_flags & MS_RDONLY ? " ro" : " rw"); | 872 | seq_puts(m, sb->s_flags & MS_RDONLY ? " ro" : " rw"); |
868 | show_sb_opts(m, sb); | 873 | err = show_sb_opts(m, sb); |
874 | if (err) | ||
875 | goto out; | ||
869 | if (sb->s_op->show_options) | 876 | if (sb->s_op->show_options) |
870 | err = sb->s_op->show_options(m, mnt); | 877 | err = sb->s_op->show_options(m, mnt); |
871 | seq_putc(m, '\n'); | 878 | seq_putc(m, '\n'); |
879 | out: | ||
872 | return err; | 880 | return err; |
873 | } | 881 | } |
874 | 882 | ||
diff --git a/include/linux/security.h b/include/linux/security.h index 62bd80cb7f87..c8ad8ec684b4 100644 --- a/include/linux/security.h +++ b/include/linux/security.h | |||
@@ -80,6 +80,7 @@ struct xfrm_selector; | |||
80 | struct xfrm_policy; | 80 | struct xfrm_policy; |
81 | struct xfrm_state; | 81 | struct xfrm_state; |
82 | struct xfrm_user_sec_ctx; | 82 | struct xfrm_user_sec_ctx; |
83 | struct seq_file; | ||
83 | 84 | ||
84 | extern int cap_netlink_send(struct sock *sk, struct sk_buff *skb); | 85 | extern int cap_netlink_send(struct sock *sk, struct sk_buff *skb); |
85 | extern int cap_netlink_recv(struct sk_buff *skb, int cap); | 86 | extern int cap_netlink_recv(struct sk_buff *skb, int cap); |
@@ -1331,6 +1332,7 @@ struct security_operations { | |||
1331 | void (*sb_free_security) (struct super_block *sb); | 1332 | void (*sb_free_security) (struct super_block *sb); |
1332 | int (*sb_copy_data) (char *orig, char *copy); | 1333 | int (*sb_copy_data) (char *orig, char *copy); |
1333 | int (*sb_kern_mount) (struct super_block *sb, void *data); | 1334 | int (*sb_kern_mount) (struct super_block *sb, void *data); |
1335 | int (*sb_show_options) (struct seq_file *m, struct super_block *sb); | ||
1334 | int (*sb_statfs) (struct dentry *dentry); | 1336 | int (*sb_statfs) (struct dentry *dentry); |
1335 | int (*sb_mount) (char *dev_name, struct path *path, | 1337 | int (*sb_mount) (char *dev_name, struct path *path, |
1336 | char *type, unsigned long flags, void *data); | 1338 | char *type, unsigned long flags, void *data); |
@@ -1610,6 +1612,7 @@ int security_sb_alloc(struct super_block *sb); | |||
1610 | void security_sb_free(struct super_block *sb); | 1612 | void security_sb_free(struct super_block *sb); |
1611 | int security_sb_copy_data(char *orig, char *copy); | 1613 | int security_sb_copy_data(char *orig, char *copy); |
1612 | int security_sb_kern_mount(struct super_block *sb, void *data); | 1614 | int security_sb_kern_mount(struct super_block *sb, void *data); |
1615 | int security_sb_show_options(struct seq_file *m, struct super_block *sb); | ||
1613 | int security_sb_statfs(struct dentry *dentry); | 1616 | int security_sb_statfs(struct dentry *dentry); |
1614 | int security_sb_mount(char *dev_name, struct path *path, | 1617 | int security_sb_mount(char *dev_name, struct path *path, |
1615 | char *type, unsigned long flags, void *data); | 1618 | char *type, unsigned long flags, void *data); |
@@ -1887,6 +1890,12 @@ static inline int security_sb_kern_mount(struct super_block *sb, void *data) | |||
1887 | return 0; | 1890 | return 0; |
1888 | } | 1891 | } |
1889 | 1892 | ||
1893 | static inline int security_sb_show_options(struct seq_file *m, | ||
1894 | struct super_block *sb) | ||
1895 | { | ||
1896 | return 0; | ||
1897 | } | ||
1898 | |||
1890 | static inline int security_sb_statfs(struct dentry *dentry) | 1899 | static inline int security_sb_statfs(struct dentry *dentry) |
1891 | { | 1900 | { |
1892 | return 0; | 1901 | return 0; |
diff --git a/security/dummy.c b/security/dummy.c index 1db712d99dc7..c155f08e9dd8 100644 --- a/security/dummy.c +++ b/security/dummy.c | |||
@@ -194,6 +194,11 @@ static int dummy_sb_kern_mount (struct super_block *sb, void *data) | |||
194 | return 0; | 194 | return 0; |
195 | } | 195 | } |
196 | 196 | ||
197 | static int dummy_sb_show_options(struct seq_file *m, struct super_block *sb) | ||
198 | { | ||
199 | return 0; | ||
200 | } | ||
201 | |||
197 | static int dummy_sb_statfs (struct dentry *dentry) | 202 | static int dummy_sb_statfs (struct dentry *dentry) |
198 | { | 203 | { |
199 | return 0; | 204 | return 0; |
@@ -1088,6 +1093,7 @@ void security_fixup_ops (struct security_operations *ops) | |||
1088 | set_to_dummy_if_null(ops, sb_free_security); | 1093 | set_to_dummy_if_null(ops, sb_free_security); |
1089 | set_to_dummy_if_null(ops, sb_copy_data); | 1094 | set_to_dummy_if_null(ops, sb_copy_data); |
1090 | set_to_dummy_if_null(ops, sb_kern_mount); | 1095 | set_to_dummy_if_null(ops, sb_kern_mount); |
1096 | set_to_dummy_if_null(ops, sb_show_options); | ||
1091 | set_to_dummy_if_null(ops, sb_statfs); | 1097 | set_to_dummy_if_null(ops, sb_statfs); |
1092 | set_to_dummy_if_null(ops, sb_mount); | 1098 | set_to_dummy_if_null(ops, sb_mount); |
1093 | set_to_dummy_if_null(ops, sb_check_sb); | 1099 | set_to_dummy_if_null(ops, sb_check_sb); |
diff --git a/security/security.c b/security/security.c index 2c0a5876b939..de74fdccde26 100644 --- a/security/security.c +++ b/security/security.c | |||
@@ -292,6 +292,11 @@ int security_sb_kern_mount(struct super_block *sb, void *data) | |||
292 | return security_ops->sb_kern_mount(sb, data); | 292 | return security_ops->sb_kern_mount(sb, data); |
293 | } | 293 | } |
294 | 294 | ||
295 | int security_sb_show_options(struct seq_file *m, struct super_block *sb) | ||
296 | { | ||
297 | return security_ops->sb_show_options(m, sb); | ||
298 | } | ||
299 | |||
295 | int security_sb_statfs(struct dentry *dentry) | 300 | int security_sb_statfs(struct dentry *dentry) |
296 | { | 301 | { |
297 | return security_ops->sb_statfs(dentry); | 302 | return security_ops->sb_statfs(dentry); |
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 85f74f665765..33dee83fdd2f 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -9,7 +9,8 @@ | |||
9 | * James Morris <jmorris@redhat.com> | 9 | * James Morris <jmorris@redhat.com> |
10 | * | 10 | * |
11 | * Copyright (C) 2001,2002 Networks Associates Technology, Inc. | 11 | * Copyright (C) 2001,2002 Networks Associates Technology, Inc. |
12 | * Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com> | 12 | * Copyright (C) 2003-2008 Red Hat, Inc., James Morris <jmorris@redhat.com> |
13 | * Eric Paris <eparis@redhat.com> | ||
13 | * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. | 14 | * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. |
14 | * <dgoeddel@trustedcs.com> | 15 | * <dgoeddel@trustedcs.com> |
15 | * Copyright (C) 2006, 2007 Hewlett-Packard Development Company, L.P. | 16 | * Copyright (C) 2006, 2007 Hewlett-Packard Development Company, L.P. |
@@ -970,6 +971,57 @@ out_err: | |||
970 | return rc; | 971 | return rc; |
971 | } | 972 | } |
972 | 973 | ||
974 | void selinux_write_opts(struct seq_file *m, struct security_mnt_opts *opts) | ||
975 | { | ||
976 | int i; | ||
977 | char *prefix; | ||
978 | |||
979 | for (i = 0; i < opts->num_mnt_opts; i++) { | ||
980 | char *has_comma = strchr(opts->mnt_opts[i], ','); | ||
981 | |||
982 | switch (opts->mnt_opts_flags[i]) { | ||
983 | case CONTEXT_MNT: | ||
984 | prefix = CONTEXT_STR; | ||
985 | break; | ||
986 | case FSCONTEXT_MNT: | ||
987 | prefix = FSCONTEXT_STR; | ||
988 | break; | ||
989 | case ROOTCONTEXT_MNT: | ||
990 | prefix = ROOTCONTEXT_STR; | ||
991 | break; | ||
992 | case DEFCONTEXT_MNT: | ||
993 | prefix = DEFCONTEXT_STR; | ||
994 | break; | ||
995 | default: | ||
996 | BUG(); | ||
997 | }; | ||
998 | /* we need a comma before each option */ | ||
999 | seq_putc(m, ','); | ||
1000 | seq_puts(m, prefix); | ||
1001 | if (has_comma) | ||
1002 | seq_putc(m, '\"'); | ||
1003 | seq_puts(m, opts->mnt_opts[i]); | ||
1004 | if (has_comma) | ||
1005 | seq_putc(m, '\"'); | ||
1006 | } | ||
1007 | } | ||
1008 | |||
1009 | static int selinux_sb_show_options(struct seq_file *m, struct super_block *sb) | ||
1010 | { | ||
1011 | struct security_mnt_opts opts; | ||
1012 | int rc; | ||
1013 | |||
1014 | rc = selinux_get_mnt_opts(sb, &opts); | ||
1015 | if (rc) | ||
1016 | return rc; | ||
1017 | |||
1018 | selinux_write_opts(m, &opts); | ||
1019 | |||
1020 | security_free_mnt_opts(&opts); | ||
1021 | |||
1022 | return rc; | ||
1023 | } | ||
1024 | |||
973 | static inline u16 inode_mode_to_security_class(umode_t mode) | 1025 | static inline u16 inode_mode_to_security_class(umode_t mode) |
974 | { | 1026 | { |
975 | switch (mode & S_IFMT) { | 1027 | switch (mode & S_IFMT) { |
@@ -5365,6 +5417,7 @@ static struct security_operations selinux_ops = { | |||
5365 | .sb_free_security = selinux_sb_free_security, | 5417 | .sb_free_security = selinux_sb_free_security, |
5366 | .sb_copy_data = selinux_sb_copy_data, | 5418 | .sb_copy_data = selinux_sb_copy_data, |
5367 | .sb_kern_mount = selinux_sb_kern_mount, | 5419 | .sb_kern_mount = selinux_sb_kern_mount, |
5420 | .sb_show_options = selinux_sb_show_options, | ||
5368 | .sb_statfs = selinux_sb_statfs, | 5421 | .sb_statfs = selinux_sb_statfs, |
5369 | .sb_mount = selinux_mount, | 5422 | .sb_mount = selinux_mount, |
5370 | .sb_umount = selinux_umount, | 5423 | .sb_umount = selinux_umount, |