On Mon, Apr 15, 2019 at 11:20 AM Paul Moore <paul@xxxxxxxxxxxxxx> wrote: > > On Mon, Apr 15, 2019 at 11:05 AM Oleg Nesterov <oleg@xxxxxxxxxx> wrote: > > On 04/15, Paul Moore wrote: > > > > > > On Mon, Apr 15, 2019 at 9:43 AM Oleg Nesterov <oleg@xxxxxxxxxx> wrote: > > > > Well, acct("/proc/self/attr/current") doesn't look like a good idea, but I do > > > > not know where should we put the additional check... And probably > > > > "echo /proc/self/attr/current > /proc/sys/kernel/core_pattern" can hit the > > > > same problem, do_coredump() does override_creds() too. > > > > > > > > May be just add > > > > > > > > if (current->cred != current->real_cred) > > > > return -EACCES; > > > > > > > > into proc_pid_attr_write(), I dunno. > > > > > > Is the problem that do_acct_process() is calling override_creds() and > > > the returned/old credentials are being freed before do_acct_process() > > > can reinstall the creds via revert_creds()? Presumably because the > > > process accounting is causing the credentials to be replaced? > > > > Afaics, the problem is that do_acct_process() does override_creds() and > > then __kernel_write(). Which calls proc_pid_attr_write(), which in turn calls > > selinux_setprocattr(), which does another prepare_creds() + commit_creds(); > > and commit_creds() hits > > > > BUG_ON(task->cred != old); > > Gotcha. In the process of looking at the backtrace I forgot about the > BUG_ON() at the top of the oops message. > > I wonder what terrible things would happen if we changed the BUG_ON() > in commit_creds to simple returning an error an error code to the > caller. There is a warning/requirement in commit_creds() function > header comment that it should always return 0. Would callers be expected to call abort_creds() on failure? There are a number of places where it'd need fixing up. And would likely be best with a __must_check marking. It seems like avoiding the pathological case might be simpler? -- Kees Cook