Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1556683 > unrolled thread
| Started by | Khalid Aziz <khalid.aziz@oracle.com> |
|---|---|
| First post | 2017-01-11 17:20 +0100 |
| Last post | 2017-01-13 17:10 +0100 |
| Articles | 18 — 3 participants |
Back to article view | Back to linux.kernel
[PATCH v4 0/4] Application Data Integrity feature introduced by SPARC M7 Khalid Aziz <khalid.aziz@oracle.com> - 2017-01-11 17:20 +0100
[PATCH v4 1/4] signals, sparc: Add signal codes for ADI violations Khalid Aziz <khalid.aziz@oracle.com> - 2017-01-11 17:20 +0100
Re: [PATCH v4 0/4] Application Data Integrity feature introduced by SPARC M7 Dave Hansen <dave.hansen@linux.intel.com> - 2017-01-11 17:40 +0100
Re: [PATCH v4 0/4] Application Data Integrity feature introduced by SPARC M7 Khalid Aziz <khalid.aziz@oracle.com> - 2017-01-11 18:00 +0100
Re: [PATCH v4 0/4] Application Data Integrity feature introduced by SPARC M7 Dave Hansen <dave.hansen@linux.intel.com> - 2017-01-11 19:20 +0100
Re: [PATCH v4 0/4] Application Data Integrity feature introduced by SPARC M7 Khalid Aziz <khalid.aziz@oracle.com> - 2017-01-11 20:00 +0100
Re: [PATCH v4 0/4] Application Data Integrity feature introduced by SPARC M7 Dave Hansen <dave.hansen@linux.intel.com> - 2017-01-11 20:20 +0100
Re: [PATCH v4 0/4] Application Data Integrity feature introduced by SPARC M7 Khalid Aziz <khalid.aziz@oracle.com> - 2017-01-12 01:30 +0100
Re: [PATCH v4 0/4] Application Data Integrity feature introduced by SPARC M7 Dave Hansen <dave.hansen@linux.intel.com> - 2017-01-12 01:50 +0100
Re: [PATCH v4 0/4] Application Data Integrity feature introduced by SPARC M7 Khalid Aziz <khalid.aziz@oracle.com> - 2017-01-12 18:00 +0100
Re: [PATCH v4 0/4] Application Data Integrity feature introduced by SPARC M7 Dave Hansen <dave.hansen@linux.intel.com> - 2017-01-12 19:00 +0100
Re: [PATCH v4 0/4] Application Data Integrity feature introduced by SPARC M7 Khalid Aziz <khalid.aziz@oracle.com> - 2017-01-13 01:30 +0100
Re: [PATCH v4 0/4] Application Data Integrity feature introduced by SPARC M7 Rob Gardner <rob.gardner@oracle.com> - 2017-01-13 02:40 +0100
Re: [PATCH v4 0/4] Application Data Integrity feature introduced by SPARC M7 Khalid Aziz <khalid.aziz@oracle.com> - 2017-01-13 15:50 +0100
Re: [PATCH v4 0/4] Application Data Integrity feature introduced by SPARC M7 Rob Gardner <rob.gardner@oracle.com> - 2017-01-13 16:40 +0100
Re: [PATCH v4 0/4] Application Data Integrity feature introduced by SPARC M7 Dave Hansen <dave.hansen@linux.intel.com> - 2017-01-13 17:10 +0100
Re: [PATCH v4 0/4] Application Data Integrity feature introduced by SPARC M7 Rob Gardner <rob.gardner@oracle.com> - 2017-01-13 18:40 +0100
Re: [PATCH v4 0/4] Application Data Integrity feature introduced by SPARC M7 Khalid Aziz <khalid.aziz@oracle.com> - 2017-01-13 17:10 +0100
| From | Khalid Aziz <khalid.aziz@oracle.com> |
|---|---|
| Date | 2017-01-11 17:20 +0100 |
| Subject | [PATCH v4 0/4] Application Data Integrity feature introduced by SPARC M7 |
| Message-ID | <sYtN0-Fd-21@gated-at.bofh.it> |
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 tested with 8K normal pages as well as hugepages using malloc, mmap and shm. - Multiple long duration stress tests were run using hugepages over 2+ months. Normal pages were tested with shorter duration stress tests. - Tested swapping with malloc and shm by reducing max memory and allocating three times the available system memory by active processes using ADI on allocated memory. Ran through multiple hour long runs of this test. - Tested page migration with malloc and shm by migrating data pages of active ADI test process using migratepages, back and forth between two nodes every few seconds over an hour long run. Verified page migration through /proc/<pid>/numa_maps. --- Khalid Aziz (4): signals, sparc: Add signal codes for ADI violations mm: Add function to support extra actions on swap in/out sparc64: Add support for ADI register fields, ASIs and traps sparc64: Add support for ADI (Application Data Integrity) Documentation/sparc/adi.txt | 288 ++++++++++++++++++++++++++++++++ arch/sparc/include/asm/adi.h | 6 + arch/sparc/include/asm/adi_64.h | 46 +++++ arch/sparc/include/asm/elf_64.h | 8 + arch/sparc/include/asm/hugetlb.h | 13 ++ arch/sparc/include/asm/hypervisor.h | 2 + arch/sparc/include/asm/mman.h | 40 ++++- arch/sparc/include/asm/mmu_64.h | 2 + arch/sparc/include/asm/mmu_context_64.h | 32 ++++ arch/sparc/include/asm/pgtable_64.h | 96 ++++++++++- arch/sparc/include/asm/ttable.h | 10 ++ arch/sparc/include/asm/uaccess_64.h | 120 ++++++++++++- arch/sparc/include/uapi/asm/asi.h | 5 + arch/sparc/include/uapi/asm/auxvec.h | 8 + arch/sparc/include/uapi/asm/mman.h | 2 + arch/sparc/include/uapi/asm/pstate.h | 10 ++ arch/sparc/kernel/Makefile | 1 + arch/sparc/kernel/adi_64.c | 93 +++++++++++ arch/sparc/kernel/entry.h | 3 + arch/sparc/kernel/head_64.S | 1 + arch/sparc/kernel/mdesc.c | 4 + arch/sparc/kernel/process_64.c | 21 +++ arch/sparc/kernel/sun4v_mcd.S | 16 ++ arch/sparc/kernel/traps_64.c | 142 +++++++++++++++- arch/sparc/kernel/ttable_64.S | 6 +- arch/sparc/mm/gup.c | 37 ++++ arch/sparc/mm/tlb.c | 28 ++++ arch/x86/kernel/signal_compat.c | 2 +- include/asm-generic/pgtable.h | 5 + include/linux/mm.h | 2 + include/uapi/asm-generic/siginfo.h | 5 +- mm/memory.c | 2 +- mm/rmap.c | 4 +- 33 files changed, 1041 insertions(+), 19 deletions(-) create mode 100644 Documentation/sparc/adi.txt create mode 100644 arch/sparc/include/asm/adi.h create mode 100644 arch/sparc/include/asm/adi_64.h create mode 100644 arch/sparc/kernel/adi_64.c create mode 100644 arch/sparc/kernel/sun4v_mcd.S -- 2.7.4
[toc] | [next] | [standalone]
| From | Khalid Aziz <khalid.aziz@oracle.com> |
|---|---|
| Date | 2017-01-11 17:20 +0100 |
| Subject | [PATCH v4 1/4] signals, sparc: Add signal codes for ADI violations |
| Message-ID | <sYtN0-Fd-31@gated-at.bofh.it> |
| In reply to | #1556683 |
SPARC M7 processor introduces a new feature - Application Data
Integrity (ADI). ADI allows MMU to catch rogue accesses to memory.
When a rogue access occurs, MMU blocks the access and raises an
exception. In response to the exception, kernel sends the offending
task a SIGSEGV with si_code that indicates the nature of exception.
This patch adds three new signal codes specific to ADI feature:
1. ADI is not enabled for the address and task attempted to access
memory using ADI
2. Task attempted to access memory using wrong ADI tag and caused
a deferred exception.
3. Task attempted to access memory using wrong ADI Ttag and caused
a precise exception.
Signed-off-by: Khalid Aziz <khalid.aziz@oracle.com>
Cc: Khalid Aziz <khalid@gonehiking.org>
---
arch/x86/kernel/signal_compat.c | 2 +-
include/uapi/asm-generic/siginfo.h | 5 ++++-
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/arch/x86/kernel/signal_compat.c b/arch/x86/kernel/signal_compat.c
index ec1f756..d1e860c 100644
--- a/arch/x86/kernel/signal_compat.c
+++ b/arch/x86/kernel/signal_compat.c
@@ -26,7 +26,7 @@ static inline void signal_compat_build_tests(void)
*/
BUILD_BUG_ON(NSIGILL != 8);
BUILD_BUG_ON(NSIGFPE != 8);
- BUILD_BUG_ON(NSIGSEGV != 4);
+ BUILD_BUG_ON(NSIGSEGV != 7);
BUILD_BUG_ON(NSIGBUS != 5);
BUILD_BUG_ON(NSIGTRAP != 4);
BUILD_BUG_ON(NSIGCHLD != 6);
diff --git a/include/uapi/asm-generic/siginfo.h b/include/uapi/asm-generic/siginfo.h
index 1abaf62..2446864 100644
--- a/include/uapi/asm-generic/siginfo.h
+++ b/include/uapi/asm-generic/siginfo.h
@@ -213,7 +213,10 @@ typedef struct siginfo {
#define SEGV_ACCERR (__SI_FAULT|2) /* invalid permissions for mapped object */
#define SEGV_BNDERR (__SI_FAULT|3) /* failed address bound checks */
#define SEGV_PKUERR (__SI_FAULT|4) /* failed protection key checks */
-#define NSIGSEGV 4
+#define SEGV_ACCADI (__SI_FAULT|5) /* ADI not enabled for mapped object */
+#define SEGV_ADIDERR (__SI_FAULT|6) /* Disrupting MCD error */
+#define SEGV_ADIPERR (__SI_FAULT|7) /* Precise MCD exception */
+#define NSIGSEGV 7
/*
* SIGBUS si_codes
--
2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Dave Hansen <dave.hansen@linux.intel.com> |
|---|---|
| Date | 2017-01-11 17:40 +0100 |
| Subject | Re: [PATCH v4 0/4] Application Data Integrity feature introduced by SPARC M7 |
| Message-ID | <sYu6l-Lo-1@gated-at.bofh.it> |
| In reply to | #1556683 |
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.
[toc] | [prev] | [next] | [standalone]
| From | Khalid Aziz <khalid.aziz@oracle.com> |
|---|---|
| Date | 2017-01-11 18:00 +0100 |
| Subject | Re: [PATCH v4 0/4] Application Data Integrity feature introduced by SPARC M7 |
| Message-ID | <sYupI-Sq-29@gated-at.bofh.it> |
| In reply to | #1556699 |
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. 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. > > 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. Hardware resources used to store tags are managed entirely by MMU and invisible to the kernel. Tags are stored in spare bits in memory. The only tag resource consumption visible to OS will be the space it allocates to store tags as pages are swapped in/out or migrated. If we choose to implement subpage granularity for tags in future, resource consumption will be a concern. You are right, each n pages of tagged memory requires n/128 pages to store tags. Since each tag is just 4 bits, there are good possibilities to compress this data but that is for future. Thanks, Khalid
[toc] | [prev] | [next] | [standalone]
| From | Dave Hansen <dave.hansen@linux.intel.com> |
|---|---|
| Date | 2017-01-11 19:20 +0100 |
| Subject | Re: [PATCH v4 0/4] Application Data Integrity feature introduced by SPARC M7 |
| Message-ID | <sYvF8-1NE-23@gated-at.bofh.it> |
| In reply to | #1556723 |
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?
[toc] | [prev] | [next] | [standalone]
| From | Khalid Aziz <khalid.aziz@oracle.com> |
|---|---|
| Date | 2017-01-11 20:00 +0100 |
| Subject | Re: [PATCH v4 0/4] Application Data Integrity feature introduced by SPARC M7 |
| Message-ID | <sYwhQ-21a-31@gated-at.bofh.it> |
| In reply to | #1556807 |
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
[toc] | [prev] | [next] | [standalone]
| From | Dave Hansen <dave.hansen@linux.intel.com> |
|---|---|
| Date | 2017-01-11 20:20 +0100 |
| Subject | Re: [PATCH v4 0/4] Application Data Integrity feature introduced by SPARC M7 |
| Message-ID | <sYwBe-2p2-129@gated-at.bofh.it> |
| In reply to | #1556845 |
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.
[toc] | [prev] | [next] | [standalone]
| From | Khalid Aziz <khalid.aziz@oracle.com> |
|---|---|
| Date | 2017-01-12 01:30 +0100 |
| Subject | Re: [PATCH v4 0/4] Application Data Integrity feature introduced by SPARC M7 |
| Message-ID | <sYBrc-5sK-19@gated-at.bofh.it> |
| In reply to | #1556857 |
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
[toc] | [prev] | [next] | [standalone]
| From | Dave Hansen <dave.hansen@linux.intel.com> |
|---|---|
| Date | 2017-01-12 01:50 +0100 |
| Subject | Re: [PATCH v4 0/4] Application Data Integrity feature introduced by SPARC M7 |
| Message-ID | <sYBKx-5yS-7@gated-at.bofh.it> |
| In reply to | #1557025 |
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.
[toc] | [prev] | [next] | [standalone]
| From | Khalid Aziz <khalid.aziz@oracle.com> |
|---|---|
| Date | 2017-01-12 18:00 +0100 |
| Subject | Re: [PATCH v4 0/4] Application Data Integrity feature introduced by SPARC M7 |
| Message-ID | <sYQTf-6jV-9@gated-at.bofh.it> |
| In reply to | #1557035 |
On 01/11/2017 05:49 PM, Dave Hansen wrote: > 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. Hi Dave, You have brought up an interesting scenario with COW pages. I had started out with the following policies regarding ADI that made sense: 1. New data pages do not get full ADI protection by default, i.e. TTE.mcd is not set and tags are not set on the new pages. A task that creates a new data page must make decision to protect these new pages or not. 2. Any shared page that has ADI protection enabled on it, must stay ADI protected across all processes sharing it. 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. It is also a copy of what was ADI protected data, so should it inherit the protection instead? 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 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? Thanks, Khalid
[toc] | [prev] | [next] | [standalone]
| From | Dave Hansen <dave.hansen@linux.intel.com> |
|---|---|
| Date | 2017-01-12 19:00 +0100 |
| Subject | Re: [PATCH v4 0/4] Application Data Integrity feature introduced by SPARC M7 |
| Message-ID | <sYRPj-6SY-11@gated-at.bofh.it> |
| In reply to | #1557610 |
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.
[toc] | [prev] | [next] | [standalone]
| From | Khalid Aziz <khalid.aziz@oracle.com> |
|---|---|
| Date | 2017-01-13 01:30 +0100 |
| Subject | Re: [PATCH v4 0/4] Application Data Integrity feature introduced by SPARC M7 |
| Message-ID | <sYXUK-2kB-5@gated-at.bofh.it> |
| In reply to | #1557669 |
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
[toc] | [prev] | [next] | [standalone]
| From | Rob Gardner <rob.gardner@oracle.com> |
|---|---|
| Date | 2017-01-13 02:40 +0100 |
| Subject | Re: [PATCH v4 0/4] Application Data Integrity feature introduced by SPARC M7 |
| Message-ID | <sYZ0u-2Wc-1@gated-at.bofh.it> |
| In reply to | #1557928 |
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?
[toc] | [prev] | [next] | [standalone]
| From | Khalid Aziz <khalid.aziz@oracle.com> |
|---|---|
| Date | 2017-01-13 15:50 +0100 |
| Subject | Re: [PATCH v4 0/4] Application Data Integrity feature introduced by SPARC M7 |
| Message-ID | <sZbl0-23t-19@gated-at.bofh.it> |
| In reply to | #1557951 |
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 majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html
[toc] | [prev] | [next] | [standalone]
| From | Rob Gardner <rob.gardner@oracle.com> |
|---|---|
| Date | 2017-01-13 16:40 +0100 |
| Subject | Re: [PATCH v4 0/4] Application Data Integrity feature introduced by SPARC M7 |
| Message-ID | <sZc7u-2zn-47@gated-at.bofh.it> |
| In reply to | #1558441 |
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? 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. 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 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 majordomo@vger.kernel.org >> More majordomo info at http://vger.kernel.org/majordomo-info.html >
[toc] | [prev] | [next] | [standalone]
| From | Dave Hansen <dave.hansen@linux.intel.com> |
|---|---|
| Date | 2017-01-13 17:10 +0100 |
| Subject | Re: [PATCH v4 0/4] Application Data Integrity feature introduced by SPARC M7 |
| Message-ID | <sZcAq-2YI-25@gated-at.bofh.it> |
| In reply to | #1558505 |
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.
[toc] | [prev] | [next] | [standalone]
| From | Rob Gardner <rob.gardner@oracle.com> |
|---|---|
| Date | 2017-01-13 18:40 +0100 |
| Subject | Re: [PATCH v4 0/4] Application Data Integrity feature introduced by SPARC M7 |
| Message-ID | <sZdZw-3GV-31@gated-at.bofh.it> |
| In reply to | #1558536 |
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
[toc] | [prev] | [next] | [standalone]
| From | Khalid Aziz <khalid.aziz@oracle.com> |
|---|---|
| Date | 2017-01-13 17:10 +0100 |
| Subject | Re: [PATCH v4 0/4] Application Data Integrity feature introduced by SPARC M7 |
| Message-ID | <sZcAr-2YI-57@gated-at.bofh.it> |
| In reply to | #1558505 |
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 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 majordomo@vger.kernel.org >>> More majordomo info at http://vger.kernel.org/majordomo-info.html >> > > -- > To unsubscribe from this list: send the line "unsubscribe sparclinux" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web