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:
parent
811f379927
commit
2069f45784
5 changed files with 85 additions and 4 deletions
|
@ -750,7 +750,7 @@ struct proc_fs_info {
|
|||
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[] = {
|
||||
{ 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)
|
||||
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)
|
||||
|
@ -806,11 +808,14 @@ static int show_vfsmnt(struct seq_file *m, void *v)
|
|||
seq_putc(m, ' ');
|
||||
show_type(m, mnt->mnt_sb);
|
||||
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);
|
||||
if (mnt->mnt_sb->s_op->show_options)
|
||||
err = mnt->mnt_sb->s_op->show_options(m, mnt);
|
||||
seq_puts(m, " 0 0\n");
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -865,10 +870,13 @@ static int show_mountinfo(struct seq_file *m, void *v)
|
|||
seq_putc(m, ' ');
|
||||
mangle(m, mnt->mnt_devname ? mnt->mnt_devname : "none");
|
||||
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)
|
||||
err = sb->s_op->show_options(m, mnt);
|
||||
seq_putc(m, '\n');
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
|
@ -80,6 +80,7 @@ struct xfrm_selector;
|
|||
struct xfrm_policy;
|
||||
struct xfrm_state;
|
||||
struct xfrm_user_sec_ctx;
|
||||
struct seq_file;
|
||||
|
||||
extern int cap_netlink_send(struct sock *sk, struct sk_buff *skb);
|
||||
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);
|
||||
int (*sb_copy_data) (char *orig, char *copy);
|
||||
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_mount) (char *dev_name, struct path *path,
|
||||
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);
|
||||
int security_sb_copy_data(char *orig, char *copy);
|
||||
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_mount(char *dev_name, struct path *path,
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
return 0;
|
||||
|
|
|
@ -194,6 +194,11 @@ static int dummy_sb_kern_mount (struct super_block *sb, void *data)
|
|||
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)
|
||||
{
|
||||
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_copy_data);
|
||||
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_mount);
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
return security_ops->sb_statfs(dentry);
|
||||
|
|
|
@ -9,7 +9,8 @@
|
|||
* James Morris <jmorris@redhat.com>
|
||||
*
|
||||
* 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.
|
||||
* <dgoeddel@trustedcs.com>
|
||||
* Copyright (C) 2006, 2007 Hewlett-Packard Development Company, L.P.
|
||||
|
@ -970,6 +971,57 @@ static int superblock_doinit(struct super_block *sb, void *data)
|
|||
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)
|
||||
{
|
||||
switch (mode & S_IFMT) {
|
||||
|
@ -5365,6 +5417,7 @@ static struct security_operations selinux_ops = {
|
|||
.sb_free_security = selinux_sb_free_security,
|
||||
.sb_copy_data = selinux_sb_copy_data,
|
||||
.sb_kern_mount = selinux_sb_kern_mount,
|
||||
.sb_show_options = selinux_sb_show_options,
|
||||
.sb_statfs = selinux_sb_statfs,
|
||||
.sb_mount = selinux_mount,
|
||||
.sb_umount = selinux_umount,
|
||||
|
|
Loading…
Reference in a new issue