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>
This commit is contained in:
Eric Paris 2008-07-04 09:47:13 +10:00 коммит произвёл James Morris
Родитель 811f379927
Коммит 2069f45784
5 изменённых файлов: 85 добавлений и 4 удалений

Просмотреть файл

@ -750,7 +750,7 @@ struct proc_fs_info {
const char *str; const char *str;
}; };
static void show_sb_opts(struct seq_file *m, struct super_block *sb) static int show_sb_opts(struct seq_file *m, struct super_block *sb)
{ {
static const struct proc_fs_info fs_info[] = { static const struct proc_fs_info fs_info[] = {
{ MS_SYNCHRONOUS, ",sync" }, { MS_SYNCHRONOUS, ",sync" },
@ -764,6 +764,8 @@ static void show_sb_opts(struct seq_file *m, struct super_block *sb)
if (sb->s_flags & fs_infop->flag) if (sb->s_flags & fs_infop->flag)
seq_puts(m, fs_infop->str); seq_puts(m, fs_infop->str);
} }
return security_sb_show_options(m, sb);
} }
static void show_mnt_opts(struct seq_file *m, struct vfsmount *mnt) 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)
seq_putc(m, ' '); seq_putc(m, ' ');
show_type(m, mnt->mnt_sb); show_type(m, mnt->mnt_sb);
seq_puts(m, __mnt_is_readonly(mnt) ? " ro" : " rw"); seq_puts(m, __mnt_is_readonly(mnt) ? " ro" : " rw");
show_sb_opts(m, mnt->mnt_sb); err = show_sb_opts(m, mnt->mnt_sb);
if (err)
goto out;
show_mnt_opts(m, mnt); show_mnt_opts(m, mnt);
if (mnt->mnt_sb->s_op->show_options) if (mnt->mnt_sb->s_op->show_options)
err = mnt->mnt_sb->s_op->show_options(m, mnt); err = mnt->mnt_sb->s_op->show_options(m, mnt);
seq_puts(m, " 0 0\n"); seq_puts(m, " 0 0\n");
out:
return err; return err;
} }
@ -865,10 +870,13 @@ static int show_mountinfo(struct seq_file *m, void *v)
seq_putc(m, ' '); seq_putc(m, ' ');
mangle(m, mnt->mnt_devname ? mnt->mnt_devname : "none"); mangle(m, mnt->mnt_devname ? mnt->mnt_devname : "none");
seq_puts(m, sb->s_flags & MS_RDONLY ? " ro" : " rw"); seq_puts(m, sb->s_flags & MS_RDONLY ? " ro" : " rw");
show_sb_opts(m, sb); err = show_sb_opts(m, sb);
if (err)
goto out;
if (sb->s_op->show_options) if (sb->s_op->show_options)
err = sb->s_op->show_options(m, mnt); err = sb->s_op->show_options(m, mnt);
seq_putc(m, '\n'); seq_putc(m, '\n');
out:
return err; return err;
} }

Просмотреть файл

