Re: [PATCH v4 0/4] Application Data Integrity feature introduced by SPARC M7

2017-01-17 Thread Khalid Aziz

On 01/16/2017 09:47 PM, David Miller wrote:

From: Dave Hansen 
Date: Wed, 11 Jan 2017 10:13:54 -0800


For memory shared by two different processes, do they have to agree on
what the tags are, or can they differ?


Whoever allocates the memory (does the mmap()+mprotect() or whatever),
decides on the tag.  They set it, and this determines which virtual
address is valid to access that mapping.

It's like kmalloc() returns pointers with some weird bits set in the
upper bits of the address.  Behind the scenes kmalloc() sets the
TAG bits appropriately.

It doesn't, in that sense, matter where in the non-tagged virtual
address space the memory is mapped.  All that matters is that, for
a given page, the TAG bits in the virtual address used for loads
and stores to that mapping are set properly.

I think the fundamental thing being missed is that the TAG bits in the
virtual address are not interpreted by the TLB.  They are chopped off
before virtual address translation occurs.

The TAG bits of the virtual address serve only to indicate what ADI
value the load or store thinks is valid to use for access to that
piece of memory.

Or something like that... :-)


Hi David,

Your explanation is spot on. MMU looks at the tag bits only to determine 
if the process has permission to access the memory address. Tag bits are 
not part of VA->PA translation. The tags are stored in physical memory 
though and MMU compares the tag stored at physical address obtained from 
TLB translation to the tag embedded in VA. What that means is if two 
processes map the same physical page in their address space, they both 
must embed the same tag in the VA they present to MMU irrespective of 
where in each process' address space the page is mapped in. If one 
process changes the tag, stored in physical memory, the other process 
must also embed the new tag in its VA when accessing this shared mapped 
page. This is something to consider because a tag can be set and changed 
entirely from userspace with no kernel involvement as long as the 
process has write access to memory.


--
Khalid

--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 0/4] Application Data Integrity feature introduced by SPARC M7

2017-01-16 Thread David Miller
From: Dave Hansen 
Date: Wed, 11 Jan 2017 08:33:30 -0800

> Is there a cost in the hardware associated with doing this "ADI
> checking"?  For instance, instead of having this new mprotect()
> interface, why not just always set TTE.mcd on all PTEs?

If we did this then for every page mapped into userspace we'd have
to explicitly set all of the tags to zero, otherwise we'd get TAG
mismatch exceptions.

That would be like clearing the every mapped anonymous page twice, or
worse.
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 0/4] Application Data Integrity feature introduced by SPARC M7

2017-01-16 Thread David Miller
From: Dave Hansen 
Date: Wed, 11 Jan 2017 10:13:54 -0800

> For memory shared by two different processes, do they have to agree on
> what the tags are, or can they differ?

Whoever allocates the memory (does the mmap()+mprotect() or whatever),
decides on the tag.  They set it, and this determines which virtual
address is valid to access that mapping.

It's like kmalloc() returns pointers with some weird bits set in the
upper bits of the address.  Behind the scenes kmalloc() sets the
TAG bits appropriately.

It doesn't, in that sense, matter where in the non-tagged virtual
address space the memory is mapped.  All that matters is that, for
a given page, the TAG bits in the virtual address used for loads
and stores to that mapping are set properly.

I think the fundamental thing being missed is that the TAG bits in the
virtual address are not interpreted by the TLB.  They are chopped off
before virtual address translation occurs.

The TAG bits of the virtual address serve only to indicate what ADI
value the load or store thinks is valid to use for access to that
piece of memory.

Or something like that... :-)
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 0/4] Application Data Integrity feature introduced by SPARC M7

2017-01-13 Thread Rob Gardner

On 01/13/2017 09:08 AM, Dave Hansen wrote:

On 01/13/2017 07:29 AM, Rob Gardner wrote:

so perhaps ADI should simply be disallowed for memory mapped to
files, and this particular complication can be avoided. Thoughts?

What's a "file" from your perspective?

In Linux, shared memory is a file.  hugetlbfs is done with files.  Many
databases mmap() their data into their address space.


Of course I meant a traditional file is the DOS sense, ie, data stored 
on something magnetic. ;) But it doesn't really matter because I am just 
trying to envision a use case for any of the mmap scenarios.


For instance a very persuasive use case for ADI is to 'color' malloc 
memory, freed malloc memory, and malloc's metadata with different ADI 
version tags so as to catch buffer overflows, underflows, use-after-free 
and use-after-realloc type scenarios. What is an equally compelling or 
even mildly interesting use case for ADI in shared memory and file mmap 
situations? Maybe you could mmap a file and immediately tag the entire 
thing with some version, thus disallowing all access to it, and then 
hand out access a chunk at a time. And then?


