diff options
Diffstat (limited to 'security/landlock/fs.c')
| -rw-r--r-- | security/landlock/fs.c | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/security/landlock/fs.c b/security/landlock/fs.c index c1ecfe239032..664962a416d7 100644 --- a/security/landlock/fs.c +++ b/security/landlock/fs.c @@ -1901,6 +1901,14 @@ static bool control_current_fowner(struct fown_struct *const fown) lockdep_assert_held(&fown->lock); /* + * A process-group or session owner (PIDTYPE_PGID/PIDTYPE_SID) fans the + * signal out to every member at delivery time, so record the domain and + * let hook_file_send_sigiotask() check the live scope per recipient. + */ + if (fown->pid_type != PIDTYPE_PID && fown->pid_type != PIDTYPE_TGID) + return true; + + /* * Some callers (e.g. fcntl_dirnotify) may not be in an RCU read-side * critical section. */ @@ -1916,6 +1924,7 @@ static void hook_file_set_fowner(struct file *file) { struct landlock_ruleset *prev_dom; struct landlock_cred_security fown_subject = {}; + struct pid *prev_tg, *fown_tg = NULL; size_t fown_layer = 0; if (control_current_fowner(file_f_owner(file))) { @@ -1928,21 +1937,26 @@ static void hook_file_set_fowner(struct file *file) if (new_subject) { landlock_get_ruleset(new_subject->domain); fown_subject = *new_subject; + fown_tg = get_pid(task_tgid(current)); } } prev_dom = landlock_file(file)->fown_subject.domain; + prev_tg = landlock_file(file)->fown_tg; landlock_file(file)->fown_subject = fown_subject; + landlock_file(file)->fown_tg = fown_tg; #ifdef CONFIG_AUDIT landlock_file(file)->fown_layer = fown_layer; #endif /* CONFIG_AUDIT*/ /* May be called in an RCU read-side critical section. */ landlock_put_ruleset_deferred(prev_dom); + put_pid(prev_tg); } static void hook_file_free_security(struct file *file) { + put_pid(landlock_file(file)->fown_tg); landlock_put_ruleset_deferred(landlock_file(file)->fown_subject.domain); } |
