[Tails-dev] What is *not* erased (after shutdown) with PAX_MEMORY_SANITIZE enabled?

2017-01-02 Thread intrigeri
Hi!

I'm working on Tails (https://tails.boum.org/).

Our threat model includes "someone breaks the door and you have 15
seconds to make your current Tails activity disappear". We assume that
this "someone" may be prepared to try and recover the memory of this
Tails system, e.g. via a cold boot attack.

I'm describing at the bottom of this email our current protection
against this scenario ("Current Tails implementation" section), in
case you're interested in more background; but for now I'll jump
directly to the questions I have for you.


We're considering dropping our current implementation, and relying on
PAX_MEMORY_SANITIZE instead; I know that PAX_MEMORY_SANITIZE was not
designed for this use case, but who knows:  it might be good enough :)

I understand that the result won't achieve perfect protection, but our
current implementation doesn't either. I'd like to see numbers, but
it's hard for me to compare experimentally both approaches: our QA
about this relies on filling memory with a known pattern from
userspace, which works fine to measure the efficiency of our current
implementation, but of course PAX_MEMORY_SANITIZE will erase this
known pattern from memory… So for now I'll stick to the theoretical
level, and experimental measurements will come later.


If I got it right, with PAX_MEMORY_SANITIZE enabled, then:

 * during the lifetime of a system, any memory allocated to
   a userspace program that terminates is erased;

 * during the lifetime of a system, any kernel memory that's
   explicitly freed, e.g. with kfree(), is erased;

 * on system shutdown, all processes are killed, and thus their memory
   is erased.

So, what remains after system shutdown boils down to:

 * kernel memory allocated and then freed, during the lifetime of the
   system, through means that are not covered by PAX_MEMORY_SANITIZE:
   is there any such thing? I'm interested in a (possibly incomplete)
   list of these memory areas or allocation methods.

 * kernel memory, that was still in use during shutdown, and that the
   kernel does not explicitly free: again, is there any such thing?

 * anything else?

I'm not a low-level person myself, so I'm happy to stand corrected,
and I'll probably need help from my team-mates (Cc'ed) to analyze your
answers :)


Current Tails implementation


Our current protection against this scenario is: when I unplug my
Tails USB stick, an emergency shutdown procedure is triggered, that
kexec's another kernel with some special command line parameter, and
then the initramfs erases all the memory that's available from
userspace. This ensures that even the memory that was kept in use by
the previous kernel (e.g. data in tmpfs) is overwritten at least once:
either by the new kernel re-using the same memory, or by the userspace
memory wipe process. Of course, some memory will still remain
unmodified, e.g. whatever data the kernel may have put aside out of
userspace's reach, without overwriting it. E.g. in our tests, a few
dozens of MiB are not erased by this process on a machine with 8 GiB
of RAM. Implementation details are documented there:
https://tails.boum.org/contribute/design/memory_erasure/


Cheers,
-- 
intrigeri
___
Tails-dev mailing list
Tails-dev@boum.org
https://mailman.boum.org/listinfo/tails-dev
To unsubscribe from this list, send an empty email to 
tails-dev-unsubscr...@boum.org.

Re: [Tails-dev] What is *not* erased (after shutdown) with PAX_MEMORY_SANITIZE enabled?

2017-01-03 Thread PaX Team
On 2 Jan 2017 at 15:27, intrigeri wrote:

Hi all,

first of all, i've put spender on CC as an interested party
(especially for the kexec vs. kmem hardening you're discussing
in another thread).

> We're considering dropping our current implementation, and relying on
> PAX_MEMORY_SANITIZE instead; I know that PAX_MEMORY_SANITIZE was not
> designed for this use case, but who knows:  it might be good enough :)

actually this isn't the first time this case has been raised and
cleaning memory on shutdown has been on my todo list ever since,
just not at a high enough priority.