Rob



--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 0/4] Application Data Integrity feature introduced by SPARC M7

2017-01-13 Thread Dave Hansen
On 01/13/2017 07:29 AM, Rob Gardner wrote:
> so perhaps ADI should simply be disallowed for memory mapped to
> files, and this particular complication can be avoided. Thoughts?

What's a "file" from your perspective?

In Linux, shared memory is a file.  hugetlbfs is done with files.  Many
databases mmap() their data into their address space.
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 0/4] Application Data Integrity feature introduced by SPARC M7

2017-01-13 Thread Khalid Aziz

On 01/13/2017 08:29 AM, Rob Gardner wrote:

On 01/13/2017 07:48 AM, Khalid Aziz wrote:

On 01/12/2017 06:31 PM, Rob Gardner wrote:

On 01/12/2017 05:22 PM, Khalid Aziz wrote:

On 01/12/2017 10:53 AM, Dave Hansen wrote:

On 01/12/2017 08:50 AM, Khalid Aziz wrote:

2. Any shared page that has ADI protection enabled on it, must
stay ADI
protected across all processes sharing it.


Is that true?

What happens if a page with ADI tags set is accessed via a PTE without
the ADI enablement bit set?


ADI protection applies across all processes in terms of all of them
must use the same tag to access the shared memory, but if a process
accesses a shared page with TTE.mcde bit cleared, access will be
granted.




COW creates an intersection of the two. It creates a new copy of the
shared data. It is a new data page and hence the process creating it
must be the one responsible for enabling ADI protection on it.


Do you mean that the application must be responsible?  Or the kernel
running in the context of the new process must be responsible?


It is also a copy of what was ADI protected data, so should it
inherit the protection instead?


I think the COW'd copy must inherit the VMA bit, the PTE bits, and the
tags on the cachelines.


I misspoke earlier. I had misinterpreted the results of test I ran.
Changing the tag on shared memory is allowed by memory controller.
The
requirement is every one sharing the page must switch to the new
tag or
else they get SIGSEGV.


I asked this in the last mail, but I guess I'll ask it again. Please
answer this directly.

If we require that everyone coordinate their tags on the backing
physical memory, and we allow a lower-privileged program to access the
same data as a more-privileged one, then the lower-privilege app can
cause arbitrary crashes in the privileged application.

For instance, say sudo mmap()'s /etc/passwd and uses ADI tags to
protect
the mapping.  Couldn't any other app in the system prevent sudo from
working?

How can we *EVER* allow tags to be set on non-writable mappings?


I don't think you can write a tag to memory if you don't have write
access in the TTE. Writing a tag requires a store instruction, and if
the machine is at all sane, this will fault if you don't have write
access.



But could you have mmap'd the file writable, set the tags and then
changed the protection on memory to read-only? That would be the
logical way to ADI protect a memory being used to mmap a file. Right?



Sure, if you have write access to begin with, you can set memory
versions, then remove write access to the page. But I think the point is
that if a process doesn't have write access, and cannot get it, then it
will not ever be able to change memory versions. So in the example of a
non-root process opening /etc/passwd (read only), and mmaping it, the
mapping would be read-only as well. Personally I don't really see a use
case for ADI on memory mapped to a file. In an abstract sense, the
"backing store" for a memory mapped file is the file itself on disk, not
physical memory. And there is already a way to restrict access to files,
so perhaps ADI should simply be disallowed for memory mapped to files,
and this particular complication can be avoided. Thoughts?


Hi Rob,

That is a good way to look at it. Memory mapped files already have a 
protection mechanism in place.




Incidentally, I see ADI as primarily a way to protect memory from
improper access within a process or group of cooperating processes.
There is already a way to protect memory from unrelated processes, and
if that is circumvented somehow, then ADI won't help at all. Perhaps we
should stop talking about ADI as a "security" feature; It does add a
layer of protection against buffer overflow attacks, but this attack
only exists when there is a bug in the underlying application. If an
attacker gains access to the virtual memory for a process, then nothing
can help you.



That does make sense. Looking at ADI as a mechanism to prevent 
unintended improper access to memory through buffer overflow or other 
mechanism, would it still make sense to support ADI tags on mmap'd files 
within the group of cooperating processes? Say we have a process that 
mmap's a large file and then forks off a bunch of children that process 
smaller segments of that file. We would want to make sure these children 
do not step over each other's segments of the file due to programming 
flaw or compromise. Parent process could tag each segment with a 
different tag and give one tag to each child process.


