Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <2236FBA76BA1254E88B949DDB74E612B41B6FB4C@IRSMSX102.ger.corp.intel.com>
Date: Fri, 29 Jul 2016 12:15:53 +0000
From: "Reshetova, Elena" <elena.reshetova@...el.com>
To: Brad Spengler <spender@...ecurity.net>
CC: "kernel-hardening@...ts.openwall.com"
	<kernel-hardening@...ts.openwall.com>,
	"linux-security-module@...r.kernel.org"
	<linux-security-module@...r.kernel.org>, "keescook@...omium.org"
	<keescook@...omium.org>, "jmorris@...ei.org" <jmorris@...ei.org>,
	"Schaufler, Casey" <casey.schaufler@...el.com>, "Leibowitz, Michael"
	<michael.leibowitz@...el.com>, "Roberts, William C"
	<william.c.roberts@...el.com>
Subject: RE: [RFC] [PATCH 5/5] Hardchroot LSM

>This again is completely unacceptable.

>> + * Copyright (c) 2016, Intel Corporation

>You know full well several functions in this code are completely
>copy+pasted from grsecurity, keeping unnecessary types, same exact
>variable names, same exact casts, same exact code structure.  In other
cases you've simply renamed variables.  Last time I had to mention this, the
entirety of my RANDSTRUCT plugin had been copy+pasted by an Intel employee
with Intel's copyright >placed alone on the top of it.
>Why does Intel have such a problem with plagiarism?

I am not sure how to handle the copyright statement in this case. Part of
code comes from your code (and acknowledgment provided), task management
done based on Yama (also acknowledged), part of code is modified, new and
etc. 
I will ask lawyers on this to clarify since this is not really my choice. I
am not interested to take credit for this, I was just interested to make the
feature work inside LSM and be accepted to upstream.