> I understand that the result won't achieve perfect protection, but our
> current implementation doesn't either. I'd like to see numbers, but
> it's hard for me to compare experimentally both approaches: our QA
> about this relies on filling memory with a known pattern from
> userspace, which works fine to measure the efficiency of our current
> implementation, but of course PAX_MEMORY_SANITIZE will erase this
> known pattern from memory… So for now I'll stick to the theoretical
> level, and experimental measurements will come later.
> 
> 
> If I got it right, with PAX_MEMORY_SANITIZE enabled, then:
> 
>  * during the lifetime of a system, any memory allocated to
>a userspace program that terminates is erased;

correct but don't forget that 'allocated to userland' means only
anonymous memory pages that are mapped into userland memory,
everything else (page cache holding file content, dentry/inode/etc
metadata) is subject to different rules, see next.

>  * during the lifetime of a system, any kernel memory that's
>explicitly freed, e.g. with kfree(), is erased;

well, 'free' is a bit abstract concept to reason about at this
level ;).

the kernel has more than one way to allocate (and thus free) memory
and SANITIZE doesn't (directly) apply to all of them. in practice
most memory is managed by the buddy allocator and a few layers that
build on top of it (slab, vmalloc, etc). the first (and original)
layer where SANITIZE kicks in is the buddy allocator where memory
is managed in groups of pages. this becomes important for the layers
built on top of it since they can very well allocate/free memory at
their level without every freeing back to the buddy allocator. for
this reason a while ago Mathias Krause added support for sanitizing
at the slab layer as well (slab manages C level objects, you can
consider it as the kernel's equivalent of malloc) but for performance
reasons not all slabs are sanitized by default (for tails you'll want
to enable all of it i guess, see the config help on the boot time
command line option or just patch the code to change the default
which is probably safer for your case).

>  * on system shutdown, all processes are killed, and thus their memory
>is erased.

yes if (presumably :) you meant a clean shutdown (and subject to
the above details). i'm just pointing it out because in the panic
case you mentioned a clean shutdown may not be possible.

> So, what remains after system shutdown boils down to:
> 
>  * kernel memory allocated and then freed, during the lifetime of the
>system, through means that are not covered by PAX_MEMORY_SANITIZE:
>is there any such thing? I'm interested in a (possibly incomplete)
>list of these memory areas or allocation methods.

while the buddy allocator acts as the lowest layer of memory manager
for the kernel (so it sees everything as far as C code is concerned),
there's also boot time memory allocated that is kept around and i'm
pretty sure that some of it is never freed. there can also be
arch-specific memory reservations that may need special handling
(hugetlbfs, CMA, etc).

>  * kernel memory, that was still in use during shutdown, and that the
>kernel does not explicitly free: again, is there any such thing?

as hinted at above, there's lots of memory that is not process memory
and that will be kept around as long as something uses that memory (or
even when not). shutdown in linux isn't about undoing everything that
happened before, it's simply just another function to execute that
happens to never return. this leaves some memory in-use. just so you
can get an idea, look at /proc/slabinfo from your shutdown script and
count all the still allocated objects... now not all of them have
sensitive information that you care about, but some definitely do.

with all that said, let me comment on your current approach:

> Current Tails implementation
> 
> 
> Our current protection against this scenario is: when I unplug my
> Tails USB stick, an emergency shutdown procedure is triggered, that
> kexec's another kernel with some special command line parameter, and
> then the initramfs erases all the memory that's available from
> userspace.

i'd like to interject here and point out a less than obvious sideeffect
of SANITIZE (not really documented because the effect isn't relevant
for the original purpose of SANITIZE): when the kernel tr

Re: [Tails-dev] What is *not* erased (after shutdown) with PAX_MEMORY_SANITIZE enabled?

2017-01-03 Thread Andrew Gallagher

> On 3 Jan 2017, at 21:40, PaX Team  wrote:
> 
> in other words, if you were to kexec into a SANITIZE enabled kernel,
> you'd get your memory clearing for free automatically, earlier than
> any initramfs would execute even and it'd cover most kernel memory
> that the kernel ever cares about (or cared in its previous incarnation
> at least).
> 
> now this brings us to the other topic you raised about grsecurity's
> KMEM hardening. technically it's not incompatible with kexec, so you
> can re-enable kexec, however note that until some signed kexec mechanism
> enters the kernel, it carries a risk of executing potentially malicious
> kernels (but maybe that's not a problem in your use cases). perhaps
> embedding or loading the kexec kernel from initramfs would get around
> those concerns for good.

Can you kexec from a running kernel into itself? If so, then this single use 
case could be enabled without opening a hole for arbitrary code. It would crash 
when it discovers the boot disk is missing, but by that time sanitize should 
have done its job.

A.
___
Tails-dev mailing list
Tails-dev@boum.org
https://mailman.boum.org/listinfo/tails-dev
To unsubscribe from this list, send an empty email to 
tails-dev-unsubscr...@boum.org.

Re: [Tails-dev] What is *not* erased (after shutdown) with PAX_MEMORY_SANITIZE enabled?

2017-01-03 Thread PaX Team
On 4 Jan 2017 at 1:17, Andrew Gallagher wrote:

> > On 3 Jan 2017, at 21:40, PaX Team  wrote:
> > 
> > in other words, if you were to kexec into a SANITIZE enabled kernel,
> > you'd get your memory clearing for free automatically, earlier than
> > any initramfs would execute even and it'd cover most kernel memory
> > that the kernel ever cares about (or cared in its previous incarnation
> > at least).
> > 
> > now this brings us to the other topic you raised about grsecurity's
> > KMEM hardening. technically it's not incompatible with kexec, so you
> > can re-enable kexec, however note that until some signed kexec mechanism
> > enters the kernel, it carries a risk of executing potentially malicious
> > kernels (but maybe that's not a problem in your use cases). perhaps
> > embedding or loading the kexec kernel from initramfs would get around
> > those concerns for good.
> 
> Can you kexec from a running kernel into itself?

if by 'itself' you mean the kernel image running in memory then the
answer is 'no', or at least 'not without further surgery'.

such surgery would involve among others:
  - not freeing the init code/data on boot
  - restoring the load-time content of writable kernel sections
  - simulating the early boot environment (memory map, firmware and/or
boot loader provided data, etc)

this is feasible but i'm not sure if it's worth the effort when you can
just kexec a kernel, even the same one (loaded separately into memory
of course). note also that i'm not really a kexec guy, so you should
probably talk to the kernel maintainers as well...


___
Tails-dev mailing list
Tails-dev@boum.org
https://mailman.boum.org/listinfo/tails-dev
To unsubscribe from this list, send an empty email to 
tails-dev-unsubscr...@boum.org.

Re: [Tails-dev] What is *not* erased (after shutdown) with PAX_MEMORY_SANITIZE enabled?

2017-01-04 Thread Harlan Lieberman-Berg
Hello everyone!

Thanks for weighing in, PaX Team.  (And thank you for the awesome you
and spender do on kernel security!)

To summarize, it seems that we have a couple different options to choose
from:

* Switch to a dedicated microkernel that does a memory wipe, and kexec
  into it.  This could be something custom, or an enhancement of the
  preexisting solution.

  Advantages are that it will (probably) give us the most clean wipe, as
  we can reduce the amount of space the kernel takes up and drop all
  functionality that's not absolutely needed.  On the negative side, it
  will require continuing to support a separate codeline that's not
  going to be reused elsewhere, limiting testing and development
  effort.  It also requires us to reenable kexec functionality, which
  exposes a risk of code injection unless we get signed kexec support.

* Rely on PAX_MEMORY_SANITIZE.  This either takes the form of enhancing
  cleaning memory on shutdown, or kexec'ing into the same version of the
  kernel that's already running to rely on the buddy allocator clearing
  everything again.

  Definite pro in that it reduces the amount of code maintained
  downstream by the Tails team to ~zero.  Cons are increased reliance on
  more complex functionality in the kernel, and potentially relying on a
  somewhat undocumented and unplanned functionality in the kernel.  (It
  seems unlikely that it'll change any time without us noticing, but
  it's possible.)

* Do it in userspace.  Add functionality into the initramfs as
  necessary to wipe memory, and simply run an abbreviated shutdown.

  This lets us not have to deal with the potential for kexec's attack
  surface, and is probably some medium amount of code between the above
  two options.  Downside is that it potentially is less reliable in
  terms of clearing memory than the other options, and is probably
  slower time-to-first-bit-erased than the other options.

Does that seem like a fair summary to everyone?  If so, which path seems
the best for us to move forward on?

-- 
Harlan Lieberman-Berg
~hlieberman
___
Tails-dev mailing list
Tails-dev@boum.org
https://mailman.boum.org/listinfo/tails-dev
To unsubscribe from this list, send an empty email to 
tails-dev-unsubscr...@boum.org.

Re: [Tails-dev] What is *not* erased (after shutdown) with PAX_MEMORY_SANITIZE enabled?

2017-01-04 Thread Harlan Lieberman-Berg
Harlan Lieberman-Berg  writes:
> It also requires us to reenable kexec functionality, which exposes a
> risk of code injection unless we get signed kexec support.

I just checked the kernel, and it seems that signed kexec functionality
was mainlined in 3.17.  So, strike that from the list of problems with
all the kexec dependent solutions.

-- 
Harlan Lieberman-Berg
~hlieberman
___
Tails-dev mailing list
Tails-dev@boum.org
https://mailman.boum.org/listinfo/tails-dev
To unsubscribe from this list, send an empty email to 
tails-dev-unsubscr...@boum.org.

Re: [Tails-dev] What is *not* erased (after shutdown) with PAX_MEMORY_SANITIZE enabled?

2017-01-17 Thread intrigeri
Hi everybody!

Harlan Lieberman-Berg:
> Thanks for weighing in, PaX Team.  (And thank you for the awesome you
> and spender do on kernel security!)

+1 :)

> To summarize, it seems that we have a couple different options to choose
> from:

> * Switch to a dedicated microkernel that does a memory wipe, and kexec
>   into it.  This could be something custom, or an enhancement of the
>   preexisting solution.

>   Advantages are that it will (probably) give us the most clean wipe, as
>   we can reduce the amount of space the kernel takes up and drop all
>   functionality that's not absolutely needed.  On the negative side, it
>   will require continuing to support a separate codeline that's not
>   going to be reused elsewhere, limiting testing and development
>   effort.  It also requires us to reenable kexec functionality, which
>   exposes a risk of code injection unless we get signed kexec support.

> * Rely on PAX_MEMORY_SANITIZE.  This either takes the form of enhancing
>   cleaning memory on shutdown, or kexec'ing into the same version of the
>   kernel that's already running to rely on the buddy allocator clearing
>   everything again.

>   Definite pro in that it reduces the amount of code maintained
>   downstream by the Tails team to ~zero.  Cons are increased reliance on
>   more complex functionality in the kernel, and potentially relying on a
>   somewhat undocumented and unplanned functionality in the kernel.  (It
>   seems unlikely that it'll change any time without us noticing, but
>   it's possible.)

> * Do it in userspace.  Add functionality into the initramfs as
>   necessary to wipe memory, and simply run an abbreviated shutdown.

>   This lets us not have to deal with the potential for kexec's attack
>   surface, and is probably some medium amount of code between the above
>   two options.  Downside is that it potentially is less reliable in
>   terms of clearing memory than the other options, and is probably
>   slower time-to-first-bit-erased than the other options.

> Does that seem like a fair summary to everyone?

It does seem like it to me.

> If so, which path seems the best for us to move forward on?

I prefer the two first options (mostly because the third one is
essentially what we're already doing, and are trying to
improve/replace).

Not sure which one of those two yet, but the next thing to do in both
cases is the same: make it possible to allow kexec without disabling
GRKERNSEC_KMEM entirely.

I don't know what configuration interface would be best: move kexec
disabling out of GRKERNSEC_KMEM, to another kernel build-time config
setting? Leave it as part of GRKERNSEC_KMEM, but add a sysctl to allow
re-enabling kexec at runtime? pipacs, spender: what do you think?

Cheers,
-- 
intrigeri
___
Tails-dev mailing list
Tails-dev@boum.org
https://mailman.boum.org/listinfo/tails-dev
To unsubscribe from this list, send an empty email to 
tails-dev-unsubscr...@boum.org.