mirror of
https://gitlab.com/apparmor/apparmor.git
synced 2025-03-04 08:24:42 +01:00
109 lines
3.6 KiB
Text
109 lines
3.6 KiB
Text
From: Jeff Mahoney <jeffm@suse.com>
|
|
Subject: [PATCH] security: add ->path_permission
|
|
|
|
This patch adds a security_ops->path_permission hook that is identical to
|
|
security_ops->inode_permission except that it is passed a struct path
|
|
instead of a struct inode.
|
|
|
|
LSMs which don't implement it will have their ->inode_permission call
|
|
used instead.
|
|
|
|
Signed-off-by: Jeff Mahoney <jeffm@suse.com>
|
|
---
|
|
|
|
include/linux/security.h | 21 +++++++++++++++++++++
|
|
security/capability.c | 6 ++++++
|
|
security/security.c | 9 +++++++++
|
|
3 files changed, 36 insertions(+)
|
|
|
|
--- a/include/linux/security.h
|
|
+++ b/include/linux/security.h
|
|
@@ -592,6 +592,20 @@ static inline void security_free_mnt_opt
|
|
* file_permission, and recheck access if anything has changed
|
|
* since inode_permission.
|
|
*
|
|
+ * Security hook for path
|
|
+ *
|
|
+ * @path_permission:
|
|
+ * Check permission before accessing a path. This hook is called by the
|
|
+ * existing Linux permission function, so a security module can use it to
|
|
+ * provide additional checking for existing Linux permission checks.
|
|
+ * Notice that this hook is called when a file is opened (as well as many
|
|
+ * other operations), whereas the file_security_ops permission hook is
|
|
+ * called when the actual read/write operations are performed. This
|
|
+ * hook is optional and if absent, inode_permission will be substituted.
|
|
+ * @path contains the path structure to check.
|
|
+ * @mask contains the permission mask.
|
|
+ * Return 0 if permission is granted.
|
|
+
|
|
* Security hooks for task operations.
|
|
*
|
|
* @task_create:
|
|
@@ -1434,6 +1448,7 @@ struct security_operations {
|
|
struct fown_struct *fown, int sig);
|
|
int (*file_receive) (struct file *file);
|
|
int (*dentry_open) (struct file *file);
|
|
+ int (*path_permission) (struct path *path, int mask);
|
|
|
|
int (*task_create) (unsigned long clone_flags);
|
|
int (*task_alloc_security) (struct task_struct *p);
|
|
@@ -1708,6 +1723,7 @@ int security_file_send_sigiotask(struct
|
|
struct fown_struct *fown, int sig);
|
|
int security_file_receive(struct file *file);
|
|
int security_dentry_open(struct file *file);
|
|
+int security_path_permission(struct path *path, int mask);
|
|
int security_task_create(unsigned long clone_flags);
|
|
int security_task_alloc(struct task_struct *p);
|
|
void security_task_free(struct task_struct *p);
|
|
@@ -2240,6 +2256,11 @@ static inline int security_dentry_open(s
|
|
{
|
|
return 0;
|
|
}
|
|
+
|
|
+static inline int security_path_permission(struct path *path, int mask)
|
|
+{
|
|
+ return 0;
|
|
+}
|
|
|
|
static inline int security_task_create(unsigned long clone_flags)
|
|
{
|
|
--- a/security/capability.c
|
|
+++ b/security/capability.c
|
|
@@ -343,6 +343,11 @@ static int cap_dentry_open(struct file *
|
|
return 0;
|
|
}
|
|
|
|
+static int cap_path_permission(struct path *path, int mask)
|
|
+{
|
|
+ return security_inode_permission(path->dentry->d_inode, mask);
|
|
+}
|
|
+
|
|
static int cap_task_create(unsigned long clone_flags)
|
|
{
|
|
return 0;
|
|
@@ -897,6 +902,7 @@ void security_fixup_ops(struct security_
|
|
set_to_cap_if_null(ops, file_send_sigiotask);
|
|
set_to_cap_if_null(ops, file_receive);
|
|
set_to_cap_if_null(ops, dentry_open);
|
|
+ set_to_cap_if_null(ops, path_permission);
|
|
set_to_cap_if_null(ops, task_create);
|
|
set_to_cap_if_null(ops, task_alloc_security);
|
|
set_to_cap_if_null(ops, task_free_security);
|
|
--- a/security/security.c
|
|
+++ b/security/security.c
|
|
@@ -615,6 +615,15 @@ int security_dentry_open(struct file *fi
|
|
return security_ops->dentry_open(file);
|
|
}
|
|
|
|
+int security_path_permission(struct path *path, int mask)
|
|
+{
|
|
+ struct inode *inode = path->dentry->d_inode;
|
|
+ if (unlikely(IS_PRIVATE(inode)))
|
|
+ return 0;
|
|
+
|
|
+ return security_ops->path_permission(path, mask);
|
|
+}
|
|
+
|
|
int security_task_create(unsigned long clone_flags)
|
|
{
|
|
return security_ops->task_create(clone_flags);
|