I want to be sure we are not shutting down potential useful applications 
of ADI before we choose to not support ADI with memory mapped files.


I appreciate your input.

Thanks,
Khalid



Rob




--
Khalid


Rob





I understand your quetion better now. That is a very valid concern.
Using ADI tags to prevent an unauthorized process from just reading
data in memory, say an in-memory copy of database, is one of the use
cases for ADI. This means 

Re: [PATCH v4 0/4] Application Data Integrity feature introduced by SPARC M7

2017-01-13 Thread Khalid Aziz

On 01/12/2017 06:31 PM, Rob Gardner wrote:

On 01/12/2017 05:22 PM, Khalid Aziz wrote:

On 01/12/2017 10:53 AM, Dave Hansen wrote:

On 01/12/2017 08:50 AM, Khalid Aziz wrote:

2. Any shared page that has ADI protection enabled on it, must stay ADI
protected across all processes sharing it.


Is that true?

What happens if a page with ADI tags set is accessed via a PTE without
the ADI enablement bit set?


ADI protection applies across all processes in terms of all of them
must use the same tag to access the shared memory, but if a process
accesses a shared page with TTE.mcde bit cleared, access will be granted.




COW creates an intersection of the two. It creates a new copy of the
shared data. It is a new data page and hence the process creating it
must be the one responsible for enabling ADI protection on it.


Do you mean that the application must be responsible?  Or the kernel
running in the context of the new process must be responsible?


It is also a copy of what was ADI protected data, so should it
inherit the protection instead?


I think the COW'd copy must inherit the VMA bit, the PTE bits, and the
tags on the cachelines.


I misspoke earlier. I had misinterpreted the results of test I ran.
Changing the tag on shared memory is allowed by memory controller. The
requirement is every one sharing the page must switch to the new tag or
else they get SIGSEGV.


I asked this in the last mail, but I guess I'll ask it again. Please
answer this directly.

If we require that everyone coordinate their tags on the backing
physical memory, and we allow a lower-privileged program to access the
same data as a more-privileged one, then the lower-privilege app can
cause arbitrary crashes in the privileged application.

For instance, say sudo mmap()'s /etc/passwd and uses ADI tags to protect
the mapping.  Couldn't any other app in the system prevent sudo from
working?

How can we *EVER* allow tags to be set on non-writable mappings?


I don't think you can write a tag to memory if you don't have write
access in the TTE. Writing a tag requires a store instruction, and if
the machine is at all sane, this will fault if you don't have write access.



But could you have mmap'd the file writable, set the tags and then 
changed the protection on memory to read-only? That would be the logical 
way to ADI protect a memory being used to mmap a file. Right?


--
Khalid


Rob





I understand your quetion better now. That is a very valid concern.
Using ADI tags to prevent an unauthorized process from just reading
data in memory, say an in-memory copy of database, is one of the use
cases for ADI. This means there is a reasonable case to allow enabling
ADI and setting tags even on non-writable mappings. On the other hand,
if an unauthorized process manages to map the right memory pages in
its address space, it can read them any way by not setting TTE.mcd.

Userspace app can set tag on any memory it has mapped in without
requiring assistance from kernel. Can this problem be solved by not
allowing setting TTE.mcd on non-writable mappings? Doesn't the same
problem occur on writable mappings? If a privileged process mmap()'s a
writable file with MAP_SHARED, enables ADI and sets tag on the mmap'd
memory region, then another lower privilege process mmap's the same
file writable (assuming file permissions allow it to), enables ADI and
sets a different tag on it, the privileged process would get SIGSEGV
when it tries to access the mmap'd file. Right?




--
To unsubscribe from this list: send the line "unsubscribe sparclinux" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 0/4] Application Data Integrity feature introduced by SPARC M7

2017-01-12 Thread Rob Gardner

On 01/12/2017 05:22 PM, Khalid Aziz wrote:

On 01/12/2017 10:53 AM, Dave Hansen wrote:

On 01/12/2017 08:50 AM, Khalid Aziz wrote:

2. Any shared page that has ADI protection enabled on it, must stay ADI
protected across all processes sharing it.


Is that true?

What happens if a page with ADI tags set is accessed via a PTE without
the ADI enablement bit set?


ADI protection applies across all processes in terms of all of them 
must use the same tag to access the shared memory, but if a process 
accesses a shared page with TTE.mcde bit cleared, access will be granted.





COW creates an intersection of the two. It creates a new copy of the
shared data. It is a new data page and hence the process creating it
must be the one responsible for enabling ADI protection on it.


