|
89 | 89 | #include <linux/kernfs.h> |
90 | 90 | #include <linux/stringhash.h> /* for hashlen_string() */ |
91 | 91 | #include <uapi/linux/mount.h> |
| 92 | +#include <linux/fsnotify.h> |
| 93 | +#include <linux/fanotify.h> |
92 | 94 |
|
93 | 95 | #include "avc.h" |
94 | 96 | #include "objsec.h" |
@@ -3275,6 +3277,50 @@ static int selinux_inode_removexattr(struct dentry *dentry, const char *name) |
3275 | 3277 | return -EACCES; |
3276 | 3278 | } |
3277 | 3279 |
|
| 3280 | +static int selinux_path_notify(const struct path *path, u64 mask, |
| 3281 | + unsigned int obj_type) |
| 3282 | +{ |
| 3283 | + int ret; |
| 3284 | + u32 perm; |
| 3285 | + |
| 3286 | + struct common_audit_data ad; |
| 3287 | + |
| 3288 | + ad.type = LSM_AUDIT_DATA_PATH; |
| 3289 | + ad.u.path = *path; |
| 3290 | + |
| 3291 | + /* |
| 3292 | + * Set permission needed based on the type of mark being set. |
| 3293 | + * Performs an additional check for sb watches. |
| 3294 | + */ |
| 3295 | + switch (obj_type) { |
| 3296 | + case FSNOTIFY_OBJ_TYPE_VFSMOUNT: |
| 3297 | + perm = FILE__WATCH_MOUNT; |
| 3298 | + break; |
| 3299 | + case FSNOTIFY_OBJ_TYPE_SB: |
| 3300 | + perm = FILE__WATCH_SB; |
| 3301 | + ret = superblock_has_perm(current_cred(), path->dentry->d_sb, |
| 3302 | + FILESYSTEM__WATCH, &ad); |
| 3303 | + if (ret) |
| 3304 | + return ret; |
| 3305 | + break; |
| 3306 | + case FSNOTIFY_OBJ_TYPE_INODE: |
| 3307 | + perm = FILE__WATCH; |
| 3308 | + break; |
| 3309 | + default: |
| 3310 | + return -EINVAL; |
| 3311 | + } |
| 3312 | + |
| 3313 | + /* blocking watches require the file:watch_with_perm permission */ |
| 3314 | + if (mask & (ALL_FSNOTIFY_PERM_EVENTS)) |
| 3315 | + perm |= FILE__WATCH_WITH_PERM; |
| 3316 | + |
| 3317 | + /* watches on read-like events need the file:watch_reads permission */ |
| 3318 | + if (mask & (FS_ACCESS | FS_ACCESS_PERM | FS_CLOSE_NOWRITE)) |
| 3319 | + perm |= FILE__WATCH_READS; |
| 3320 | + |
| 3321 | + return path_has_perm(current_cred(), path, perm); |
| 3322 | +} |
| 3323 | + |
3278 | 3324 | /* |
3279 | 3325 | * Copy the inode security context value to the user. |
3280 | 3326 | * |
@@ -3403,7 +3449,7 @@ static int selinux_inode_copy_up_xattr(const char *name) |
3403 | 3449 | static int selinux_kernfs_init_security(struct kernfs_node *kn_dir, |
3404 | 3450 | struct kernfs_node *kn) |
3405 | 3451 | { |
3406 | | - const struct task_security_struct *tsec = current_security(); |
| 3452 | + const struct task_security_struct *tsec = selinux_cred(current_cred()); |
3407 | 3453 | u32 parent_sid, newsid, clen; |
3408 | 3454 | int rc; |
3409 | 3455 | char *context; |
@@ -6818,6 +6864,7 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = { |
6818 | 6864 | LSM_HOOK_INIT(inode_getsecid, selinux_inode_getsecid), |
6819 | 6865 | LSM_HOOK_INIT(inode_copy_up, selinux_inode_copy_up), |
6820 | 6866 | LSM_HOOK_INIT(inode_copy_up_xattr, selinux_inode_copy_up_xattr), |
| 6867 | + LSM_HOOK_INIT(path_notify, selinux_path_notify), |
6821 | 6868 |
|
6822 | 6869 | LSM_HOOK_INIT(kernfs_init_security, selinux_kernfs_init_security), |
6823 | 6870 |
|
|
0 commit comments