apparmor: add special .null file used to "close" fds at exec
Borrow the special null device file from selinux to "close" fds that don't have sufficient permissions at exec time. Signed-off-by: John Johansen <john.johansen@canonical.com>
This commit is contained in:
parent
34c426acb7
commit
a71ada3058
3 changed files with 81 additions and 1 deletions
|
@ -18,9 +18,12 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/mount.h>
|
||||
#include <linux/namei.h>
|
||||
#include <linux/capability.h>
|
||||
#include <linux/rcupdate.h>
|
||||
#include <uapi/linux/major.h>
|
||||
#include <linux/fs.h>
|
||||
|
||||
#include "include/apparmor.h"
|
||||
#include "include/apparmorfs.h"
|
||||
|
@ -352,6 +355,28 @@ static const struct file_operations aa_fs_seq_hash_fops = {
|
|||
.release = single_release,
|
||||
};
|
||||
|
||||
static int aa_fs_seq_show_ns_level(struct seq_file *seq, void *v)
|
||||
{
|
||||
struct aa_ns *ns = aa_current_profile()->ns;
|
||||
|
||||
seq_printf(seq, "%d\n", ns->level);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aa_fs_seq_open_ns_level(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, aa_fs_seq_show_ns_level, inode->i_private);
|
||||
}
|
||||
|
||||
static const struct file_operations aa_fs_ns_level = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = aa_fs_seq_open_ns_level,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
};
|
||||
|
||||
/** fns to setup dynamic per profile/namespace files **/
|
||||
void __aa_fs_profile_rmdir(struct aa_profile *profile)
|
||||
{
|
||||
|
@ -825,6 +850,7 @@ static struct aa_fs_entry aa_fs_entry_apparmor[] = {
|
|||
AA_FS_FILE_FOPS(".load", 0640, &aa_fs_profile_load),
|
||||
AA_FS_FILE_FOPS(".replace", 0640, &aa_fs_profile_replace),
|
||||
AA_FS_FILE_FOPS(".remove", 0640, &aa_fs_profile_remove),
|
||||
AA_FS_FILE_FOPS(".ns_level", 0666, &aa_fs_ns_level),
|
||||
AA_FS_FILE_FOPS("profiles", 0640, &aa_fs_profiles_fops),
|
||||
AA_FS_DIR("features", aa_fs_entry_features),
|
||||
{ }
|
||||
|
@ -934,6 +960,52 @@ void __init aa_destroy_aafs(void)
|
|||
aafs_remove_dir(&aa_fs_entry);
|
||||
}
|
||||
|
||||
|
||||
#define NULL_FILE_NAME ".null"
|
||||
struct path aa_null;
|
||||
|
||||
static int aa_mk_null_file(struct dentry *parent)
|
||||
{
|
||||
struct vfsmount *mount = NULL;
|
||||
struct dentry *dentry;
|
||||
struct inode *inode;
|
||||
int count = 0;
|
||||
int error = simple_pin_fs(parent->d_sb->s_type, &mount, &count);
|
||||
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
inode_lock(d_inode(parent));
|
||||
dentry = lookup_one_len(NULL_FILE_NAME, parent, strlen(NULL_FILE_NAME));
|
||||
if (IS_ERR(dentry)) {
|
||||
error = PTR_ERR(dentry);
|
||||
goto out;
|
||||
}
|
||||
inode = new_inode(parent->d_inode->i_sb);
|
||||
if (!inode) {
|
||||
error = -ENOMEM;
|
||||
goto out1;
|
||||
}
|
||||
|
||||
inode->i_ino = get_next_ino();
|
||||
inode->i_mode = S_IFCHR | S_IRUGO | S_IWUGO;
|
||||
inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
|
||||
init_special_inode(inode, S_IFCHR | S_IRUGO | S_IWUGO,
|
||||
MKDEV(MEM_MAJOR, 3));
|
||||
d_instantiate(dentry, inode);
|
||||
aa_null.dentry = dget(dentry);
|
||||
aa_null.mnt = mntget(mount);
|
||||
|
||||
error = 0;
|
||||
|
||||
out1:
|
||||
dput(dentry);
|
||||
out:
|
||||
inode_unlock(d_inode(parent));
|
||||
simple_release_fs(&mount, &count);
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
* aa_create_aafs - create the apparmor security filesystem
|
||||
*
|
||||
|
@ -962,7 +1034,11 @@ static int __init aa_create_aafs(void)
|
|||
if (error)
|
||||
goto error;
|
||||
|
||||
/* TODO: add support for apparmorfs_null and apparmorfs_mnt */
|
||||
error = aa_mk_null_file(aa_fs_entry.dentry);
|
||||
if (error)
|
||||
goto error;
|
||||
|
||||
/* TODO: add default profile to apparmorfs */
|
||||
|
||||
/* Report that AppArmor fs is enabled */
|
||||
aa_info_message("AppArmor Filesystem Enabled");
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
#ifndef __AA_APPARMORFS_H
|
||||
#define __AA_APPARMORFS_H
|
||||
|
||||
extern struct path aa_null;
|
||||
|
||||
enum aa_fs_type {
|
||||
AA_FS_TYPE_BOOLEAN,
|
||||
AA_FS_TYPE_STRING,
|
||||
|
|
|
@ -44,6 +44,7 @@ struct aa_ns_acct {
|
|||
* @sub_ns: list of namespaces under the current namespace.
|
||||
* @uniq_null: uniq value used for null learning profiles
|
||||
* @uniq_id: a unique id count for the profiles in the namespace
|
||||
* @level: level of ns within the tree hierarchy
|
||||
* @dents: dentries for the namespaces file entries in apparmorfs
|
||||
*
|
||||
* An aa_ns defines the set profiles that are searched to determine which
|
||||
|
@ -66,6 +67,7 @@ struct aa_ns {
|
|||
struct list_head sub_ns;
|
||||
atomic_t uniq_null;
|
||||
long uniq_id;
|
||||
int level;
|
||||
|
||||
struct dentry *dents[AAFS_NS_SIZEOF];
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue