Message ID | 894cc57c-d298-4b60-a67d-42c1a92d0b92@I-love.SAKURA.ne.jp (mailing list archive) |
---|---|
State | Under Review |
Delegated to: | Paul Moore |
Headers | show |
Series | fs/exec: remove current->in_execve flag | expand |
On Feb 6, 2024 Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> wrote: > > A regression caused by commit 978ffcbf00d8 ("execve: open the executable > file before doing anything else") has been fixed by commit 4759ff71f23e > ("exec: Check __FMODE_EXEC instead of in_execve for LSMs") and commit > 3eab830189d9 ("uselib: remove use of __FMODE_EXEC"). While fixing this > regression, Linus commented that we want to remove current->in_execve flag. > > The current->in_execve flag was introduced by commit f9ce1f1cda8b ("Add > in_execve flag into task_struct.") when TOMOYO LSM was merged, and the > reason was explained in commit f7433243770c ("LSM adapter functions."). > > In short, TOMOYO's design is not compatible with COW credential model > introduced in Linux 2.6.29, and the current->in_execve flag was added for > emulating security_bprm_free() hook which has been removed by introduction > of COW credential model. If you wanted to mention the relevant commit where security_bprm_free() was removed, it was a6f76f23d297 ("CRED: Make execve() take advantage of copy-on-write credentials"). > security_task_alloc()/security_task_free() hooks have been removed by > commit f1752eec6145 ("CRED: Detach the credentials from task_struct"), > and these hooks have been revived by commit 1a2a4d06e1e9 ("security: > create task_free security callback") and commit e4e55b47ed9a ("LSM: Revive > security_task_alloc() hook and per "struct task_struct" security blob."). > > But security_bprm_free() hook did not revive until now. Now that Linus > wants TOMOYO to stop carrying state across two independent execve() calls, > and TOMOYO can stop carrying state if a hook for restoring previous state > upon failed execve() call were provided, this patch revives the hook. > > Since security_bprm_committing_creds() and security_bprm_committed_creds() > hooks are called when an execve() request succeeded, we don't need to call > security_bprm_free() hook when an execve() request succeeded. Therefore, > this patch adds security_execve_abort() hook which is called only when an > execve() request failed after successful prepare_bprm_creds() call. > > Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> > Acked-by: Serge E. Hallyn <serge@hallyn.com> > --- > fs/exec.c | 1 + > include/linux/lsm_hook_defs.h | 1 + > include/linux/security.h | 5 +++++ > security/security.c | 11 +++++++++++ > 4 files changed, 18 insertions(+) > > diff --git a/fs/exec.c b/fs/exec.c > index af4fbb61cd53..d6d35a06fd08 100644 > --- a/fs/exec.c > +++ b/fs/exec.c > @@ -1521,6 +1521,7 @@ static void free_bprm(struct linux_binprm *bprm) > if (bprm->cred) { > mutex_unlock(¤t->signal->cred_guard_mutex); > abort_creds(bprm->cred); > + security_execve_abort(); > } > do_close_execat(bprm->file); > if (bprm->executable) > diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h > index 76458b6d53da..fd100ab71a33 100644 > --- a/include/linux/lsm_hook_defs.h > +++ b/include/linux/lsm_hook_defs.h > @@ -54,6 +54,7 @@ LSM_HOOK(int, 0, bprm_creds_from_file, struct linux_binprm *bprm, const struct f > LSM_HOOK(int, 0, bprm_check_security, struct linux_binprm *bprm) > LSM_HOOK(void, LSM_RET_VOID, bprm_committing_creds, const struct linux_binprm *bprm) > LSM_HOOK(void, LSM_RET_VOID, bprm_committed_creds, const struct linux_binprm *bprm) > +LSM_HOOK(void, LSM_RET_VOID, execve_abort, void) > LSM_HOOK(int, 0, fs_context_submount, struct fs_context *fc, struct super_block *reference) > LSM_HOOK(int, 0, fs_context_dup, struct fs_context *fc, > struct fs_context *src_sc) > diff --git a/include/linux/security.h b/include/linux/security.h > index d0eb20f90b26..31532b30c4f0 100644 > --- a/include/linux/security.h > +++ b/include/linux/security.h > @@ -299,6 +299,7 @@ int security_bprm_creds_from_file(struct linux_binprm *bprm, const struct file * > int security_bprm_check(struct linux_binprm *bprm); > void security_bprm_committing_creds(const struct linux_binprm *bprm); > void security_bprm_committed_creds(const struct linux_binprm *bprm); > +void security_execve_abort(void); > int security_fs_context_submount(struct fs_context *fc, struct super_block *reference); > int security_fs_context_dup(struct fs_context *fc, struct fs_context *src_fc); > int security_fs_context_parse_param(struct fs_context *fc, struct fs_parameter *param); > @@ -648,6 +649,10 @@ static inline void security_bprm_committed_creds(const struct linux_binprm *bprm > { > } > > +static inline void security_execve_abort(void) > +{ > +} > + > static inline int security_fs_context_submount(struct fs_context *fc, > struct super_block *reference) > { > diff --git a/security/security.c b/security/security.c > index 3aaad75c9ce8..10adc4d3c5e0 100644 > --- a/security/security.c > +++ b/security/security.c > @@ -1223,6 +1223,17 @@ void security_bprm_committed_creds(const struct linux_binprm *bprm) > call_void_hook(bprm_committed_creds, bprm); > } > > +/** > + * security_execve_abort() - Notify that exec() has failed > + * > + * This hook is for undoing changes which cannot be discarded by > + * abort_creds(). > + */ > +void security_execve_abort(void) > +{ > + call_void_hook(execve_abort); > +} I don't have a problem with reinstating something like security_bprm_free(), but I don't like the name security_execve_abort(), especially given that it is being called from alloc_bprm() as well as all of the execve code. At the risk of bikeshedding this, I'd be much happier if this hook were renamed to security_bprm_free() and the hook's description explained that this hook is called when a linux_bprm instance is being destroyed, after the bprm creds have been released, and is intended to cleanup any internal LSM state associated with the linux_bprm instance. Are you okay with that? -- paul-moore.com
On 2024/02/07 9:00, Paul Moore wrote: >> @@ -1223,6 +1223,17 @@ void security_bprm_committed_creds(const struct linux_binprm *bprm) >> call_void_hook(bprm_committed_creds, bprm); >> } >> >> +/** >> + * security_execve_abort() - Notify that exec() has failed >> + * >> + * This hook is for undoing changes which cannot be discarded by >> + * abort_creds(). >> + */ >> +void security_execve_abort(void) >> +{ >> + call_void_hook(execve_abort); >> +} > > I don't have a problem with reinstating something like > security_bprm_free(), but I don't like the name security_execve_abort(), > especially given that it is being called from alloc_bprm() as well as > all of the execve code. At the risk of bikeshedding this, I'd be much > happier if this hook were renamed to security_bprm_free() and the > hook's description explained that this hook is called when a linux_bprm > instance is being destroyed, after the bprm creds have been released, > and is intended to cleanup any internal LSM state associated with the > linux_bprm instance. > > Are you okay with that? Hmm, that will bring us back to v1 of this series. v3 was based on Eric W. Biederman's suggestion If you aren't going to change your design your new hook should be: security_execve_revert(current); Or maybe: security_execve_abort(current); At least then it is based upon the reality that you plan to revert changes to current->security. Saying anything about creds or bprm when you don't touch them, makes no sense at all. Causing people to completely misunderstand what is going on, and making it more likely they will change the code in ways that will break TOMOYO. at https://lkml.kernel.org/r/8734ug9fbt.fsf@email.froward.int.ebiederm.org .
On Wed, Feb 07, 2024 at 08:10:55PM +0900, Tetsuo Handa wrote: > On 2024/02/07 9:00, Paul Moore wrote: > >> @@ -1223,6 +1223,17 @@ void security_bprm_committed_creds(const struct linux_binprm *bprm) > >> call_void_hook(bprm_committed_creds, bprm); > >> } > >> > >> +/** > >> + * security_execve_abort() - Notify that exec() has failed > >> + * > >> + * This hook is for undoing changes which cannot be discarded by > >> + * abort_creds(). > >> + */ > >> +void security_execve_abort(void) > >> +{ > >> + call_void_hook(execve_abort); > >> +} > > > > I don't have a problem with reinstating something like > > security_bprm_free(), but I don't like the name security_execve_abort(), > > especially given that it is being called from alloc_bprm() as well as > > all of the execve code. At the risk of bikeshedding this, I'd be much > > happier if this hook were renamed to security_bprm_free() and the > > hook's description explained that this hook is called when a linux_bprm > > instance is being destroyed, after the bprm creds have been released, > > and is intended to cleanup any internal LSM state associated with the > > linux_bprm instance. > > > > Are you okay with that? > > Hmm, that will bring us back to v1 of this series. > > v3 was based on Eric W. Biederman's suggestion > > If you aren't going to change your design your new hook should be: > security_execve_revert(current); > Or maybe: > security_execve_abort(current); > > At least then it is based upon the reality that you plan to revert > changes to current->security. Saying anything about creds or bprm when > you don't touch them, makes no sense at all. Causing people to > completely misunderstand what is going on, and making it more likely > they will change the code in ways that will break TOMOYO. > > at https://lkml.kernel.org/r/8734ug9fbt.fsf@email.froward.int.ebiederm.org . Yeah, I'd agree with Eric on this: it's not about bprm freeing, it's catching the execve failure. I think the name is accurate -- it mirrors the abort_creds() call. -Kees
On Wed, Feb 7, 2024 at 9:34 AM Kees Cook <keescook@chromium.org> wrote: > On Wed, Feb 07, 2024 at 08:10:55PM +0900, Tetsuo Handa wrote: > > On 2024/02/07 9:00, Paul Moore wrote: > > >> @@ -1223,6 +1223,17 @@ void security_bprm_committed_creds(const struct linux_binprm *bprm) > > >> call_void_hook(bprm_committed_creds, bprm); > > >> } > > >> > > >> +/** > > >> + * security_execve_abort() - Notify that exec() has failed > > >> + * > > >> + * This hook is for undoing changes which cannot be discarded by > > >> + * abort_creds(). > > >> + */ > > >> +void security_execve_abort(void) > > >> +{ > > >> + call_void_hook(execve_abort); > > >> +} > > > > > > I don't have a problem with reinstating something like > > > security_bprm_free(), but I don't like the name security_execve_abort(), > > > especially given that it is being called from alloc_bprm() as well as > > > all of the execve code. At the risk of bikeshedding this, I'd be much > > > happier if this hook were renamed to security_bprm_free() and the > > > hook's description explained that this hook is called when a linux_bprm > > > instance is being destroyed, after the bprm creds have been released, > > > and is intended to cleanup any internal LSM state associated with the > > > linux_bprm instance. > > > > > > Are you okay with that? > > > > Hmm, that will bring us back to v1 of this series. > > > > v3 was based on Eric W. Biederman's suggestion > > > > If you aren't going to change your design your new hook should be: > > security_execve_revert(current); > > Or maybe: > > security_execve_abort(current); > > > > At least then it is based upon the reality that you plan to revert > > changes to current->security. Saying anything about creds or bprm when > > you don't touch them, makes no sense at all. Causing people to > > completely misunderstand what is going on, and making it more likely > > they will change the code in ways that will break TOMOYO. > > > > at https://lkml.kernel.org/r/8734ug9fbt.fsf@email.froward.int.ebiederm.org . > > Yeah, I'd agree with Eric on this: it's not about bprm freeing, it's > catching the execve failure. I think the name is accurate -- it mirrors > the abort_creds() call. I'm sorry, but I would still much rather prefer security_bprm_free() both to reflect the nature of the caller as well as to abstract away a particular use case; this is also why I suggested a different hook description for the function header block. If you really want this to be focused on reverting the execvc changes (I do agree with Eric about "revert" over "abort") then please move this hook out of free_bprm() and into do_execveat_common() and kernel_execve(). To quickly summarize, there are two paths forward that I believe are acceptable from a LSM perspective, pick either one and send me an updated patchset. 1. Rename the hook to security_bprm_free() and update the LSM hook description as I mentioned earlier in this thread. 2. Rename the hook to security_execve_revert(), move it into the execve related functions, and update the LSM hook description to reflect that this hook is for reverting execve related changes to the current task's internal LSM state beyond what is possible via the credential hooks.
On Wed, Feb 7, 2024 at 11:01 AM Paul Moore <paul@paul-moore.com> wrote: > On Wed, Feb 7, 2024 at 9:34 AM Kees Cook <keescook@chromium.org> wrote: > > On Wed, Feb 07, 2024 at 08:10:55PM +0900, Tetsuo Handa wrote: > > > On 2024/02/07 9:00, Paul Moore wrote: > > > >> @@ -1223,6 +1223,17 @@ void security_bprm_committed_creds(const struct linux_binprm *bprm) > > > >> call_void_hook(bprm_committed_creds, bprm); > > > >> } > > > >> > > > >> +/** > > > >> + * security_execve_abort() - Notify that exec() has failed > > > >> + * > > > >> + * This hook is for undoing changes which cannot be discarded by > > > >> + * abort_creds(). > > > >> + */ > > > >> +void security_execve_abort(void) > > > >> +{ > > > >> + call_void_hook(execve_abort); > > > >> +} > > > > > > > > I don't have a problem with reinstating something like > > > > security_bprm_free(), but I don't like the name security_execve_abort(), > > > > especially given that it is being called from alloc_bprm() as well as > > > > all of the execve code. At the risk of bikeshedding this, I'd be much > > > > happier if this hook were renamed to security_bprm_free() and the > > > > hook's description explained that this hook is called when a linux_bprm > > > > instance is being destroyed, after the bprm creds have been released, > > > > and is intended to cleanup any internal LSM state associated with the > > > > linux_bprm instance. > > > > > > > > Are you okay with that? > > > > > > Hmm, that will bring us back to v1 of this series. > > > > > > v3 was based on Eric W. Biederman's suggestion > > > > > > If you aren't going to change your design your new hook should be: > > > security_execve_revert(current); > > > Or maybe: > > > security_execve_abort(current); > > > > > > At least then it is based upon the reality that you plan to revert > > > changes to current->security. Saying anything about creds or bprm when > > > you don't touch them, makes no sense at all. Causing people to > > > completely misunderstand what is going on, and making it more likely > > > they will change the code in ways that will break TOMOYO. > > > > > > at https://lkml.kernel.org/r/8734ug9fbt.fsf@email.froward.int.ebiederm.org . > > > > Yeah, I'd agree with Eric on this: it's not about bprm freeing, it's > > catching the execve failure. I think the name is accurate -- it mirrors > > the abort_creds() call. > > I'm sorry, but I would still much rather prefer security_bprm_free() > both to reflect the nature of the caller as well as to abstract away a > particular use case; this is also why I suggested a different hook > description for the function header block. > > If you really want this to be focused on reverting the execvc changes > (I do agree with Eric about "revert" over "abort") then please move > this hook out of free_bprm() and into do_execveat_common() and > kernel_execve(). > > To quickly summarize, there are two paths forward that I believe are > acceptable from a LSM perspective, pick either one and send me an > updated patchset. > > 1. Rename the hook to security_bprm_free() and update the LSM hook > description as I mentioned earlier in this thread. > > 2. Rename the hook to security_execve_revert(), move it into the > execve related functions, and update the LSM hook description to > reflect that this hook is for reverting execve related changes to the > current task's internal LSM state beyond what is possible via the > credential hooks. Hi Tetsuo, I just wanted to check on this and see if you've been able to make any progress?
On 2024/02/15 6:46, Paul Moore wrote: >> To quickly summarize, there are two paths forward that I believe are >> acceptable from a LSM perspective, pick either one and send me an >> updated patchset. >> >> 1. Rename the hook to security_bprm_free() and update the LSM hook >> description as I mentioned earlier in this thread. >> >> 2. Rename the hook to security_execve_revert(), move it into the >> execve related functions, and update the LSM hook description to >> reflect that this hook is for reverting execve related changes to the >> current task's internal LSM state beyond what is possible via the >> credential hooks. > > Hi Tetsuo, I just wanted to check on this and see if you've been able > to make any progress? > I'm fine with either approach. Just worrying that someone doesn't like overhead of unconditionally calling security_bprm_free() hook. If everyone is fine with below one, I'll post v4 patchset. fs/exec.c | 1 + include/linux/lsm_hook_defs.h | 1 + include/linux/security.h | 5 +++++ security/security.c | 12 ++++++++++++ 4 files changed, 19 insertions(+) diff --git a/fs/exec.c b/fs/exec.c index af4fbb61cd53..cbee988445c6 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -1530,6 +1530,7 @@ static void free_bprm(struct linux_binprm *bprm) kfree(bprm->interp); kfree(bprm->fdpath); kfree(bprm); + security_bprm_free(); } static struct linux_binprm *alloc_bprm(int fd, struct filename *filename, int flags) diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h index 76458b6d53da..0ef298231de2 100644 --- a/include/linux/lsm_hook_defs.h +++ b/include/linux/lsm_hook_defs.h @@ -54,6 +54,7 @@ LSM_HOOK(int, 0, bprm_creds_from_file, struct linux_binprm *bprm, const struct f LSM_HOOK(int, 0, bprm_check_security, struct linux_binprm *bprm) LSM_HOOK(void, LSM_RET_VOID, bprm_committing_creds, const struct linux_binprm *bprm) LSM_HOOK(void, LSM_RET_VOID, bprm_committed_creds, const struct linux_binprm *bprm) +LSM_HOOK(void, LSM_RET_VOID, bprm_free, void) LSM_HOOK(int, 0, fs_context_submount, struct fs_context *fc, struct super_block *reference) LSM_HOOK(int, 0, fs_context_dup, struct fs_context *fc, struct fs_context *src_sc) diff --git a/include/linux/security.h b/include/linux/security.h index d0eb20f90b26..b12d20071a8f 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -299,6 +299,7 @@ int security_bprm_creds_from_file(struct linux_binprm *bprm, const struct file * int security_bprm_check(struct linux_binprm *bprm); void security_bprm_committing_creds(const struct linux_binprm *bprm); void security_bprm_committed_creds(const struct linux_binprm *bprm); +void security_bprm_free(void); int security_fs_context_submount(struct fs_context *fc, struct super_block *reference); int security_fs_context_dup(struct fs_context *fc, struct fs_context *src_fc); int security_fs_context_parse_param(struct fs_context *fc, struct fs_parameter *param); @@ -648,6 +649,10 @@ static inline void security_bprm_committed_creds(const struct linux_binprm *bprm { } +static inline void security_bprm_free(void) +{ +} + static inline int security_fs_context_submount(struct fs_context *fc, struct super_block *reference) { diff --git a/security/security.c b/security/security.c index 3aaad75c9ce8..ba2f480b2bdb 100644 --- a/security/security.c +++ b/security/security.c @@ -1223,6 +1223,18 @@ void security_bprm_committed_creds(const struct linux_binprm *bprm) call_void_hook(bprm_committed_creds, bprm); } +/** + * security_bprm_free() - Notify of completion of an exec() + * + * This hook is called when a linux_bprm instance is being destroyed, after + * the bprm creds have been released, and is intended to cleanup any internal + * LSM state associated with the linux_bprm instance. + */ +void security_bprm_free(void) +{ + call_void_hook(bprm_free); +} + /** * security_fs_context_submount() - Initialise fc->security * @fc: new filesystem context
On Thu, Feb 15, 2024 at 9:33 AM Tetsuo Handa <penguin-kernel@i-love.sakura.ne.jp> wrote: > On 2024/02/15 6:46, Paul Moore wrote: > >> To quickly summarize, there are two paths forward that I believe are > >> acceptable from a LSM perspective, pick either one and send me an > >> updated patchset. > >> > >> 1. Rename the hook to security_bprm_free() and update the LSM hook > >> description as I mentioned earlier in this thread. > >> > >> 2. Rename the hook to security_execve_revert(), move it into the > >> execve related functions, and update the LSM hook description to > >> reflect that this hook is for reverting execve related changes to the > >> current task's internal LSM state beyond what is possible via the > >> credential hooks. > > > > Hi Tetsuo, I just wanted to check on this and see if you've been able > > to make any progress? > > > > I'm fine with either approach. Just worrying that someone doesn't like > overhead of unconditionally calling security_bprm_free() hook. > If everyone is fine with below one, I'll post v4 patchset. My guess is that based on the previous comments people are going to prefer option #2 above, but we'll see what everyone says. I did have one comment, below ... > fs/exec.c | 1 + > include/linux/lsm_hook_defs.h | 1 + > include/linux/security.h | 5 +++++ > security/security.c | 12 ++++++++++++ > 4 files changed, 19 insertions(+) ... > diff --git a/security/security.c b/security/security.c > index 3aaad75c9ce8..ba2f480b2bdb 100644 > --- a/security/security.c > +++ b/security/security.c > @@ -1223,6 +1223,18 @@ void security_bprm_committed_creds(const struct linux_binprm *bprm) > call_void_hook(bprm_committed_creds, bprm); > } > > +/** > + * security_bprm_free() - Notify of completion of an exec() The short summary above doesn't match the summary below. If we stick with the security_bprm_free() approach please change "Notify of completion of an exec()" to "Notify LSMs of a bprm free event" or similar. > + * This hook is called when a linux_bprm instance is being destroyed, after > + * the bprm creds have been released, and is intended to cleanup any internal > + * LSM state associated with the linux_bprm instance. > + */ > +void security_bprm_free(void) > +{ > + call_void_hook(bprm_free); > +} > + > /** > * security_fs_context_submount() - Initialise fc->security > * @fc: new filesystem context >
On Thu, Feb 15, 2024 at 11:33:32PM +0900, Tetsuo Handa wrote: > On 2024/02/15 6:46, Paul Moore wrote: > >> To quickly summarize, there are two paths forward that I believe are > >> acceptable from a LSM perspective, pick either one and send me an > >> updated patchset. > >> > >> 1. Rename the hook to security_bprm_free() and update the LSM hook > >> description as I mentioned earlier in this thread. > >> > >> 2. Rename the hook to security_execve_revert(), move it into the > >> execve related functions, and update the LSM hook description to > >> reflect that this hook is for reverting execve related changes to the > >> current task's internal LSM state beyond what is possible via the > >> credential hooks. > > > > Hi Tetsuo, I just wanted to check on this and see if you've been able > > to make any progress? > > > > I'm fine with either approach. Just worrying that someone doesn't like > overhead of unconditionally calling security_bprm_free() hook. With the coming static calls series, this concern will delightfully go away. :) > If everyone is fine with below one, I'll post v4 patchset. I'm okay with it being security_bprm_free(). One question I had was how Tomoyo deals with it? I was depending on the earlier hook only being called in a failure path. > [...] > @@ -1530,6 +1530,7 @@ static void free_bprm(struct linux_binprm *bprm) > kfree(bprm->interp); > kfree(bprm->fdpath); > kfree(bprm); > + security_bprm_free(); > } I'm fine with security_bprm_free(), but this needs to be moved to the start of free_bprm(), and to pass the bprm itself. This is the pattern we use for all the other "free" hooks. (Though in this case we don't attach any security context to the brpm, but there may be state of interest in it.) i.e.: diff --git a/fs/exec.c b/fs/exec.c index 40073142288f..7ec13b104960 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -1532,6 +1532,7 @@ static void do_close_execat(struct file *file) static void free_bprm(struct linux_binprm *bprm) { + security_bprm_free(bprm); if (bprm->mm) { acct_arg_size(bprm, 0); mmput(bprm->mm);
On Wed, May 1, 2024 at 4:04 PM Kees Cook <keescook@chromium.org> wrote: > On Thu, Feb 15, 2024 at 11:33:32PM +0900, Tetsuo Handa wrote: > > On 2024/02/15 6:46, Paul Moore wrote: > > >> To quickly summarize, there are two paths forward that I believe are > > >> acceptable from a LSM perspective, pick either one and send me an > > >> updated patchset. > > >> > > >> 1. Rename the hook to security_bprm_free() and update the LSM hook > > >> description as I mentioned earlier in this thread. > > >> > > >> 2. Rename the hook to security_execve_revert(), move it into the > > >> execve related functions, and update the LSM hook description to > > >> reflect that this hook is for reverting execve related changes to the > > >> current task's internal LSM state beyond what is possible via the > > >> credential hooks. > > > > > > Hi Tetsuo, I just wanted to check on this and see if you've been able > > > to make any progress? > > > > > > > I'm fine with either approach. Just worrying that someone doesn't like > > overhead of unconditionally calling security_bprm_free() hook. > > With the coming static calls series, this concern will delightfully go > away. :) > > > If everyone is fine with below one, I'll post v4 patchset. > > I'm okay with it being security_bprm_free(). One question I had was how > Tomoyo deals with it? I was depending on the earlier hook only being > called in a failure path. > > > [...] > > @@ -1530,6 +1530,7 @@ static void free_bprm(struct linux_binprm *bprm) > > kfree(bprm->interp); > > kfree(bprm->fdpath); > > kfree(bprm); > > + security_bprm_free(); > > } > > I'm fine with security_bprm_free(), but this needs to be moved to the > start of free_bprm(), and to pass the bprm itself. This is the pattern we > use for all the other "free" hooks. (Though in this case we don't attach > any security context to the brpm, but there may be state of interest in > it.) i.e.: > > diff --git a/fs/exec.c b/fs/exec.c > index 40073142288f..7ec13b104960 100644 > --- a/fs/exec.c > +++ b/fs/exec.c > @@ -1532,6 +1532,7 @@ static void do_close_execat(struct file *file) > > static void free_bprm(struct linux_binprm *bprm) > { > + security_bprm_free(bprm); > if (bprm->mm) { > acct_arg_size(bprm, 0); > mmput(bprm->mm); > Tetsuo, it's been a while since we've heard from you in this thread - are you still planning to work on this? If not, would you object if someone else took over this patchset?
On 2024/06/11 5:44, Paul Moore wrote: >> diff --git a/fs/exec.c b/fs/exec.c >> index 40073142288f..7ec13b104960 100644 >> --- a/fs/exec.c >> +++ b/fs/exec.c >> @@ -1532,6 +1532,7 @@ static void do_close_execat(struct file *file) >> >> static void free_bprm(struct linux_binprm *bprm) >> { >> + security_bprm_free(bprm); >> if (bprm->mm) { >> acct_arg_size(bprm, 0); >> mmput(bprm->mm); >> > > Tetsuo, it's been a while since we've heard from you in this thread - > are you still planning to work on this? If not, would you object if > someone else took over this patchset? > You are going to merge static call patches first (though I call it a regression), aren't you? For me, reviving dynamically appendable hooks (which is about to be killed by static call patches) has the higher priority than adding security_bprm_free() hook.
On Tue, Jun 11, 2024 at 9:10 AM Tetsuo Handa <penguin-kernel@i-love.sakura.ne.jp> wrote: > On 2024/06/11 5:44, Paul Moore wrote: > >> diff --git a/fs/exec.c b/fs/exec.c > >> index 40073142288f..7ec13b104960 100644 > >> --- a/fs/exec.c > >> +++ b/fs/exec.c > >> @@ -1532,6 +1532,7 @@ static void do_close_execat(struct file *file) > >> > >> static void free_bprm(struct linux_binprm *bprm) > >> { > >> + security_bprm_free(bprm); > >> if (bprm->mm) { > >> acct_arg_size(bprm, 0); > >> mmput(bprm->mm); > >> > > > > Tetsuo, it's been a while since we've heard from you in this thread - > > are you still planning to work on this? If not, would you object if > > someone else took over this patchset? > > You are going to merge static call patches first (though I call it a regression), > aren't you? That is the plan, although we need another revision as the latest draft has a randstruct casting problem. > For me, reviving dynamically appendable hooks (which is about to be > killed by static call patches) has the higher priority than adding > security_bprm_free() hook. Unfortunately, dynamic hooks do not appear to be something we are going to support, at least in the near term. With that understanding, do you expect to be able to work on the security_bprm_free() hook patchset?
diff --git a/fs/exec.c b/fs/exec.c index af4fbb61cd53..d6d35a06fd08 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -1521,6 +1521,7 @@ static void free_bprm(struct linux_binprm *bprm) if (bprm->cred) { mutex_unlock(¤t->signal->cred_guard_mutex); abort_creds(bprm->cred); + security_execve_abort(); } do_close_execat(bprm->file); if (bprm->executable) diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h index 76458b6d53da..fd100ab71a33 100644 --- a/include/linux/lsm_hook_defs.h +++ b/include/linux/lsm_hook_defs.h @@ -54,6 +54,7 @@ LSM_HOOK(int, 0, bprm_creds_from_file, struct linux_binprm *bprm, const struct f LSM_HOOK(int, 0, bprm_check_security, struct linux_binprm *bprm) LSM_HOOK(void, LSM_RET_VOID, bprm_committing_creds, const struct linux_binprm *bprm) LSM_HOOK(void, LSM_RET_VOID, bprm_committed_creds, const struct linux_binprm *bprm) +LSM_HOOK(void, LSM_RET_VOID, execve_abort, void) LSM_HOOK(int, 0, fs_context_submount, struct fs_context *fc, struct super_block *reference) LSM_HOOK(int, 0, fs_context_dup, struct fs_context *fc, struct fs_context *src_sc) diff --git a/include/linux/security.h b/include/linux/security.h index d0eb20f90b26..31532b30c4f0 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -299,6 +299,7 @@ int security_bprm_creds_from_file(struct linux_binprm *bprm, const struct file * int security_bprm_check(struct linux_binprm *bprm); void security_bprm_committing_creds(const struct linux_binprm *bprm); void security_bprm_committed_creds(const struct linux_binprm *bprm); +void security_execve_abort(void); int security_fs_context_submount(struct fs_context *fc, struct super_block *reference); int security_fs_context_dup(struct fs_context *fc, struct fs_context *src_fc); int security_fs_context_parse_param(struct fs_context *fc, struct fs_parameter *param); @@ -648,6 +649,10 @@ static inline void security_bprm_committed_creds(const struct linux_binprm *bprm { } +static inline void security_execve_abort(void) +{ +} + static inline int security_fs_context_submount(struct fs_context *fc, struct super_block *reference) { diff --git a/security/security.c b/security/security.c index 3aaad75c9ce8..10adc4d3c5e0 100644 --- a/security/security.c +++ b/security/security.c @@ -1223,6 +1223,17 @@ void security_bprm_committed_creds(const struct linux_binprm *bprm) call_void_hook(bprm_committed_creds, bprm); } +/** + * security_execve_abort() - Notify that exec() has failed + * + * This hook is for undoing changes which cannot be discarded by + * abort_creds(). + */ +void security_execve_abort(void) +{ + call_void_hook(execve_abort); +} + /** * security_fs_context_submount() - Initialise fc->security * @fc: new filesystem context