]>
Commit | Line | Data |
---|---|---|
1 | From: Jeff Mahoney <jeffm@suse.com> | |
2 | Subject: [PATCH] security: add ->path_permission | |
3 | ||
4 | This patch adds a security_ops->path_permission hook that is identical to | |
5 | security_ops->inode_permission except that it is passed a struct path | |
6 | instead of a struct inode. | |
7 | ||
8 | LSMs which don't implement it will have their ->inode_permission call | |
9 | used instead. | |
10 | ||
11 | Signed-off-by: Jeff Mahoney <jeffm@suse.com> | |
12 | --- | |
13 | ||
14 | include/linux/security.h | 21 +++++++++++++++++++++ | |
15 | security/capability.c | 6 ++++++ | |
16 | security/security.c | 9 +++++++++ | |
17 | 3 files changed, 36 insertions(+) | |
18 | ||
19 | --- a/include/linux/security.h | |
20 | +++ b/include/linux/security.h | |
21 | @@ -592,6 +592,20 @@ static inline void security_free_mnt_opt | |
22 | * file_permission, and recheck access if anything has changed | |
23 | * since inode_permission. | |
24 | * | |
25 | + * Security hook for path | |
26 | + * | |
27 | + * @path_permission: | |
28 | + * Check permission before accessing a path. This hook is called by the | |
29 | + * existing Linux permission function, so a security module can use it to | |
30 | + * provide additional checking for existing Linux permission checks. | |
31 | + * Notice that this hook is called when a file is opened (as well as many | |
32 | + * other operations), whereas the file_security_ops permission hook is | |
33 | + * called when the actual read/write operations are performed. This | |
34 | + * hook is optional and if absent, inode_permission will be substituted. | |
35 | + * @path contains the path structure to check. | |
36 | + * @mask contains the permission mask. | |
37 | + * Return 0 if permission is granted. | |
38 | + | |
39 | * Security hooks for task operations. | |
40 | * | |
41 | * @task_create: | |
42 | @@ -1434,6 +1448,7 @@ struct security_operations { | |
43 | struct fown_struct *fown, int sig); | |
44 | int (*file_receive) (struct file *file); | |
45 | int (*dentry_open) (struct file *file); | |
46 | + int (*path_permission) (struct path *path, int mask); | |
47 | ||
48 | int (*task_create) (unsigned long clone_flags); | |
49 | int (*task_alloc_security) (struct task_struct *p); | |
50 | @@ -1708,6 +1723,7 @@ int security_file_send_sigiotask(struct | |
51 | struct fown_struct *fown, int sig); | |
52 | int security_file_receive(struct file *file); | |
53 | int security_dentry_open(struct file *file); | |
54 | +int security_path_permission(struct path *path, int mask); | |
55 | int security_task_create(unsigned long clone_flags); | |
56 | int security_task_alloc(struct task_struct *p); | |
57 | void security_task_free(struct task_struct *p); | |
58 | @@ -2240,6 +2256,11 @@ static inline int security_dentry_open(s | |
59 | { | |
60 | return 0; | |
61 | } | |
62 | + | |
63 | +static inline int security_path_permission(struct path *path, int mask) | |
64 | +{ | |
65 | + return 0; | |
66 | +} | |
67 | ||
68 | static inline int security_task_create(unsigned long clone_flags) | |
69 | { | |
70 | --- a/security/capability.c | |
71 | +++ b/security/capability.c | |
72 | @@ -343,6 +343,11 @@ static int cap_dentry_open(struct file * | |
73 | return 0; | |
74 | } | |
75 | ||
76 | +static int cap_path_permission(struct path *path, int mask) | |
77 | +{ | |
78 | + return security_inode_permission(path->dentry->d_inode, mask); | |
79 | +} | |
80 | + | |
81 | static int cap_task_create(unsigned long clone_flags) | |
82 | { | |
83 | return 0; | |
84 | @@ -897,6 +902,7 @@ void security_fixup_ops(struct security_ | |
85 | set_to_cap_if_null(ops, file_send_sigiotask); | |
86 | set_to_cap_if_null(ops, file_receive); | |
87 | set_to_cap_if_null(ops, dentry_open); | |
88 | + set_to_cap_if_null(ops, path_permission); | |
89 | set_to_cap_if_null(ops, task_create); | |
90 | set_to_cap_if_null(ops, task_alloc_security); | |
91 | set_to_cap_if_null(ops, task_free_security); | |
92 | --- a/security/security.c | |
93 | +++ b/security/security.c | |
94 | @@ -615,6 +615,15 @@ int security_dentry_open(struct file *fi | |
95 | return security_ops->dentry_open(file); | |
96 | } | |
97 | ||
98 | +int security_path_permission(struct path *path, int mask) | |
99 | +{ | |
100 | + struct inode *inode = path->dentry->d_inode; | |
101 | + if (unlikely(IS_PRIVATE(inode))) | |
102 | + return 0; | |
103 | + | |
104 | + return security_ops->path_permission(path, mask); | |
105 | +} | |
106 | + | |
107 | int security_task_create(unsigned long clone_flags) | |
108 | { | |
109 | return security_ops->task_create(clone_flags); |