Do you mean that the application must be responsible?  Or the kernel
running in the context of the new process must be responsible?


It is also a copy of what was ADI protected data, so should it
inherit the protection instead?


I think the COW'd copy must inherit the VMA bit, the PTE bits, and the
tags on the cachelines.


I misspoke earlier. I had misinterpreted the results of test I ran.
Changing the tag on shared memory is allowed by memory controller. The
requirement is every one sharing the page must switch to the new tag or
else they get SIGSEGV.


I asked this in the last mail, but I guess I'll ask it again. Please
answer this directly.

If we require that everyone coordinate their tags on the backing
physical memory, and we allow a lower-privileged program to access the
same data as a more-privileged one, then the lower-privilege app can
cause arbitrary crashes in the privileged application.

For instance, say sudo mmap()'s /etc/passwd and uses ADI tags to protect
the mapping.  Couldn't any other app in the system prevent sudo from
working?

How can we *EVER* allow tags to be set on non-writable mappings?


I don't think you can write a tag to memory if you don't have write 
access in the TTE. Writing a tag requires a store instruction, and if 
the machine is at all sane, this will fault if you don't have write access.


Rob





I understand your quetion better now. That is a very valid concern. 
Using ADI tags to prevent an unauthorized process from just reading 
data in memory, say an in-memory copy of database, is one of the use 
cases for ADI. This means there is a reasonable case to allow enabling 
ADI and setting tags even on non-writable mappings. On the other hand, 
if an unauthorized process manages to map the right memory pages in 
its address space, it can read them any way by not setting TTE.mcd.


Userspace app can set tag on any memory it has mapped in without 
requiring assistance from kernel. Can this problem be solved by not 
allowing setting TTE.mcd on non-writable mappings? Doesn't the same 
problem occur on writable mappings? If a privileged process mmap()'s a 
writable file with MAP_SHARED, enables ADI and sets tag on the mmap'd 
memory region, then another lower privilege process mmap's the same 
file writable (assuming file permissions allow it to), enables ADI and 
sets a different tag on it, the privileged process would get SIGSEGV 
when it tries to access the mmap'd file. Right?




--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 0/4] Application Data Integrity feature introduced by SPARC M7

2017-01-12 Thread Khalid Aziz

On 01/12/2017 10:53 AM, Dave Hansen wrote:

On 01/12/2017 08:50 AM, Khalid Aziz wrote:

2. Any shared page that has ADI protection enabled on it, must stay ADI
protected across all processes sharing it.


Is that true?

What happens if a page with ADI tags set is accessed via a PTE without
the ADI enablement bit set?


ADI protection applies across all processes in terms of all of them must 
use the same tag to access the shared memory, but if a process accesses 
a shared page with TTE.mcde bit cleared, access will be granted.





COW creates an intersection of the two. It creates a new copy of the
shared data. It is a new data page and hence the process creating it
must be the one responsible for enabling ADI protection on it.


Do you mean that the application must be responsible?  Or the kernel
running in the context of the new process must be responsible?


It is also a copy of what was ADI protected data, so should it
inherit the protection instead?


I think the COW'd copy must inherit the VMA bit, the PTE bits, and the
tags on the cachelines.


I misspoke earlier. I had misinterpreted the results of test I ran.
Changing the tag on shared memory is allowed by memory controller. The
requirement is every one sharing the page must switch to the new tag or
else they get SIGSEGV.


I asked this in the last mail, but I guess I'll ask it again.  Please
answer this directly.

If we require that everyone coordinate their tags on the backing
physical memory, and we allow a lower-privileged program to access the
same data as a more-privileged one, then the lower-privilege app can
cause arbitrary crashes in the privileged application.

For instance, say sudo mmap()'s /etc/passwd and uses ADI tags to protect
the mapping.  Couldn't any other app in the system prevent sudo from
working?

How can we *EVER* allow tags to be set on non-writable mappings?


I understand your quetion better now. That is a very valid concern. 
Using ADI tags to prevent an unauthorized process from just reading data 
in memory, say an in-memory copy of database, is one of the use cases 
for ADI. This means there is a reasonable case to allow enabling ADI and 
setting tags even on non-writable mappings. On the other hand, if an 
unauthorized process manages to map the right memory pages in its 
address space, it can read them any way by not setting TTE.mcd.