>Yes, there are some original changes in here, but this doesn't seem to have
been tested at all -- I see obvious ways of bypassing it, and some of the
checks that have been modified (aka single lines that weren't copy+pasted)
are now wrong and simply >won't work at all.

It was actually tested, I won't send untested code for review. I have tested
this on Ubuntu and Fedora, as well as with Ubuntu standard chroot. I don't
have any automatic tests done yet and there are couple of corner cases that
I omitted now, as I don't mark process from init_mount_tree(), don't
restrict filename lookup yet, don't cover mount with MS_MOVE flag and etc.
This is beginning of the work to bring all these features in place, and I
figured I would get initial comments earlier than later on this. 

>I'm sure Kees will save the day though by repeating the flaw I just
mentioned on IRC.  For the rest, Intel will have to do some actual original
work for a change.

This was actually the main point of sending these patches now, I want
feedback and I am grateful for it. So, thank you! Anything you can point out
is valuable. 


> +#include <linux/lsm_hooks.h>
> +#include <linux/sysctl.h>
> +#include <linux/fs_struct.h>
> +#include <linux/nsproxy.h>
> +#include <linux/pid_namespace.h>
> +#include <linux/printk.h>
> +#include "../fs/mount.h"
> +
> +/* describe a hardchroot info for a task */ struct hardchroot_info {
> +	struct task_struct *task;
> +	struct dentry *dentry;
> +	bool invalid;
> +	struct list_head node;
> +	struct rcu_head rcu;
> +};
> +
> +static LIST_HEAD(hardchroot_infos);
> +static DEFINE_SPINLOCK(hardchroot_infos_lock);
> +
> +static void hardchroot_info_cleanup(struct work_struct *work); static 
> +DECLARE_WORK(hardchroot_info_work, hardchroot_info_cleanup);
> +
> +/**
> + * hardchroot_info_cleanup - remove invalid entries from
> + * the hardchroot info list.
> + */
> +static void hardchroot_info_cleanup(struct work_struct *work) {
> +	struct hardchroot_info *entry;
> +
> +	spin_lock(&hardchroot_infos_lock);
> +	rcu_read_lock();
> +	list_for_each_entry_rcu(entry, &hardchroot_infos, node) {
> +		if (entry->invalid) {
> +			list_del_rcu(&entry->node);
> +			kfree_rcu(entry, rcu);
> +		}
> +	}
> +	rcu_read_unlock();
> +	spin_unlock(&hardchroot_infos_lock);
> +}
> +
> +/**
> + * hardchroot_info_add - add/replace
> + * @task: the task_struct of the process entering chroot
> + * @dentry: the chroot dentry
> + *
> + * Returns 0 if info was added, -ve on error.
> + */
> +static int hardchroot_info_add(struct task_struct *task,
> +				struct dentry *dentry)
> +{
> +	struct hardchroot_info *entry;
> +	struct hardchroot_info *added;
> +
> +	added = kmalloc(sizeof(*added), GFP_KERNEL);
> +	if (!added)
> +		return -ENOMEM;
> +
> +	added->task = task;
> +	added->dentry = dentry;
> +	added->invalid = false;
> +
> +	spin_lock(&hardchroot_infos_lock);
> +	rcu_read_lock();
> +	list_for_each_entry_rcu(entry, &hardchroot_infos, node) {
> +		if (entry->invalid)
> +			continue;
> +		if (entry->task == task) {
> +			list_replace_rcu(&entry->node, &added->node);
> +			kfree_rcu(entry, rcu);
> +			goto out;
> +		}
> +	}
> +
> +	list_add_rcu(&added->node, &hardchroot_infos);
> +
> +out:
> +	rcu_read_unlock();
> +	spin_unlock(&hardchroot_infos_lock);
> +	return 0;
> +}
> +
> +/**
> + * hardchroot_info_del - remove hardchroot info for a given task
> + * @task: remove any relation where task matches
> + * @dentry: remove any relation where dentry matches  */ static void 
> +hardchroot_info_del(struct task_struct *task,
> +				struct dentry *dentry)
> +{
> +	struct hardchroot_info *entry;
> +	bool marked = false;
> +
> +	rcu_read_lock();
> +	list_for_each_entry_rcu(entry, &hardchroot_infos, node) {
> +		if (entry->invalid)
> +			continue;
> +		if (entry->task == task ||
> +			(dentry && entry->dentry == dentry)) {
> +			entry->invalid = true;
> +			marked = true;
> +		}
> +	}
> +	rcu_read_unlock();
> +
> +	if (marked)
> +		schedule_work(&hardchroot_info_work);
> +}
> +
> +/**
> + * hardchroot_task_free - remove task from exception list
> + * @task: task being removed
> + */
> +void hardchroot_task_free(struct task_struct *task) {
> +	hardchroot_info_del(task, NULL);
> +}
> +
> +/**
> + * task_is_descendant - walk up a process family tree looking for a 
> +match
> + * The function is taken from Yama LSM
> + * @parent: the process to compare against while walking up from 
> +child
> + * @child: the process to start from while looking upwards for parent
> + *
> + * Returns 1 if child is a descendant of parent, 0 if not.
> + */
> +static int task_is_descendant(struct task_struct *parent,
> +				  struct task_struct *child)
> +{
> +	int rc = 0;
> +	struct task_struct *walker = child;
> +
> +	if (!parent || !child)
> +		return 0;
> +
> +	rcu_read_lock();
> +	if (!thread_group_leader(parent))
> +		parent = rcu_dereference(parent->group_leader);
> +	while (walker->pid > 0) {
> +		if (!thread_group_leader(walker))
> +			walker = rcu_dereference(walker->group_leader);
> +		if (walker == parent) {
> +			rc = 1;
> +			break;
> +		}
> +		walker = rcu_dereference(walker->real_parent);
> +	}
> +	rcu_read_unlock();
> +
> +	return rc;
> +}
> +
> +/**
> + * is_process_chrooted - process is inside chroot
> + * @task: the task_struct of the process to be checked
> + *
> + * Returns 1 if task is inside chroot.
> + */
> +static int is_process_chrooted(struct task_struct *task) {
> +	int rc = 0;
> +	struct hardchroot_info *entry;
> +
> +	rcu_read_lock();
> +	list_for_each_entry_rcu(entry, &hardchroot_infos, node) {
> +		if (entry->invalid)
> +			continue;
> +		if ((entry->task == task) ||
> +			(task_is_descendant(entry->task, task))) {
> +			rc = 1;
> +			pr_info("HCRT: pid %d is already chrooted\n",
> +			task_pid_nr(entry->task));
> +			break;
> +		}
> +	}
> +	rcu_read_unlock();
> +	return rc;
> +}
> +
> +/**
> + * is_same_root - check if two tasks share the same root
> + * @task1: the task_struct of the first task to be checked
> + * @task2: the task_struct of the second task to be checked
> + *
> + * Returns 1 if tasks share the same root.
> + */
> +static int is_same_root(struct task_struct *task1, struct task_struct 
> +*task2) {
> +	int rc = 0;
> +	struct hardchroot_info *entry;
> +	struct dentry *dentry1 = NULL;
> +	struct dentry *dentry2 = NULL;
> +
> +	rcu_read_lock();
> +	list_for_each_entry_rcu(entry, &hardchroot_infos, node) {
> +		if (entry->invalid)
> +			continue;
> +		if (entry->task == task1)
> +			dentry1 = entry->dentry;
> +		if (entry->task == task2)
> +			dentry2 = entry->dentry;
> +	}
> +	if (dentry1 && (dentry1 == dentry2)) {
> +		rc = 1;
> +		pr_info("HCRT: pids %d and %d have the same root\n",
> +				task_pid_nr(task1), task_pid_nr(task2));
> +	}
> +	rcu_read_unlock();
> +	return rc;
> +}
> +
> +/**
> + * is_inside_chroot - check if dentry and mount
> + * are inside the current process fs root
> + * @u_dentry: dentry to be checked
> + * @u_mnt: mnt to be checked
> + *
> + * Returns 1 if dentry and mount are under fs root.
> + */
> +int is_inside_chroot(const struct dentry *u_dentry,
> +			const struct vfsmount *u_mnt)
> +{
> +	struct path path;
> +	struct path currentroot;
> +	int ret = 0;
> +
> +	path.dentry = (struct dentry *)u_dentry;
> +	path.mnt = (struct vfsmount *)u_mnt;
> +	get_fs_root(current->fs, &currentroot);
> +	if (path_is_under(&path, &currentroot))
> +		ret = 1;
> +	else
> +		pr_info("HCRT: dentry %lu is outside current task %d
root\n",
> +				d_backing_inode(u_dentry)->i_ino,
> +				task_pid_nr(current));
> +	path_put(&currentroot);
> +	return ret;
> +}
> +
> +/**
> + * hardchroot_path_chroot - validate chroot entry
> + * @path contains the path structure.
> + *
> + * Returns 0 if chroot is allowed, -ve on error.
> + */
> +static int hardchroot_path_chroot(const struct path *path) {
> +	int rc = 0;
> +	struct task_struct *myself = current;
> +
> +	pr_info("HCRT, chroot: inode %lu and pid %d\n",
> +			d_backing_inode(path->dentry)->i_ino,
> +			task_pid_nr(myself));
> +
> +	get_task_struct(myself);
> +	if (is_process_chrooted(myself) &&
> +		!is_inside_chroot(path->dentry, path->mnt)) {
> +		put_task_struct(myself);
> +		pr_info("HCRT, chroot denied: for inode %lu and pid %d\n",
> +				d_backing_inode(path->dentry)->i_ino,
> +				task_pid_nr(myself));
> +		return -EACCES;
> +	}
> +
> +	if (task_pid_nr(myself) > 1 &&
> +		path->dentry != init_task.fs->root.dentry &&
> +		path->dentry != myself->nsproxy->mnt_ns->root->mnt.mnt_root)
{
> +		/* task is attempting to chroot, add it to the list */
> +		rc = hardchroot_info_add(myself, path->dentry);
> +		pr_info("HCRT, chroot: adding %d to chrooted task list\n",
> +			task_pid_nr(myself));
> +	}
> +
> +	/* set the current working directory of all newly-chrooted
> +	 * processes to the the root directory of the chroot
> +	 */
> +	set_fs_pwd(myself->fs, path);
> +	put_task_struct(myself);
> +
> +	return rc;
> +}
> +
> +/**
> + * hardchroot_task_unshare - check if process is
> + * allowed to unshare its namespaces
> + * @unshare_flags flags
> + * @new_fs contains the new fs_struct if created.
> + * @new_fd contains the new files_struct if created.
> + * @new_creds contains the new cred if created.
> + * @new_nsproxy contains the new nsproxy if created.
> + *
> + * Returns 0 if unshare is allowed, -ve on error.
> + */
> +static int hardchroot_task_unshare(unsigned long unshare_flags,
> +		const struct fs_struct *new_fs,
> +		const struct files_struct *new_fd,
> +		const struct cred *new_cred,
> +		const struct nsproxy *new_nsproxy)
> +{
> +	int rc = 0;
> +	struct task_struct *myself = current;
> +	const struct nsproxy *tnsproxy = new_nsproxy;
> +
> +	pr_info("HCRT, unshare: unshare_flags %lu and pid %d\n",
> +			unshare_flags, task_pid_nr(myself));
> +	if (new_fs)
> +		pr_info("HCRT, unshare: new_fs->root.dentry inode%lu\n",
> +			d_backing_inode(new_fs->root.dentry)->i_ino);
> +
> +	if (!tnsproxy)
> +		tnsproxy = myself->nsproxy;
> +
> +	if (new_fs && task_pid_nr(myself) > 1 &&
> +		new_fs->root.dentry != init_task.fs->root.dentry &&
> +		new_fs->root.dentry != tnsproxy->mnt_ns->root->mnt.mnt_root)
{
> +		rc = hardchroot_info_add(myself, new_fs->root.dentry);
> +		pr_info("HCRT, unshare: adding %d to chrooted task list\n",
> +			task_pid_nr(myself));
> +	}
> +
> +	return rc;
> +}
> +
> +/**
> + * hardchroot_sb_unsharefs - check if process is
> + * allowed to unshare fs_struct
> + * @path contains the path for the new root structure.
> + *
> + * Returns 0 if unsharefs is allowed, -ve on error.
> + */
> +static int hardchroot_sb_unsharefs(const struct path *path) {
> +	int rc = 0;
> +	struct task_struct *myself = current;
> +
> +	pr_info("HCRT, unsharefs: inode %lu and pid %d\n",
> +			d_backing_inode(path->dentry)->i_ino,
> +			task_pid_nr(myself));
> +
> +	if (task_pid_nr(myself) > 1 &&
> +		path->dentry != init_task.fs->root.dentry &&
> +		path->dentry != myself->nsproxy->mnt_ns->root->mnt.mnt_root)
{
> +		rc = hardchroot_info_add(myself, path->dentry);
> +		pr_info("HCRT, unsharefs: adding %d to chrooted task
list\n",
> +			task_pid_nr(myself));
> +	}
> +
> +	return rc;
> +}
> +
> +/**
> + * hardchroot_path_chmod - validate if chmod is allowed
> + * @mnt contains the vfsmnt structure.
> + * @mode contains DAC's mode
> + *
> + * Returns 0 if allowed, -ve on error.
> + */
> +static int hardchroot_path_chmod(const struct path *path, umode_t 
> +mode) {
> +	int rc = 0;
> +	struct task_struct *myself = current;
> +
> +	pr_info("HCRT, chmod: inode %lu, pid %d\n",
> +			d_backing_inode(path->dentry)->i_ino,
> +			task_pid_nr(myself));
> +
> +	/* allow chmod +s on directories, but not files */
> +	if (!S_ISDIR(path->dentry->d_inode->i_mode) && ((mode & S_ISUID) ||
> +		((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP))) &&
> +		is_process_chrooted(myself)) {
> +		pr_info("HCRT, chmod denied: inode %lu, pid %d\n",
> +				d_backing_inode(path->dentry)->i_ino,
> +				task_pid_nr(myself));
> +		return -EACCES;
> +	}
> +
> +	return rc;
> +
> +}
> +
> +/**
> + * hardchroot_path_fchdir - validate if fchdir is allowed
> + * @path: contains the path structure
> + *
> + * Returns 0 if allowed, -ve on error.
> + */
> +static int hardchroot_path_fchdir(const struct path *path) {
> +	int rc = 0;
> +	struct task_struct *myself = current;
> +
> +	pr_info("HCRT, fchdir: pid %d, path %lu",
> +			task_pid_nr(myself),
> +			d_backing_inode(path->dentry)->i_ino);
> +
> +	if (!is_process_chrooted(myself))
> +		return rc;
> +	if (!is_inside_chroot(path->dentry, path->mnt)) {
> +		pr_info("HCRT, fchdir denied: pid %d, path %lu",
> +			task_pid_nr(myself),
> +			d_backing_inode(path->dentry)->i_ino);
> +		return -EACCES;
> +	}
> +
> +	return rc;
> +}
> +
> +/**
> + * hardchroot_path_fhandle - validate if converting
> + * handle to path is allowed
> + * @path: contains the path structure
> + *
> + * Returns 0 if allowed, -ve on error.
> + */
> +static int hardchroot_path_fhandle(const struct path *path) {
> +	int rc = 0;
> +	struct task_struct *myself = current;
> +
> +	pr_info("HCRT, fhandle: pid %d, path %lu",
> +			task_pid_nr(myself),
> +			d_backing_inode(path->dentry)->i_ino);
> +
> +	if (is_process_chrooted(myself)) {
> +		pr_info("HCRT, fhandle denied: pid %d, path %lu",
> +			task_pid_nr(myself),
> +			d_backing_inode(path->dentry)->i_ino);
> +		return -EACCES;
> +	}
> +
> +	return rc;
> +}
> +
> +/**
> + * hardchroot_task_setnice - check if setting nice is allowed
> + * @task contains the task_struct of process.
> + * @nice contains the new nice value.
> + *
> + * Return 0 if allowed, -ve on error.
> + */
> +static int hardchroot_task_setnice(struct task_struct *task, int 
> +nice) {
> +	int rc = 0;
> +	struct task_struct *myself = current;
> +
> +	pr_info("HCRT, setnice: current %d, nice %d, for pid %d and current
nice %d\n",
> +			task_pid_nr(myself), nice,
> +			task_pid_nr(task), task_nice(task));
> +
> +	if (is_process_chrooted(myself) && (nice < task_nice(task))) {
> +		pr_info("HCRT, setnice denied: current %d, nice %d, for pid
%d and current nice %d\n",
> +			task_pid_nr(myself), nice,
> +			task_pid_nr(task), task_nice(task));
> +		return -EACCES;
> +	}
> +	return rc;
> +}
> +
> +/**
> + * hardchroot_path_mknod - check if mknod is allowed
> + * @dir contains the path structure of parent of the new file.
> + * @dentry contains the dentry structure of the new file.
> + * @mode contains the mode of the new file.
> + * @dev contains the undecoded device number. Use new_decode_dev() to 
> +get
> + * the decoded device number.
> + *
> + * Return 0 if allowed, -ve on error.
> + */
> +static int hardchroot_path_mknod(const struct path *dir, struct dentry
*dentry,
> +			umode_t mode, unsigned int dev)
> +{
> +	int rc = 0;
> +	struct task_struct *myself = current;
> +
> +	pr_info("HCRT, mknod: dir %lu, mode %d pid %d\n",
> +				d_backing_inode(dir->dentry)->i_ino,
> +				mode, task_pid_nr(myself));
> +
> +	if (!S_ISFIFO(mode) && !S_ISREG(mode) &&
is_process_chrooted(myself)) {
> +		pr_info("HCRT, mknod denied: dir %lu, mode %d pid %d\n",
> +				d_backing_inode(dir->dentry)->i_ino,
> +				mode, task_pid_nr(myself));
> +		return -EACCES;
> +	}
> +	return rc;
> +}
> +
> +/**
> + * hardchroot_sb_mount - check if mount is allowed
> + * @dev_name contains the name for object being mounted.
> + * @path contains the path for mount point object.
> + * @type contains the filesystem type.
> + * @flags contains the mount flags.
> + * @data contains the filesystem-specific data.
> + *
> + * Return 0 if allowed, -ve on error.
> + */
> +static int hardchroot_sb_mount(const char *dev_name, const struct path
*path,
> +			const char *type, unsigned long flags, void *data) {
> +	int rc = 0;
> +	struct task_struct *myself = current;
> +
> +	pr_info("HCRT, mount: dev %s, inode %lu, flags %lu pid %d\n",
> +			dev_name, d_backing_inode(path->dentry)->i_ino,
> +			flags, task_pid_nr(myself));
> +
> +	if (is_process_chrooted(myself)) {
> +		pr_info("HCRT, mount denied: dev %s, inode %lu, flags %lu,
pid %d\n",
> +				dev_name,
d_backing_inode(path->dentry)->i_ino,
> +				flags, task_pid_nr(myself));
> +		return -EACCES;
> +	}
> +	return rc;
> +}
> +
> +/**
> + * hardchroot_sb_pivotroot - check if pivotroot is allowed
> + * @old_path contains the path for the new location of the
> + * current root (put_old).
> + * @new_path contains the path for the new root (new_root).
> + *
> + * Return 0 if allowed, -ve on error.
> + */
> +static int hardchroot_sb_pivotroot(const struct path *old_path,
> +			const struct path *new_path)
> +{
> +	int rc = 0;
> +	struct task_struct *myself = current;
> +
> +	pr_info("HCRT, pivotroot: old %lu, new %lu, pid %d\n",
> +			d_backing_inode(old_path->dentry)->i_ino,
> +			d_backing_inode(new_path->dentry)->i_ino,
> +			task_pid_nr(myself));
> +
> +	if (is_process_chrooted(myself)) {
> +		pr_info("HCRT, pivotroot denied: old %lu, new %lu, pid
%d\n",
> +				d_backing_inode(old_path->dentry)->i_ino,
> +				d_backing_inode(new_path->dentry)->i_ino,
> +				task_pid_nr(myself));
> +		return -EACCES;
> +	}
> +	return rc;
> +}
> +
> +/**
> + * hardchroot_shm_shmat - check if shmat is allowed
> + * @shp contains the shared memory structure to be modified.
> + * @shmaddr contains the address to attach memory region to.
> + * @shmflg contains the operational flags.
> + *
> + * Return 0 if allowed, -ve on error.
> + */
> +int hardchroot_shm_shmat(struct shmid_kernel *shp, char __user *shmaddr,
> +			int shmflg)
> +{
> +	int rc = 0;
> +	struct task_struct *p;
> +	struct task_struct *myself = current;
> +	u64 st;
> +	time_t ct;
> +
> +	pr_info("HCRT, shmat: shp %d, shmflg %d, pid %d\n",
> +			shp->shm_perm.id, shmflg,
> +			task_pid_nr(myself));
> +
> +	if (likely(!is_process_chrooted(myself)))
> +		return rc;
> +
> +	rcu_read_lock();
> +	read_lock(&tasklist_lock);
> +
> +	p = find_task_by_vpid(shp->shm_cprid);
> +	if (p) {
> +		st = p->start_time;
> +		ct = shp->shm_ctim;
> +		if (time_before_eq((unsigned long)st, (unsigned long)ct)) {
> +			if (is_same_root(myself, p))
> +				goto allow;
> +			else {
> +				read_unlock(&tasklist_lock);
> +				rcu_read_unlock();
> +				pr_info("HCRT, shmat denied: shp %d, shmflg
%d, pid %d\n",
> +						shp->shm_perm.id, shmflg,
> +						task_pid_nr(myself));
> +				return -EACCES;
> +			}
> +		}
> +		/* creator exited, pid reuse, fall through to next check */
> +	}
> +	p = find_task_by_vpid(shp->shm_lprid);
> +	if (p) {
> +		if (unlikely(!is_same_root(myself, p))) {
> +			read_unlock(&tasklist_lock);
> +			rcu_read_unlock();
> +			pr_info("HCRT, shmat denied: shp %d, shmflg %d, pid
%d\n",
> +					shp->shm_perm.id, shmflg,
> +					task_pid_nr(myself));
> +			return -EACCES;
> +		}
> +	}
> +
> +allow:
> +	read_unlock(&tasklist_lock);
> +	rcu_read_unlock();
> +
> +	return rc;
> +
> +
> +}
> +
> +static struct security_hook_list hardchroot_hooks[] = {
> +	LSM_HOOK_INIT(path_chroot, hardchroot_path_chroot),
> +	LSM_HOOK_INIT(path_chmod, hardchroot_path_chmod),
> +	LSM_HOOK_INIT(path_mknod, hardchroot_path_mknod),
> +	LSM_HOOK_INIT(path_fchdir, hardchroot_path_fchdir),
> +	LSM_HOOK_INIT(path_fhandle, hardchroot_path_fhandle),
> +	LSM_HOOK_INIT(sb_mount, hardchroot_sb_mount),
> +	LSM_HOOK_INIT(sb_pivotroot, hardchroot_sb_pivotroot),
> +	LSM_HOOK_INIT(sb_unsharefs, hardchroot_sb_unsharefs),
> +	LSM_HOOK_INIT(task_setnice, hardchroot_task_setnice),
> +	LSM_HOOK_INIT(task_free, hardchroot_task_free),
> +	LSM_HOOK_INIT(task_unshare, hardchroot_task_unshare),
> +	LSM_HOOK_INIT(shm_shmat, hardchroot_shm_shmat), };
> +
> +static inline void hardchroot_init_sysctl(void) { }
> +
> +void __init hardchroot_add_hooks(void) {
> +	pr_info("Hardchroot: Getting stronger.\n");
> +	security_add_hooks(hardchroot_hooks, ARRAY_SIZE(hardchroot_hooks));
> +	hardchroot_init_sysctl();
> +}
> diff --git a/security/security.c b/security/security.c index 
> 95487b9..ff65f06 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -61,6 +61,7 @@ int __init security_init(void)
>  	capability_add_hooks();
>  	yama_add_hooks();
>  	loadpin_add_hooks();
> +	hardchroot_add_hooks();
>  
>  	/*
>  	 * Load all the remaining security modules.
> --
> 1.9.1

Download attachment "smime.p7s" of type "application/pkcs7-signature" (7586 bytes)

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.