[PATCH 0/6] RFC: adding support to GCC for detecting trust boundaries

David Malcolm dmalcolm@redhat.com
Sun Nov 14 02:54:19 GMT 2021


On Sun, 2021-11-14 at 00:20 +0100, Peter Zijlstra wrote:
> On Sat, Nov 13, 2021 at 03:37:24PM -0500, David Malcolm wrote:
> 
> > This approach is much less expressive that the custom addres space
> > approach; it would only cover the trust boundary aspect; it
> > wouldn't
> > cover any differences between generic pointers and __user, vs
> > __iomem,
> > __percpu, and __rcu which I admit I only dimly understand.
> 
> __iomem would point at device memory, which can have curious side
> effects or is yet another trust boundary, depending on device and
> usage.
> 
> __percpu is an address space that denotes a per-cpu variable's
> relative
> offset, it needs be combined with a per-cpu offset to get a 'real'
> pointer, on x86_64 %gs segment offset is used for this purpose, other
> architectures are less fortunate. The whole per_cpu()/this_cpu_*()
> family of APIs accepts such pointers.
> 
> __rcu is the regular kernel address space, but denotes that the
> object
> pointed to has RCU lifetime management. The attribute is laundered
> through rcu_dereference() to remove the __rcu qualifier.

Thanks; this is very helpful.

> 
> > Possibly silly question: is it always a bug for the value of a
> > kernel
> > pointer to leak into user space?  i.e. should I be complaining
> > about an
> > infoleak if the value of a trusted_ptr itself is written to
> > *untrusted_ptr?  e.g.
> 
> Yes, always. Leaking kernel pointers is unconditionally bad.

Thanks.

FWIW I've thrown together a new warning in -fanalyzer for this, e.g.
given:

/* Some kernel space thing, where the address is presumably secret */
struct foo_t
{
} foo;

/* Response struct for some ioctl/syscall  */
struct s1
{
  void *ptr;
};

void test_1 (void __user *p)
{
  struct s1 s = {0};
  s.ptr = &foo;
  copy_to_user (p, &s, sizeof (s));
}

...my code emits...

infoleak-ptr-1.c: In function ‘test_1’:
infoleak-ptr-1.c:17:3: warning: potential exposure of sensitive
  information by copying pointer ‘&foo’ across trust boundary
  [-Wanalyzer-exposure-of-pointer]
   17 |   copy_to_user (p, &s, sizeof (s));
      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

but it strikes me that there could be other sensitive information
beyond just the values of kernel-space pointers that must not cross a
trust boundary.  GCC's -fanalyzer currently has a state machine for
tracking "sensitive" values, but it's currently just a proof-of-concept
that merely treats the result of the user-space API "getpass" as
sensitive (with a demo of detecting passwords being exposed via
logfiles).  Any ideas on other values in the kernel that it would be
useful to treat as "sensitive"?  (maybe crypto private keys???  other
internal state???)  I can do it by types, by results of functions, etc.
That said, I'm not modeling the kernel's own access model (root vs
regular user etc) in the analyzer, so maybe extending things beyond
kernel space addresses is misguided?


Hope this is constructive
Dave



More information about the Gcc-patches mailing list