Userspace app can set tag on any memory it has mapped in without 
requiring assistance from kernel. Can this problem be solved by not 
allowing setting TTE.mcd on non-writable mappings? Doesn't the same 
problem occur on writable mappings? If a privileged process mmap()'s a 
writable file with MAP_SHARED, enables ADI and sets tag on the mmap'd 
memory region, then another lower privilege process mmap's the same file 
writable (assuming file permissions allow it to), enables ADI and sets a 
different tag on it, the privileged process would get SIGSEGV when it 
tries to access the mmap'd file. Right?


Thanks,
Khalid
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 0/4] Application Data Integrity feature introduced by SPARC M7

2017-01-12 Thread Dave Hansen
On 01/12/2017 08:50 AM, Khalid Aziz wrote:
> 2. Any shared page that has ADI protection enabled on it, must stay ADI
> protected across all processes sharing it.

Is that true?

What happens if a page with ADI tags set is accessed via a PTE without
the ADI enablement bit set?

> COW creates an intersection of the two. It creates a new copy of the
> shared data. It is a new data page and hence the process creating it
> must be the one responsible for enabling ADI protection on it.

Do you mean that the application must be responsible?  Or the kernel
running in the context of the new process must be responsible?

> It is also a copy of what was ADI protected data, so should it
> inherit the protection instead?

I think the COW'd copy must inherit the VMA bit, the PTE bits, and the
tags on the cachelines.

> I misspoke earlier. I had misinterpreted the results of test I ran.
> Changing the tag on shared memory is allowed by memory controller. The
> requirement is every one sharing the page must switch to the new tag or
> else they get SIGSEGV.

I asked this in the last mail, but I guess I'll ask it again.  Please
answer this directly.

If we require that everyone coordinate their tags on the backing
physical memory, and we allow a lower-privileged program to access the
same data as a more-privileged one, then the lower-privilege app can
cause arbitrary crashes in the privileged application.

For instance, say sudo mmap()'s /etc/passwd and uses ADI tags to protect
the mapping.  Couldn't any other app in the system prevent sudo from
working?

How can we *EVER* allow tags to be set on non-writable mappings?

> I am inclined to suggest we copy the tags to the new data page on COW
> and that will continue to enforce ADI on the COW'd pages even though
> COW'd pages are new data pages. This is the logically consistent
> behavior. Does that make sense?

Yes, I think this is what you have to do.
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 0/4] Application Data Integrity feature introduced by SPARC M7

2017-01-11 Thread Dave Hansen
On 01/11/2017 04:22 PM, Khalid Aziz wrote:
...
> All of the tag coordination can happen in userspace. Once a process sets
> a tag on a physical page mapped in its address space, another process
> that has mapped the same physical page in its address space can only set
> the tag to exact same value. Attempts to set a different tag are caught
> by memory controller and result in MCD trap and kernel sends SIGSEGV to
> the process trying to set a different tag.

Again, I don't think these semantics will work for anything other than
explicitly shared memory.  This behavior ensures that it is *entirely*
unsafe to use ADI on any data that any process you do not control might
be able to mmap().  That's a *HUGE* caveat for the feature and can't
imagine ever seeing this get merged without addressing it.

I think it's fairly simple to address, though a bit expensive.  First,
you can't allow the VMA bit to get set on non-writable mappings.
Second, you'll have to force COW to occur on read-only pages in writable
mappings before the PTE bit can get set.  I think you can probably even
do this in the faults that presumably occur when you try to set ADI tags
on memory mapped with non-ADI PTEs.

>> If you want to use it on copy-on-write'able data, you've got to ensure
>> that you've got entirely private copies.  I'm not sure we even have an
>> interface to guarantee that.  How could this work after a fork() on
>> un-COW'd, but COW'able data?
> 
> On COW, kernel maps the the source and destination pages with
> kmap_atomic() and copies the data over to the new page and the new page
> wouldn't be ADI protected unless the child process chooses to do so.

What do you mean by "ADI protection"?

I think of ADI _protection_ as coming from the PTE and/or VMA bits.
Those are copied at fork() from the old VMA to the new one.  Is there a
reason the child won't implicitly inherit these that I missed?

Whether the parent or the child does the COW fault is basically random.
Whether they get the ADI-tagged page, or the non-ADI-tagged copy is thus
effectively random.  Assuming that the new page has its tags cleared
(and thus is tagged not to be protected), whether your data continues to
be protected or not after a fork() is random.

That doesn't seem like workable behavior.


--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 0/4] Application Data Integrity feature introduced by SPARC M7

2017-01-11 Thread Khalid Aziz

On 01/11/2017 12:11 PM, Dave Hansen wrote:

On 01/11/2017 10:50 AM, Khalid Aziz wrote:

On 01/11/2017 11:13 AM, Dave Hansen wrote:

On 01/11/2017 08:56 AM, Khalid Aziz wrote:
For memory shared by two different processes, do they have to agree on
what the tags are, or can they differ?


The two processes have to agree on the tag. This is part of the security
design to prevent other processes from accessing pages belonging to
another process unless they know the tag set on those pages.


So what do you do with static data, say from a shared executable?  You
need to ensure that two different processes from two different privilege
domains can't set different tags on the same physical memory.  That
would seem to mean that you must not allow tags to be set of memory
unless you have write access to it.  Or, you have to ensure that any
file that you might want to use this feature on is entirely unreadable
(well, un-mmap()-able really) by anybody that you are not coordinating with.


All of the tag coordination can happen in userspace. Once a process sets 
a tag on a physical page mapped in its address space, another process 
that has mapped the same physical page in its address space can only set 
the tag to exact same value. Attempts to set a different tag are caught 
by memory controller and result in MCD trap and kernel sends SIGSEGV to 
the process trying to set a different tag.




If you want to use it on copy-on-write'able data, you've got to ensure
that you've got entirely private copies.  I'm not sure we even have an
interface to guarantee that.  How could this work after a fork() on
un-COW'd, but COW'able data?


On COW, kernel maps the the source and destination pages with 
kmap_atomic() and copies the data over to the new page and the new page 
wouldn't be ADI protected unless the child process chooses to do so. 
This wouldn't change with ADI as far as private copies are concerned. 
Please do correct me if I get something wrong here. Quick tests with COW 
data show everything working as expected but your asking about COW has 
raised a few questions in my own mind. I am researching through docs and 
running experiments to validate my thinking and I will give you more 
definite information on whether COW would mess ADI up.


Thanks,
Khalid

--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 0/4] Application Data Integrity feature introduced by SPARC M7

2017-01-11 Thread Dave Hansen
On 01/11/2017 10:50 AM, Khalid Aziz wrote:
> On 01/11/2017 11:13 AM, Dave Hansen wrote:
>> On 01/11/2017 08:56 AM, Khalid Aziz wrote:
>> For memory shared by two different processes, do they have to agree on
>> what the tags are, or can they differ?
> 
> The two processes have to agree on the tag. This is part of the security
> design to prevent other processes from accessing pages belonging to
> another process unless they know the tag set on those pages.

So what do you do with static data, say from a shared executable?  You
need to ensure that two different processes from two different privilege
domains can't set different tags on the same physical memory.  That
would seem to mean that you must not allow tags to be set of memory
unless you have write access to it.  Or, you have to ensure that any
file that you might want to use this feature on is entirely unreadable
(well, un-mmap()-able really) by anybody that you are not coordinating with.

If you want to use it on copy-on-write'able data, you've got to ensure
that you've got entirely private copies.  I'm not sure we even have an
interface to guarantee that.  How could this work after a fork() on
un-COW'd, but COW'able data?

>>> Potential for side
>>> effects is too high in such case and would require kernel to either
>>> track tags for every page as they are re-allocated or migrated, or scrub
>>> pages constantly to ensure we do not get spurious tag mismatches. Unless
>>> there is a very strong reason to blindly set TTE.mcd on every PTE, I
>>> think the risk of instability is too high without lot of extra code.
>>
>> Ahh, ok.  That makes sense.  Clearing the tags is expensive.  We must
>> either clear tags or know the previous tags of the memory before we
>> access it.
>>
>> Are any of the tags special?  Do any of them mean "don't do any
>> checking", or similar?
> 
> Tag values of 0 and 15 can be considered special. Setting tag to 15 on
> memory range is disallowed. Accessing a memory location whose tag is
> cleared (means set to 0) with any tag value in the VA is allowed. Once a
> tag is set on a memory, and PSTATE.mcde and TTE.mcd are set, there isn't
> a tag that can be used to bypass version check by MMU.

Bummer.  If the hardware had allowed a special VA tag to bypass checks,
then you wouldn't need to worry about clearing the tags, and you
wouldn't need the interface to control the PTE bit setting/clearing.

--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 0/4] Application Data Integrity feature introduced by SPARC M7

2017-01-11 Thread Khalid Aziz

On 01/11/2017 11:13 AM, Dave Hansen wrote:

On 01/11/2017 08:56 AM, Khalid Aziz wrote:

On 01/11/2017 09:33 AM, Dave Hansen wrote:

On 01/11/2017 08:12 AM, Khalid Aziz wrote:

A userspace task enables ADI through mprotect(). This patch series adds
a page protection bit PROT_ADI and a corresponding VMA flag
VM_SPARC_ADI. VM_SPARC_ADI is used to trigger setting TTE.mcd bit in the
sparc pte that enables ADI checking on the corresponding page.


Is there a cost in the hardware associated with doing this "ADI
checking"?  For instance, instead of having this new mprotect()
interface, why not just always set TTE.mcd on all PTEs?


There is no performance penalty in the MMU to check tags, but if
PSTATE.mcd bit is set and TTE.mcde is set, the tag in VA must match what
was set on the physical page for all memory accesses.


OK, then I'm misunderstanding the architecture again.

For memory shared by two different processes, do they have to agree on
what the tags are, or can they differ?


The two processes have to agree on the tag. This is part of the security 
design to prevent other processes from accessing pages belonging to 
another process unless they know the tag set on those pages.





Potential for side
effects is too high in such case and would require kernel to either
track tags for every page as they are re-allocated or migrated, or scrub
pages constantly to ensure we do not get spurious tag mismatches. Unless
there is a very strong reason to blindly set TTE.mcd on every PTE, I
think the risk of instability is too high without lot of extra code.


Ahh, ok.  That makes sense.  Clearing the tags is expensive.  We must
either clear tags or know the previous tags of the memory before we
access it.

Are any of the tags special?  Do any of them mean "don't do any
checking", or similar?



Tag values of 0 and 15 can be considered special. Setting tag to 15 on 
memory range is disallowed. Accessing a memory location whose tag is 
cleared (means set to 0) with any tag value in the VA is allowed. Once a 
tag is set on a memory, and PSTATE.mcde and TTE.mcd are set, there isn't 
a tag that can be used to bypass version check by MMU.


Thanks,
Khalid

--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 0/4] Application Data Integrity feature introduced by SPARC M7

2017-01-11 Thread Dave Hansen
On 01/11/2017 08:56 AM, Khalid Aziz wrote:
> On 01/11/2017 09:33 AM, Dave Hansen wrote:
>> On 01/11/2017 08:12 AM, Khalid Aziz wrote:
>>> A userspace task enables ADI through mprotect(). This patch series adds
>>> a page protection bit PROT_ADI and a corresponding VMA flag
>>> VM_SPARC_ADI. VM_SPARC_ADI is used to trigger setting TTE.mcd bit in the
>>> sparc pte that enables ADI checking on the corresponding page.
>>
>> Is there a cost in the hardware associated with doing this "ADI
>> checking"?  For instance, instead of having this new mprotect()
>> interface, why not just always set TTE.mcd on all PTEs?
> 
> There is no performance penalty in the MMU to check tags, but if
> PSTATE.mcd bit is set and TTE.mcde is set, the tag in VA must match what
> was set on the physical page for all memory accesses.

OK, then I'm misunderstanding the architecture again.

For memory shared by two different processes, do they have to agree on
what the tags are, or can they differ?

> Potential for side
> effects is too high in such case and would require kernel to either
> track tags for every page as they are re-allocated or migrated, or scrub
> pages constantly to ensure we do not get spurious tag mismatches. Unless
> there is a very strong reason to blindly set TTE.mcd on every PTE, I
> think the risk of instability is too high without lot of extra code.

Ahh, ok.  That makes sense.  Clearing the tags is expensive.  We must
either clear tags or know the previous tags of the memory before we
access it.

Are any of the tags special?  Do any of them mean "don't do any
checking", or similar?

--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 0/4] Application Data Integrity feature introduced by SPARC M7

2017-01-11 Thread Dave Hansen
On 01/11/2017 08:12 AM, Khalid Aziz wrote:
> A userspace task enables ADI through mprotect(). This patch series adds
> a page protection bit PROT_ADI and a corresponding VMA flag
> VM_SPARC_ADI. VM_SPARC_ADI is used to trigger setting TTE.mcd bit in the
> sparc pte that enables ADI checking on the corresponding page.

Is there a cost in the hardware associated with doing this "ADI
checking"?  For instance, instead of having this new mprotect()
interface, why not just always set TTE.mcd on all PTEs?

Also, should this be a privileged interface in some way?  The hardware
is storing these tags *somewhere* and that storage is consuming
resources *somewhere*.  What stops a crafty attacker from mmap()'ing a
128TB chunk of the zero pages and storing ADI tags for all of it?
That'll be 128TB/64*4bits = 1TB worth of 4-bit tags.  Page tables, for
instance, consume a comparable amount of storage, but the OS *knows*
about those and can factor them into OOM decisions.
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 0/4] Application Data Integrity feature introduced by SPARC M7