@ -80,6 +80,7 @@ struct xfrm_selector;
struct xfrm_policy; struct xfrm_policy;
struct xfrm_state; struct xfrm_state;
struct xfrm_user_sec_ctx; struct xfrm_user_sec_ctx;
struct seq_file;
extern int cap_netlink_send(struct sock *sk, struct sk_buff *skb); extern int cap_netlink_send(struct sock *sk, struct sk_buff *skb);
extern int cap_netlink_recv(struct sk_buff *skb, int cap); extern int cap_netlink_recv(struct sk_buff *skb, int cap);
@ -1331,6 +1332,7 @@ struct security_operations {
void (*sb_free_security) (struct super_block *sb); void (*sb_free_security) (struct super_block *sb);
int (*sb_copy_data) (char *orig, char *copy); int (*sb_copy_data) (char *orig, char *copy);
int (*sb_kern_mount) (struct super_block *sb, void *data); int (*sb_kern_mount) (struct super_block *sb, void *data);
int (*sb_show_options) (struct seq_file *m, struct super_block *sb);
int (*sb_statfs) (struct dentry *dentry); int (*sb_statfs) (struct dentry *dentry);
int (*sb_mount) (char *dev_name, struct path *path, int (*sb_mount) (char *dev_name, struct path *path,
char *type, unsigned long flags, void *data); char *type, unsigned long flags, void *data);
@ -1610,6 +1612,7 @@ int security_sb_alloc(struct super_block *sb);
void security_sb_free(struct super_block *sb); void security_sb_free(struct super_block *sb);
int security_sb_copy_data(char *orig, char *copy); int security_sb_copy_data(char *orig, char *copy);
int security_sb_kern_mount(struct super_block *sb, void *data); int security_sb_kern_mount(struct super_block *sb, void *data);
int security_sb_show_options(struct seq_file *m, struct super_block *sb);
int security_sb_statfs(struct dentry *dentry); int security_sb_statfs(struct dentry *dentry);
int security_sb_mount(char *dev_name, struct path *path, int security_sb_mount(char *dev_name, struct path *path,
char *type, unsigned long flags, void *data); char *type, unsigned long flags, void *data);
@ -1887,6 +1890,12 @@ static inline int security_sb_kern_mount(struct super_block *sb, void *data)
return 0; return 0;
} }
static inline int security_sb_show_options(struct seq_file *m,
struct super_block *sb)
{
return 0;
}
static inline int security_sb_statfs(struct dentry *dentry) static inline int security_sb_statfs(struct dentry *dentry)
{ {
return 0; return 0;

Просмотреть файл

@ -194,6 +194,11 @@ static int dummy_sb_kern_mount (struct super_block *sb, void *data)
return 0; return 0;
} }
static int dummy_sb_show_options(struct seq_file *m, struct super_block *sb)
{
return 0;
}
static int dummy_sb_statfs (struct dentry *dentry) static int dummy_sb_statfs (struct dentry *dentry)
{ {
return 0; return 0;
@ -1088,6 +1093,7 @@ void security_fixup_ops (struct security_operations *ops)
set_to_dummy_if_null(ops, sb_free_security); set_to_dummy_if_null(ops, sb_free_security);
set_to_dummy_if_null(ops, sb_copy_data); set_to_dummy_if_null(ops, sb_copy_data);
set_to_dummy_if_null(ops, sb_kern_mount); set_to_dummy_if_null(ops, sb_kern_mount);
set_to_dummy_if_null(ops, sb_show_options);
set_to_dummy_if_null(ops, sb_statfs); set_to_dummy_if_null(ops, sb_statfs);
set_to_dummy_if_null(ops, sb_mount); set_to_dummy_if_null(ops, sb_mount);
set_to_dummy_if_null(ops, sb_check_sb); set_to_dummy_if_null(ops, sb_check_sb);

Просмотреть файл

@ -292,6 +292,11 @@ int security_sb_kern_mount(struct super_block *sb, void *data)
return security_ops->sb_kern_mount(sb, data); return security_ops->sb_kern_mount(sb, data);
} }
int security_sb_show_options(struct seq_file *m, struct super_block *sb)
{
return security_ops->sb_show_options(m, sb);
}
int security_sb_statfs(struct dentry *dentry) int security_sb_statfs(struct dentry *dentry)
{ {
return security_ops->sb_statfs(dentry); return security_ops->sb_statfs(dentry);

Просмотреть файл

@ -9,7 +9,8 @@
* James Morris <jmorris@redhat.com> * James Morris <jmorris@redhat.com>
* *
* Copyright (C) 2001,2002 Networks Associates Technology, Inc. * Copyright (C) 2001,2002 Networks Associates Technology, Inc.
* Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com> * Copyright (C) 2003-2008 Red Hat, Inc., James Morris <jmorris@redhat.com>
* Eric Paris <eparis@redhat.com>
* Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc.
* <dgoeddel@trustedcs.com> * <dgoeddel@trustedcs.com>
* Copyright (C) 2006, 2007 Hewlett-Packard Development Company, L.P. * Copyright (C) 2006, 2007 Hewlett-Packard Development Company, L.P.
@ -970,6 +971,57 @@ out_err:
return rc; return rc;
} }
void selinux_write_opts(struct seq_file *m, struct security_mnt_opts *opts)
{
int i;
char *prefix;
for (i = 0; i < opts->num_mnt_opts; i++) {
char *has_comma = strchr(opts->mnt_opts[i], ',');
switch (opts->mnt_opts_flags[i]) {
case CONTEXT_MNT:
prefix = CONTEXT_STR;
break;
case FSCONTEXT_MNT:
prefix = FSCONTEXT_STR;
break;
case ROOTCONTEXT_MNT:
prefix = ROOTCONTEXT_STR;
break;
case DEFCONTEXT_MNT:
prefix = DEFCONTEXT_STR;
break;
default:
BUG();
};
/* we need a comma before each option */
seq_putc(m, ',');
seq_puts(m, prefix);
if (has_comma)
seq_putc(m, '\"');
seq_puts(m, opts->mnt_opts[i]);
if (has_comma)
seq_putc(m, '\"');
}
}
static int selinux_sb_show_options(struct seq_file *m, struct super_block *sb)
{
struct security_mnt_opts opts;
int rc;
rc = selinux_get_mnt_opts(sb, &opts);
if (rc)
return rc;
selinux_write_opts(m, &opts);
security_free_mnt_opts(&opts);
return rc;
}
static inline u16 inode_mode_to_security_class(umode_t mode) static inline u16 inode_mode_to_security_class(umode_t mode)
{ {
switch (mode & S_IFMT) { switch (mode & S_IFMT) {
@ -5365,6 +5417,7 @@ static struct security_operations selinux_ops = {
.sb_free_security = selinux_sb_free_security, .sb_free_security = selinux_sb_free_security,
.sb_copy_data = selinux_sb_copy_data, .sb_copy_data = selinux_sb_copy_data,
.sb_kern_mount = selinux_sb_kern_mount, .sb_kern_mount = selinux_sb_kern_mount,
.sb_show_options = selinux_sb_show_options,
.sb_statfs = selinux_sb_statfs, .sb_statfs = selinux_sb_statfs,
.sb_mount = selinux_mount, .sb_mount = selinux_mount,
.sb_umount = selinux_umount, .sb_umount = selinux_umount,