Re: [PATCH v2] kernel: add panic_on_taint
From: Rafael Aquini
Date: Sat May 09 2020 - 10:56:40 EST
On Sat, May 09, 2020 at 03:48:54AM +0000, Luis Chamberlain wrote:
> On Fri, May 08, 2020 at 08:47:19AM -0400, Rafael Aquini wrote:
> > On Thu, May 07, 2020 at 10:25:58PM +0000, Luis Chamberlain wrote:
> > > On Thu, May 07, 2020 at 06:06:06PM -0400, Rafael Aquini wrote:
> > > > On Thu, May 07, 2020 at 08:33:40PM +0000, Luis Chamberlain wrote:
> > > > > I *think* that a cmdline route to enable this would likely remove the
> > > > > need for the kernel config for this. But even with Vlastimil's work
> > > > > merged, I think we'd want yet-another value to enable / disable this
> > > > > feature. Do we need yet-another-taint flag to tell us that this feature
> > > > > was enabled?
> > > > >
> > > >
> > > > I guess it makes sense to get rid of the sysctl interface for
> > > > proc_on_taint, and only keep it as a cmdline option.
> > >
> > > That would be easier to support and k3eps this simple.
> > >
> > > > But the real issue seems to be, regardless we go with a cmdline-only option
> > > > or not, the ability of proc_taint() to set any arbitrary taint flag
> > > > other than just marking the kernel with TAINT_USER.
> > >
> > > I think we would have no other option but to add a new TAINT flag so
> > > that we know that the taint flag was modified by a user. Perhaps just
> > > re-using TAINT_USER when proc_taint() would suffice.
> > >
> >
> > We might not need an extra taint flag if, perhaps, we could make these
> > two features mutually exclusive. The idea here is that bitmasks added
> > via panic_on_taint get filtered out in proc_taint(), so a malicious
> > user couldn't exploit the latter interface to easily panic the system,
> > when the first one is also in use.
>
> I get it, however I I can still see the person who enables enabling
> panic-on-tain wanting to know if proc_taint() was used. So even if
> it was not on their mask, if it was modified that seems like important
> information for a bug report analysis.
>
For that purpose (tracking user taints) I think sth between these lines
would work:
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 8a176d8727a3..651a82c13621 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -2602,6 +2602,9 @@ int proc_douintvec(struct ctl_table *table, int write,
do_proc_douintvec_conv, NULL);
}
+/* track which taint bits were set by the user */
+static unsigned long user_tainted;
+
/*
* Taint values can only be increased
* This means we can safely use a temporary.
@@ -2629,11 +2632,20 @@ static int proc_taint(struct ctl_table *table, int write,
*/
int i;
for (i = 0; i < BITS_PER_LONG && tmptaint >> i; i++) {
- if ((tmptaint >> i) & 1)
+ if ((tmptaint >> i) & 1) {
+ set_bit(i, &user_tainted);
add_taint(i, LOCKDEP_STILL_OK);
+ }
}
}
+ /*
+ * Users with SYS_ADMIN capability can fiddle with any arbitrary
+ * taint flag through this interface.
+ * If that's the case, we also need to mark the kernel "tainted by user"
+ */
+ add_taint(TAINT_USER, LOCKDEP_STILL_OK);
+
return err;
}
I don't think, though, it's panic_on_taint work to track that. I posted a v3 for
this feature with a way to select if one wants to avoid user forced taints
triggering panic() for flags also set for panic_on_taint.
Cheers,
-- Rafael