2017-01-11 Thread Khalid Aziz
SPARC M7 processor adds additional metadata for memory address space
that can be used to secure access to regions of memory. This additional
metadata is implemented as a 4-bit tag attached to each cacheline size
block of memory. A task can set a tag on any number of such blocks.
Access to such block is granted only if the virtual address used to
access that block of memory has the tag encoded in the uppermost 4 bits
of VA. Any mismatch between tag encoded in VA and tag set on the memory
block results in a trap. Tags are verified in the VA presented to the
MMU and tags are associated with the physical page VA maps on to. If a
memory page is swapped out and page frame gets reused for another task,
the tags are lost and hence must be saved when swapping or migrating the
page.

A userspace task enables ADI through mprotect(). This patch series adds
a page protection bit PROT_ADI and a corresponding VMA flag
VM_SPARC_ADI. VM_SPARC_ADI is used to trigger setting TTE.mcd bit in the
sparc pte that enables ADI checking on the corresponding page. MMU
validates the tag embedded in VA for every page that has TTE.mcd bit set
in its pte. After enabling ADI on a memory range, the userspace task can
set ADI version tags using stxa instruction with ASI_MCD_PRIMARY or
ASI_MCD_ST_BLKINIT_PRIMARY ASI.

Once userspace task calls mprotect() with PROT_ADI, kernel takes
following overall steps:

1. Find the VMAs covering the address range passed in to mprotect and
set VM_SPARC_ADI flag. If address range covers a subset of a VMA, the
VMA will be split.

2. When a page is allocated for a VA and the VMA covering this VA has
VM_SPARC_ADI flag set, set the TTE.mcd bit so MMU will check the
vwersion tag.

3. Userspace can now set version tags on the memory it has enabled ADI
on. Userspace accesses ADI enabled memory using a virtual address that
has the version tag embedded in the high bits. MMU validates this
version tag against the actual tag set on the memory. If tag matches,
MMU performs the VA->PA translation and access is granted. If there is
a mismatch, hypervisor sends a data access exception or precise memory
corruption detected exception depending upon whether precise exceptions
are enabled or not (controlled by MCDPERR register). Kernel sends
SIGSEGV to the task with appropriate si_code.

4. If a page is being swapped out or migrated, kernel builds a swap pte
for the page. If the page is ADI enabled and has version tags set on it,
set_swp_pte_at() function introduced by this patch series allows kernel
to save the version tags. set_swp_pte_at() replaces the calls to
set_pte_at() in functions that unmap and map a page. On architectures
that do not require special handling on a page being swapped,
set_swp_pte_at() defaults to set_pte_at(). In this initial
implementation, kernel supports saving one version tag per page and top
bits of swap offset in swap pte are used to store the tag.

5. When the page is swapped back in or reinstantiated after migration,
set_swp_pte_at() function allows kernel to restore the version tags on
the new physical page by retrieving the original tag from swap offset in
swap pte.

User task can disable ADI by calling mprotect() again on the memory
range with PROT_ADI bit unset. Kernel clears the VM_SPARC_ADI flag in
VMAs, merges adjacent VMAs if necessary, and clears TTE.mcd bit in the
corresponding ptes.

IOMMU does not support ADI checking. Any version tags
embedded in the top bits of VA meant for IOMMU, are cleared and replaced
with sign extension of the first non-version tag bit (bit 59 for SPARC
M7) for IOMMU addresses.

This patch series adds support for this feature in 4 patches:

Patch 1/4
  Tag mismatch on access by a task results in a trap from hypervisor as
  data access exception or a precide memory corruption detected
  exception. As part of handling these exceptions, kernel sends a
  SIGSEGV to user process with special si_code to indicate which fault
  occurred. This patch adds three new si_codes to differentiate between
  various mismatch errors.

Patch 2/4
  When a page is swapped or migrated, metadata associated with the page
  must be saved so it can be restored later. This patch adds a new
  function that saves/restores this metadata when updating pte upon a
  swap/migration.

Patch 3/4
  SPARC M7 processor adds new fields to control registers to support ADI
  feature. It also adds a new exception for precise traps on tag
  mismatch. This patch adds definitions for the new control register
  fields, new ASIs for ADI and an exception handler for the precise trap
  on tag mismatch.

Patch 4/4
  This patch adds support for a user space task to enable ADI and enable
  tag checking for subsets of its address space. As part of enabling
  this feature, this patch also extends exception handlers to handler
  tag mismatch exceptions, adds code to save and restore tags on page
  swap and migration, and adds code to return ADI parameters to
  userspace.


Testing:

- All functionality was