|
|
Message-Id: <1469777680-3687-2-git-send-email-elena.reshetova@intel.com>
Date: Fri, 29 Jul 2016 10:34:36 +0300
From: Elena Reshetova <elena.reshetova@...el.com>
To: kernel-hardening@...ts.openwall.com
Cc: linux-security-module@...r.kernel.org,
keescook@...omium.org,
spender@...ecurity.net,
jmorris@...ei.org,
casey.schaufler@...el.com,
michael.leibowitz@...el.com,
william.c.roberts@...el.com,
Elena Reshetova <elena.reshetova@...el.com>
Subject: [RFC] [PATCH 1/5] path_fchdir and path_fhandle LSM hooks
This introduces two new LSM hooks operating on paths.
- security_path_fchdir() checks for permission on
changing working directory. It can be used by
LSMs concerned on fchdir system call
- security_path_fhandle() checks for permission
before converting file handle to path. It can be
used by LSMs concerned with file handle transfers
Both hooks are under CONFIG_SECURITY_PATH.
Signed-off-by: Elena Reshetova <elena.reshetova@...el.com>
---
fs/fhandle.c | 5 +++++
fs/open.c | 3 +++
include/linux/lsm_hooks.h | 12 ++++++++++++
include/linux/security.h | 13 +++++++++++++
security/security.c | 11 +++++++++++
5 files changed, 44 insertions(+)
diff --git a/fs/fhandle.c b/fs/fhandle.c
index ca3c3dd..6e8aba5 100644
--- a/fs/fhandle.c
+++ b/fs/fhandle.c
@@ -8,6 +8,7 @@
#include <linux/fs_struct.h>
#include <linux/fsnotify.h>
#include <linux/personality.h>
+#include <linux/security.h>
#include <asm/uaccess.h>
#include "internal.h"
#include "mount.h"
@@ -179,6 +180,10 @@ static int handle_to_path(int mountdirfd, struct file_handle __user *ufh,
retval = -EPERM;
goto out_err;
}
+ retval = security_path_fhandle(path);
+ if (retval)
+ goto out_err;
+
if (copy_from_user(&f_handle, ufh, sizeof(struct file_handle))) {
retval = -EFAULT;
goto out_err;
diff --git a/fs/open.c b/fs/open.c
index 93ae3cd..9c260d4 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -458,6 +458,9 @@ SYSCALL_DEFINE1(fchdir, unsigned int, fd)
goto out_putf;
error = inode_permission(inode, MAY_EXEC | MAY_CHDIR);
+ if (error)
+ goto out_putf;
+ error = security_path_fchdir(&f.file->f_path);
if (!error)
set_fs_pwd(current->fs, &f.file->f_path);
out_putf:
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 7ae3976..25164b6 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -308,6 +308,14 @@
* Check for permission to change root directory.
* @path contains the path structure.
* Return 0 if permission is granted.
+ * @path_fchdir:
+ * Check for permission to change working directory.
+ * @path contains the path structure.
+ * Return 0 if permission is granted.
+ * @path_fhandle:
+ * Check for permission to convert handle to path.
+ * @path contains the path structure.
+ * Return 0 if permission is granted.
* @inode_readlink:
* Check the permission to read the symbolic link.
* @dentry contains the dentry structure for the file link.
@@ -1378,6 +1386,8 @@ union security_list_options {
int (*path_chmod)(const struct path *path, umode_t mode);
int (*path_chown)(const struct path *path, kuid_t uid, kgid_t gid);
int (*path_chroot)(const struct path *path);
+ int (*path_fchdir)(const struct path *path);
+ int (*path_fhandle)(const struct path *path);
#endif
int (*inode_alloc_security)(struct inode *inode);
@@ -1668,6 +1678,8 @@ struct security_hook_heads {
struct list_head path_chmod;
struct list_head path_chown;
struct list_head path_chroot;
+ struct list_head path_fchdir;
+ struct list_head path_fhandle;
#endif
struct list_head inode_alloc_security;
struct list_head inode_free_security;
diff --git a/include/linux/security.h b/include/linux/security.h
index 14df373..6745c06 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -1472,6 +1472,9 @@ int security_path_rename(const struct path *old_dir, struct dentry *old_dentry,
int security_path_chmod(const struct path *path, umode_t mode);
int security_path_chown(const struct path *path, kuid_t uid, kgid_t gid);
int security_path_chroot(const struct path *path);
+int security_path_fchdir(const struct path *path);
+int security_path_fhandle(const struct path *path);
+
#else /* CONFIG_SECURITY_PATH */
static inline int security_path_unlink(const struct path *dir, struct dentry *dentry)
{
@@ -1536,6 +1539,16 @@ static inline int security_path_chroot(const struct path *path)
{
return 0;
}
+
+static inline int security_path_fchdir(const struct path *path)
+{
+ return 0;
+}
+
+static inline int security_path_fhandle(const struct path *path)
+{
+ return 0;
+}
#endif /* CONFIG_SECURITY_PATH */
#ifdef CONFIG_KEYS
diff --git a/security/security.c b/security/security.c
index 7095693..cd82276 100644
--- a/security/security.c
+++ b/security/security.c
@@ -504,6 +504,15 @@ int security_path_chroot(const struct path *path)
{
return call_int_hook(path_chroot, 0, path);
}
+
+int security_path_fchdir(const struct path *path)
+{
+ return call_int_hook(path_fchdir, 0, path);
+}
+int security_path_fhandle(const struct path *path)
+{
+ return call_int_hook(path_fhandle, 0, path);
+}
#endif
int security_inode_create(struct inode *dir, struct dentry *dentry, umode_t mode)
@@ -1615,6 +1624,8 @@ struct security_hook_heads security_hook_heads = {
.path_chmod = LIST_HEAD_INIT(security_hook_heads.path_chmod),
.path_chown = LIST_HEAD_INIT(security_hook_heads.path_chown),
.path_chroot = LIST_HEAD_INIT(security_hook_heads.path_chroot),
+ .path_fchdir = LIST_HEAD_INIT(security_hook_heads.path_fchdir),
+ .path_fhandle = LIST_HEAD_INIT(security_hook_heads.path_fhandle),
#endif
.inode_alloc_security =
LIST_HEAD_INIT(security_hook_heads.inode_alloc_security),
--
1.9.1
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.