All of lore.kernel.org
 help / color / mirror / Atom feed
* [LTP] [PATCH v2] mprotect04: Support execute-only page access permissions
@ 2019-02-12  0:00 Daniel Mentz
  2019-02-19 13:34 ` Li Wang
  2019-02-25  7:39 ` Jan Stancek
  0 siblings, 2 replies; 9+ messages in thread
From: Daniel Mentz @ 2019-02-12  0:00 UTC (permalink / raw)
  To: ltp

Linux version 4.9 introduced support for execute-only page access permissions on
arm64. As a result, user space processes, by default, cannot read from
their own .text sections. This change adds an extra call to mprotect()
to explicitly change access protections to allow relevant parts of the
.text section to be read.

Without this change, mprotect04 generates false TBROK results. We
previously saw this test output:

mprotect04    1  TPASS  :  test PROT_NONE for mprotect success
mprotect04    0  TINFO  :  exec_func: 0x5ac82d3588, page_to_copy: 0x5ac82d3000
mprotect04    2  TBROK  :  ltp/testcases/kernel/syscalls/mprotect/mprotect04.c:236: page_to_copy not present
mprotect04    3  TBROK  :  ltp/testcases/kernel/syscalls/mprotect/mprotect04.c:236: Remaining cases broken

Signed-off-by: Daniel Mentz <danielmentz@google.com>
---

v2: Re-based on Jan's commit ("syscalls/mprotect: align exec_func to 64
bytes")

 .../kernel/syscalls/mprotect/mprotect04.c     | 27 ++++++++++++++++---
 1 file changed, 23 insertions(+), 4 deletions(-)

diff --git a/testcases/kernel/syscalls/mprotect/mprotect04.c b/testcases/kernel/syscalls/mprotect/mprotect04.c
index 0f7890dca..192a0184d 100644
--- a/testcases/kernel/syscalls/mprotect/mprotect04.c
+++ b/testcases/kernel/syscalls/mprotect/mprotect04.c
@@ -227,10 +227,25 @@ static void *get_func(void *mem, uintptr_t *func_page_offset)
 	tst_resm(TINFO, "exec_func: %p, page_to_copy: %p",
 		&exec_func, page_to_copy);
 
-	/* copy 1st page, if it's not present something is wrong */
-	if (!page_present(page_to_copy))
-		tst_brkm(TBROK, cleanup, "page_to_copy not present\n");
-
+	/* Copy 1st page. If it's not accessible, we might be running on a
+	 * platform that supports execute-only page access permissions, in which
+	 * case we have to explicitly change access protections to allow the
+	 * memory to be read. */
+	if (!page_present(page_to_copy)) {
+		TEST(mprotect(page_to_copy, page_sz, PROT_READ | PROT_EXEC));
+		if (TEST_RETURN == -1) {
+			tst_resm(TFAIL | TTERRNO,
+				 "mprotect(PROT_READ|PROT_EXEC) failed");
+			return NULL;
+		}
+		/* If the memory is still not accessible, then something must be
+		 * wrong. */
+		if (!page_present(page_to_copy)) {
+			tst_resm(TINFO, "exec_func: %p, page_to_copy: %p\n",
+				&exec_func, page_to_copy);
+			tst_brkm(TBROK, cleanup, "page_to_copy not present\n");
+		}
+	}
 	memcpy(mem, page_to_copy, page_sz);
 
 	clear_cache(mem_start, page_sz);
@@ -260,6 +275,9 @@ static void testfunc_protexec(void)
 	func = get_func(p, &func_page_offset);
 #endif
 
+	if (!func)
+		goto out;
+
 	if (func_page_offset + 64 >= page_sz) {
 		SAFE_MUNMAP(cleanup, p, page_sz);
 		tst_brkm(TCONF, cleanup, "func too close to page boundary, "
@@ -289,6 +307,7 @@ static void testfunc_protexec(void)
 		}
 	}
 
+out:
 	SAFE_MUNMAP(cleanup, p, page_sz);
 }
 
-- 
2.20.1.791.gb4d0f1c61a-goog


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [LTP] [PATCH v2] mprotect04: Support execute-only page access permissions
  2019-02-12  0:00 [LTP] [PATCH v2] mprotect04: Support execute-only page access permissions Daniel Mentz
@ 2019-02-19 13:34 ` Li Wang
  2019-02-20  0:21   ` Daniel Mentz
  2019-02-25  7:39 ` Jan Stancek
  1 sibling, 1 reply; 9+ messages in thread
From: Li Wang @ 2019-02-19 13:34 UTC (permalink / raw)
  To: ltp

Hi Daniel,

On Tue, Feb 12, 2019 at 8:00 AM Daniel Mentz <danielmentz@google.com> wrote:

> Linux version 4.9 introduced support for execute-only page access
> permissions on
> arm64. As a result, user space processes, by default, cannot read from
> their own .text sections. This change adds an extra call to mprotect()
> to explicitly change access protections to allow relevant parts of the
> .text section to be read.
>
> Without this change, mprotect04 generates false TBROK results. We
> previously saw this test output:
>
> mprotect04    1  TPASS  :  test PROT_NONE for mprotect success
> mprotect04    0  TINFO  :  exec_func: 0x5ac82d3588, page_to_copy:
> 0x5ac82d3000
> mprotect04    2  TBROK  :
> ltp/testcases/kernel/syscalls/mprotect/mprotect04.c:236: page_to_copy not
> present
> mprotect04    3  TBROK  :
> ltp/testcases/kernel/syscalls/mprotect/mprotect04.c:236: Remaining cases
> broken
>
>
I believe your patch make sense, but I can't reproduce that problem on my
aarch64 platform with upstream kernel-v5.0-rc7. Is that execute-only page
permission needs a special config to enable? or can you point me which
commit made the change?

===== without your patch ====
# uname -rm
5.0.0-rc7 aarch64

# ./mprotect04
mprotect04    1  TPASS  :  test PROT_NONE for mprotect success
mprotect04    2  TPASS  :  test PROT_EXEC for mprotect success

I confirmed the '&exec_func == 0x403460' has READ&EXEC permission in the
.text section. Or, did I missed anything?

00400000-00420000 r-xp 00000000 fd:00 101414360
/root/ltp/testcases/kernel/syscalls/mprotect/mprotect04
00420000-00430000 r--p 00010000 fd:00 101414360
/root/ltp/testcases/kernel/syscalls/mprotect/mprotect04
00430000-00440000 rw-p 00020000 fd:00 101414360
/root/ltp/testcases/kernel/syscalls/mprotect/mprotect04
2ff00000-2ff30000 rw-p 00000000 00:00 0
[heap]
ffff86b00000-ffff86b20000 --xp 00000000 00:00 0
ffff86b20000-ffff86c80000 r-xp 00000000 fd:00 1164
 /usr/lib64/libc-2.28.so
ffff86c80000-ffff86c90000 r--p 00150000 fd:00 1164
 /usr/lib64/libc-2.28.so
ffff86c90000-ffff86ca0000 rw-p 00160000 fd:00 1164
 /usr/lib64/libc-2.28.so
ffff86cb0000-ffff86cc0000 r--p 00000000 00:00 0
[vvar]
ffff86cc0000-ffff86cd0000 r-xp 00000000 00:00 0
[vdso]
ffff86cd0000-ffff86cf0000 r-xp 00000000 fd:00 1157
 /usr/lib64/ld-2.28.so
ffff86cf0000-ffff86d00000 r--p 00010000 fd:00 1157
 /usr/lib64/ld-2.28.so
ffff86d00000-ffff86d10000 rw-p 00020000 fd:00 1157
 /usr/lib64/ld-2.28.so
ffffed310000-ffffed340000 rw-p 00000000 00:00 0
[stack]

-- 
Regards,
Li Wang
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.linux.it/pipermail/ltp/attachments/20190219/44ca0d04/attachment.html>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [LTP] [PATCH v2] mprotect04: Support execute-only page access permissions
  2019-02-19 13:34 ` Li Wang
@ 2019-02-20  0:21   ` Daniel Mentz
  2019-02-20  7:59     ` Li Wang
  0 siblings, 1 reply; 9+ messages in thread
From: Daniel Mentz @ 2019-02-20  0:21 UTC (permalink / raw)
  To: ltp

Hi Li,

No, execute-only page access permissions don't need any special
configuration. They have been introduced by the following commit:

"arm64: Introduce execute-only page access permissions"
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=cab15ce604e550020bb7115b779013b91bcdbc21

/proc//maps for my mprotect04 executable looks as follows:

6458f5e000-6458f62000 r--p 00000000 fd:06 11691
/data/local/tmp/mprotect04
6458f62000-6458f67000 --xp 00004000 fd:06 11691
/data/local/tmp/mprotect04
6458f67000-6458f6a000 rw-p 00009000 fd:06 11691
/data/local/tmp/mprotect04
6458f6a000-6458f6d000 rw-p 00000000 00:00 0
70c5cc0000-70c5d11000 ---p 00000000 00:00 0

The notable difference are the access permissions of the second VMA which
are "--xp". In your case, the permissions were "r-xp", hence reading was
allowed in addition to execution. I should also note that most other
binaries on my device like /system/bin/sh don't have the execute-only
mapping "--xp". Instead, they only have an "r-xp" VMA like your mprotect04.
In the end, I couldn't find out why there's a difference. Objdump and
readelf both show that the respective segment is execute-only, but it's
somehow still mapped readable and executable:

# head /proc/$$/maps
5cf18f9000-5cf1903000 r--p 00000000 fd:03 3361
 /system/bin/sh
5cf1903000-5cf193e000 r-xp 0000a000 fd:03 3361
 /system/bin/sh
5cf193e000-5cf193f000 rw-p 00045000 fd:03 3361
 /system/bin/sh
5cf193f000-5cf1941000 r--p 00046000 fd:03 3361
 /system/bin/sh

I should also mention that we compiled mprotect04 with clang instead of
gcc. Maybe that makes a difference.
We are using an Android kernel based on Linux 4.9.153

Daniel

On Tue, Feb 19, 2019 at 5:34 AM Li Wang <liwang@redhat.com> wrote:

> Hi Daniel,
>
> On Tue, Feb 12, 2019 at 8:00 AM Daniel Mentz <danielmentz@google.com>
> wrote:
>
>> Linux version 4.9 introduced support for execute-only page access
>> permissions on
>> arm64. As a result, user space processes, by default, cannot read from
>> their own .text sections. This change adds an extra call to mprotect()
>> to explicitly change access protections to allow relevant parts of the
>> .text section to be read.
>>
>> Without this change, mprotect04 generates false TBROK results. We
>> previously saw this test output:
>>
>> mprotect04    1  TPASS  :  test PROT_NONE for mprotect success
>> mprotect04    0  TINFO  :  exec_func: 0x5ac82d3588, page_to_copy:
>> 0x5ac82d3000
>> mprotect04    2  TBROK  :
>> ltp/testcases/kernel/syscalls/mprotect/mprotect04.c:236: page_to_copy not
>> present
>> mprotect04    3  TBROK  :
>> ltp/testcases/kernel/syscalls/mprotect/mprotect04.c:236: Remaining cases
>> broken
>>
>>
> I believe your patch make sense, but I can't reproduce that problem on my
> aarch64 platform with upstream kernel-v5.0-rc7. Is that execute-only page
> permission needs a special config to enable? or can you point me which
> commit made the change?
>
> ===== without your patch ====
> # uname -rm
> 5.0.0-rc7 aarch64
>
> # ./mprotect04
> mprotect04    1  TPASS  :  test PROT_NONE for mprotect success
> mprotect04    2  TPASS  :  test PROT_EXEC for mprotect success
>
> I confirmed the '&exec_func == 0x403460' has READ&EXEC permission in the
> .text section. Or, did I missed anything?
>
> 00400000-00420000 r-xp 00000000 fd:00 101414360
> /root/ltp/testcases/kernel/syscalls/mprotect/mprotect04
> 00420000-00430000 r--p 00010000 fd:00 101414360
> /root/ltp/testcases/kernel/syscalls/mprotect/mprotect04
> 00430000-00440000 rw-p 00020000 fd:00 101414360
> /root/ltp/testcases/kernel/syscalls/mprotect/mprotect04
> 2ff00000-2ff30000 rw-p 00000000 00:00 0
> [heap]
> ffff86b00000-ffff86b20000 --xp 00000000 00:00 0
> ffff86b20000-ffff86c80000 r-xp 00000000 fd:00 1164
>  /usr/lib64/libc-2.28.so
> ffff86c80000-ffff86c90000 r--p 00150000 fd:00 1164
>  /usr/lib64/libc-2.28.so
> ffff86c90000-ffff86ca0000 rw-p 00160000 fd:00 1164
>  /usr/lib64/libc-2.28.so
> ffff86cb0000-ffff86cc0000 r--p 00000000 00:00 0
> [vvar]
> ffff86cc0000-ffff86cd0000 r-xp 00000000 00:00 0
> [vdso]
> ffff86cd0000-ffff86cf0000 r-xp 00000000 fd:00 1157
>  /usr/lib64/ld-2.28.so
> ffff86cf0000-ffff86d00000 r--p 00010000 fd:00 1157
>  /usr/lib64/ld-2.28.so
> ffff86d00000-ffff86d10000 rw-p 00020000 fd:00 1157
>  /usr/lib64/ld-2.28.so
> ffffed310000-ffffed340000 rw-p 00000000 00:00 0
> [stack]
>
> --
> Regards,
> Li Wang
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.linux.it/pipermail/ltp/attachments/20190219/3168a8e2/attachment.html>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [LTP] [PATCH v2] mprotect04: Support execute-only page access permissions
  2019-02-20  0:21   ` Daniel Mentz
@ 2019-02-20  7:59     ` Li Wang
  2019-02-21 15:01       ` Will Deacon
  0 siblings, 1 reply; 9+ messages in thread
From: Li Wang @ 2019-02-20  7:59 UTC (permalink / raw)
  To: ltp

On Wed, Feb 20, 2019 at 8:21 AM Daniel Mentz <danielmentz@google.com> wrote:

> Hi Li,
>
> No, execute-only page access permissions don't need any special
> configuration. They have been introduced by the following commit:
>
> "arm64: Introduce execute-only page access permissions"
>
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=cab15ce604e550020bb7115b779013b91bcdbc21
>
> /proc//maps for my mprotect04 executable looks as follows:
>
> 6458f5e000-6458f62000 r--p 00000000 fd:06 11691
> /data/local/tmp/mprotect04
> 6458f62000-6458f67000 --xp 00004000 fd:06 11691
> /data/local/tmp/mprotect04
> 6458f67000-6458f6a000 rw-p 00009000 fd:06 11691
> /data/local/tmp/mprotect04
> 6458f6a000-6458f6d000 rw-p 00000000 00:00 0
> 70c5cc0000-70c5d11000 ---p 00000000 00:00 0
>
> The notable difference are the access permissions of the second VMA which
> are "--xp". In your case, the permissions were "r-xp", hence reading was
> allowed in addition to execution. I should also note that most other
> binaries on my device like /system/bin/sh don't have the execute-only
> mapping "--xp". Instead, they only have an "r-xp" VMA like your mprotect04.
> In the end, I couldn't find out why there's a difference. Objdump and
> readelf both show that the respective segment is execute-only, but it's
> somehow still mapped readable and executable:
>

Not sure if that's a issue or intentional in design, Cc'ing Deacon and Catalin
to have look.


>
> # head /proc/$$/maps
> 5cf18f9000-5cf1903000 r--p 00000000 fd:03 3361
>  /system/bin/sh
> 5cf1903000-5cf193e000 r-xp 0000a000 fd:03 3361
>  /system/bin/sh
> 5cf193e000-5cf193f000 rw-p 00045000 fd:03 3361
>  /system/bin/sh
> 5cf193f000-5cf1941000 r--p 00046000 fd:03 3361
>  /system/bin/sh
>
> I should also mention that we compiled mprotect04 with clang instead of
> gcc. Maybe that makes a difference.
> We are using an Android kernel based on Linux 4.9.153
>
> Daniel
>
> On Tue, Feb 19, 2019 at 5:34 AM Li Wang <liwang@redhat.com> wrote:
>
>> Hi Daniel,
>>
>> On Tue, Feb 12, 2019 at 8:00 AM Daniel Mentz <danielmentz@google.com>
>> wrote:
>>
>>> Linux version 4.9 introduced support for execute-only page access
>>> permissions on
>>> arm64. As a result, user space processes, by default, cannot read from
>>> their own .text sections. This change adds an extra call to mprotect()
>>> to explicitly change access protections to allow relevant parts of the
>>> .text section to be read.
>>>
>>> Without this change, mprotect04 generates false TBROK results. We
>>> previously saw this test output:
>>>
>>> mprotect04    1  TPASS  :  test PROT_NONE for mprotect success
>>> mprotect04    0  TINFO  :  exec_func: 0x5ac82d3588, page_to_copy:
>>> 0x5ac82d3000
>>> mprotect04    2  TBROK  :
>>> ltp/testcases/kernel/syscalls/mprotect/mprotect04.c:236: page_to_copy not
>>> present
>>> mprotect04    3  TBROK  :
>>> ltp/testcases/kernel/syscalls/mprotect/mprotect04.c:236: Remaining cases
>>> broken
>>>
>>>
>> I believe your patch make sense, but I can't reproduce that problem on my
>> aarch64 platform with upstream kernel-v5.0-rc7. Is that execute-only page
>> permission needs a special config to enable? or can you point me which
>> commit made the change?
>>
>> ===== without your patch ====
>> # uname -rm
>> 5.0.0-rc7 aarch64
>>
>> # ./mprotect04
>> mprotect04    1  TPASS  :  test PROT_NONE for mprotect success
>> mprotect04    2  TPASS  :  test PROT_EXEC for mprotect success
>>
>> I confirmed the '&exec_func == 0x403460' has READ&EXEC permission in the
>> .text section. Or, did I missed anything?
>>
>> 00400000-00420000 r-xp 00000000 fd:00 101414360
>> /root/ltp/testcases/kernel/syscalls/mprotect/mprotect04
>> 00420000-00430000 r--p 00010000 fd:00 101414360
>> /root/ltp/testcases/kernel/syscalls/mprotect/mprotect04
>> 00430000-00440000 rw-p 00020000 fd:00 101414360
>> /root/ltp/testcases/kernel/syscalls/mprotect/mprotect04
>> 2ff00000-2ff30000 rw-p 00000000 00:00 0
>> [heap]
>> ffff86b00000-ffff86b20000 --xp 00000000 00:00 0
>> ffff86b20000-ffff86c80000 r-xp 00000000 fd:00 1164
>>  /usr/lib64/libc-2.28.so
>> ffff86c80000-ffff86c90000 r--p 00150000 fd:00 1164
>>  /usr/lib64/libc-2.28.so
>> ffff86c90000-ffff86ca0000 rw-p 00160000 fd:00 1164
>>  /usr/lib64/libc-2.28.so
>> ffff86cb0000-ffff86cc0000 r--p 00000000 00:00 0
>> [vvar]
>> ffff86cc0000-ffff86cd0000 r-xp 00000000 00:00 0
>> [vdso]
>> ffff86cd0000-ffff86cf0000 r-xp 00000000 fd:00 1157
>>  /usr/lib64/ld-2.28.so
>> ffff86cf0000-ffff86d00000 r--p 00010000 fd:00 1157
>>  /usr/lib64/ld-2.28.so
>> ffff86d00000-ffff86d10000 rw-p 00020000 fd:00 1157
>>  /usr/lib64/ld-2.28.so
>> ffffed310000-ffffed340000 rw-p 00000000 00:00 0
>> [stack]
>>
>> --
>> Regards,
>> Li Wang
>>
>

-- 
Regards,
Li Wang
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.linux.it/pipermail/ltp/attachments/20190220/de609c58/attachment.html>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [LTP] [PATCH v2] mprotect04: Support execute-only page access permissions
  2019-02-20  7:59     ` Li Wang
@ 2019-02-21 15:01       ` Will Deacon
  2019-02-21 20:43         ` Daniel Mentz
  0 siblings, 1 reply; 9+ messages in thread
From: Will Deacon @ 2019-02-21 15:01 UTC (permalink / raw)
  To: ltp

On Wed, Feb 20, 2019 at 03:59:57PM +0800, Li Wang wrote:
> On Wed, Feb 20, 2019 at 8:21 AM Daniel Mentz <danielmentz@google.com> wrote:
>     No, execute-only page access permissions don't need any special
>     configuration. They have been introduced by the following commit:
> 
>     "arm64: Introduce execute-only page access permissions"
>     https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?
>     id=cab15ce604e550020bb7115b779013b91bcdbc21
> 
>     /proc//maps for my mprotect04 executable looks as follows:
> 
>     6458f5e000-6458f62000 r--p 00000000 fd:06 11691                          /
>     data/local/tmp/mprotect04
>     6458f62000-6458f67000 --xp 00004000 fd:06 11691                          /
>     data/local/tmp/mprotect04
>     6458f67000-6458f6a000 rw-p 00009000 fd:06 11691                          /
>     data/local/tmp/mprotect04
>     6458f6a000-6458f6d000 rw-p 00000000 00:00 0 
>     70c5cc0000-70c5d11000 ---p 00000000 00:00 0 
> 
>     The notable difference are the access permissions of the second VMA which
>     are "--xp". In your case, the permissions were "r-xp", hence reading was
>     allowed in addition to execution. I should also note that most other
>     binaries on my device like /system/bin/sh don't have the execute-only
>     mapping "--xp". Instead, they only have an "r-xp" VMA like your mprotect04.
>     In the end, I couldn't find out why there's a difference. Objdump and
>     readelf both show that the respective segment is execute-only, but it's
>     somehow still mapped readable and executable:
> 
> 
> Not sure if that's a issue or intentional in design, Cc'ing Deacon and Catalin
> to have look.

I suspect this depends on the flags that are emitted in the program header
by your compiler. What does objdump -p say for your binary?

Will

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [LTP] [PATCH v2] mprotect04: Support execute-only page access permissions
  2019-02-21 15:01       ` Will Deacon
@ 2019-02-21 20:43         ` Daniel Mentz
  2019-02-22  3:13           ` Li Wang
  0 siblings, 1 reply; 9+ messages in thread
From: Daniel Mentz @ 2019-02-21 20:43 UTC (permalink / raw)
  To: ltp

On Thu, Feb 21, 2019 at 7:01 AM Will Deacon <will.deacon@arm.com> wrote:

> On Wed, Feb 20, 2019 at 03:59:57PM +0800, Li Wang wrote:
> > On Wed, Feb 20, 2019 at 8:21 AM Daniel Mentz <danielmentz@google.com>
> wrote:
> >     No, execute-only page access permissions don't need any special
> >     configuration. They have been introduced by the following commit:
> >
> >     "arm64: Introduce execute-only page access permissions"
> >
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/
> ?
> >     id=cab15ce604e550020bb7115b779013b91bcdbc21
> >
> >     /proc//maps for my mprotect04 executable looks as follows:
> >
> >     6458f5e000-6458f62000 r--p 00000000 fd:06 11691
>     /
> >     data/local/tmp/mprotect04
> >     6458f62000-6458f67000 --xp 00004000 fd:06 11691
>     /
> >     data/local/tmp/mprotect04
> >     6458f67000-6458f6a000 rw-p 00009000 fd:06 11691
>     /
> >     data/local/tmp/mprotect04
> >     6458f6a000-6458f6d000 rw-p 00000000 00:00 0
> >     70c5cc0000-70c5d11000 ---p 00000000 00:00 0
> >
> >     The notable difference are the access permissions of the second VMA
> which
> >     are "--xp". In your case, the permissions were "r-xp", hence reading
> was
> >     allowed in addition to execution. I should also note that most other
> >     binaries on my device like /system/bin/sh don't have the execute-only
> >     mapping "--xp". Instead, they only have an "r-xp" VMA like your
> mprotect04.
> >     In the end, I couldn't find out why there's a difference. Objdump and
> >     readelf both show that the respective segment is execute-only, but
> it's
> >     somehow still mapped readable and executable:
> >
> >
> > Not sure if that's a issue or intentional in design, Cc'ing Deacon and
> Catalin
> > to have look.
>
> I suspect this depends on the flags that are emitted in the program header
> by your compiler. What does objdump -p say for your binary?
>
>
Not sure if this question was meant for Li or me.
On my system, the objdump output looks as follows:

$ objdump -p out/target/product/crosshatch/system/bin/sh

out/target/product/crosshatch/system/bin/sh:     file format
elf64-littleaarch64

Program Header:
    PHDR off    0x0000000000000040 vaddr 0x0000000000000040 paddr
0x0000000000000040 align 2**3
         filesz 0x0000000000000230 memsz 0x0000000000000230 flags r--
  INTERP off    0x0000000000000270 vaddr 0x0000000000000270 paddr
0x0000000000000270 align 2**0
         filesz 0x0000000000000015 memsz 0x0000000000000015 flags r--
    LOAD off    0x0000000000000000 vaddr 0x0000000000000000 paddr
0x0000000000000000 align 2**12
         filesz 0x0000000000009f94 memsz 0x0000000000009f94 flags r--
    LOAD off    0x000000000000a000 vaddr 0x000000000000a000 paddr
0x000000000000a000 align 2**12
         filesz 0x000000000003a450 memsz 0x000000000003a450 flags --x
    LOAD off    0x0000000000045000 vaddr 0x0000000000045000 paddr
0x0000000000045000 align 2**12
         filesz 0x00000000000025f0 memsz 0x0000000000004cc8 flags rw-
 DYNAMIC off    0x0000000000046e80 vaddr 0x0000000000046e80 paddr
0x0000000000046e80 align 2**3
         filesz 0x0000000000000200 memsz 0x0000000000000200 flags rw-
   RELRO off    0x0000000000046000 vaddr 0x0000000000046000 paddr
0x0000000000046000 align 2**0
         filesz 0x00000000000015f0 memsz 0x0000000000002000 flags r--
EH_FRAME off    0x0000000000005498 vaddr 0x0000000000005498 paddr
0x0000000000005498 align 2**2
         filesz 0x0000000000000d64 memsz 0x0000000000000d64 flags r--
   STACK off    0x0000000000000000 vaddr 0x0000000000000000 paddr
0x0000000000000000 align 2**0
         filesz 0x0000000000000000 memsz 0x0000000000000000 flags rw-
    NOTE off    0x0000000000000288 vaddr 0x0000000000000288 paddr
0x0000000000000288 align 2**2
         filesz 0x0000000000000038 memsz 0x0000000000000038 flags r--

The second "LOAD" segment is defined with "flags --x". After looking at the
kernel source file fs/binfmt_elf.c, my understanding is that this should
translate into a VMA that is mapped execute-only. However, when looking at
/proc//maps, the corresponding VMA is mapped "read and execute". I couldn't
find out why there's a discrepancy. A different binary i.e. mprotect04
looked similar in "objdump -p", but its code segment got indeed mapped
execute-only. I currently don't have the objdump output for that binary,
but I can get it if needed. To conclude, I noticed that ELF segments marked
as "--x" are sometimes mapped execute-only and sometimes read-and-execute.
We are using an Android kernel based on Linux 4.9.153
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.linux.it/pipermail/ltp/attachments/20190221/f501e654/attachment.html>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [LTP] [PATCH v2] mprotect04: Support execute-only page access permissions
  2019-02-21 20:43         ` Daniel Mentz
@ 2019-02-22  3:13           ` Li Wang
  2019-02-22 11:16             ` Will Deacon
  0 siblings, 1 reply; 9+ messages in thread
From: Li Wang @ 2019-02-22  3:13 UTC (permalink / raw)
  To: ltp

On Fri, Feb 22, 2019 at 4:44 AM Daniel Mentz <danielmentz@google.com> wrote:

> On Thu, Feb 21, 2019 at 7:01 AM Will Deacon <will.deacon@arm.com> wrote:
>
>> On Wed, Feb 20, 2019 at 03:59:57PM +0800, Li Wang wrote:
>> > On Wed, Feb 20, 2019 at 8:21 AM Daniel Mentz <danielmentz@google.com>
>> wrote:
>> >     No, execute-only page access permissions don't need any special
>> >     configuration. They have been introduced by the following commit:
>> >
>> >     "arm64: Introduce execute-only page access permissions"
>> >
>> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/
>> ?
>> >     id=cab15ce604e550020bb7115b779013b91bcdbc21
>> >
>> >     /proc//maps for my mprotect04 executable looks as follows:
>> >
>> >     6458f5e000-6458f62000 r--p 00000000 fd:06 11691
>>       /
>> >     data/local/tmp/mprotect04
>> >     6458f62000-6458f67000 --xp 00004000 fd:06 11691
>>       /
>> >     data/local/tmp/mprotect04
>> >     6458f67000-6458f6a000 rw-p 00009000 fd:06 11691
>>       /
>> >     data/local/tmp/mprotect04
>> >     6458f6a000-6458f6d000 rw-p 00000000 00:00 0
>> >     70c5cc0000-70c5d11000 ---p 00000000 00:00 0
>> >
>> >     The notable difference are the access permissions of the second VMA
>> which
>> >     are "--xp". In your case, the permissions were "r-xp", hence
>> reading was
>> >     allowed in addition to execution. I should also note that most other
>> >     binaries on my device like /system/bin/sh don't have the
>> execute-only
>> >     mapping "--xp". Instead, they only have an "r-xp" VMA like your
>> mprotect04.
>> >     In the end, I couldn't find out why there's a difference. Objdump
>> and
>> >     readelf both show that the respective segment is execute-only, but
>> it's
>> >     somehow still mapped readable and executable:
>> >
>> >
>> > Not sure if that's a issue or intentional in design, Cc'ing Deacon and
>> Catalin
>> > to have look.
>>
>> I suspect this depends on the flags that are emitted in the program header
>> by your compiler. What does objdump -p say for your binary?
>>
>
My situation is different with Daniel's, on my aarch64 platform with
upstream kernel-v5.0-rc7, mprotect04 binary code segment has "r-x" flag and
maped as "r-x" permission in VMA, but with the "execute-only page access
permissions" patch shouldn't it map with execute only permission?

# grep CONFIG_ARM64_UAO /boot/config-5.0.0-rc7
CONFIG_ARM64_UAO=y

# lscpu
Architecture:        aarch64
Byte Order:          Little Endian
CPU(s):              32
On-line CPU(s) list: 0-31
Thread(s) per core:  1
Core(s) per socket:  32
Socket(s):           1
NUMA node(s):        1
Vendor ID:           APM
Model:               1
Model name:          X-Gene
Stepping:            0x3
CPU max MHz:         3000.0000
CPU min MHz:         375.0000
BogoMIPS:            100.00
L1d cache:           32K
L1i cache:           32K
L2 cache:            256K
NUMA node0 CPU(s):   0-31
Flags:               fp asimd evtstrm aes pmull sha1 sha2 crc32 cpuid

# gcc -g -O2 -g -O2 -fno-strict-aliasing -pipe -Wall -W
-Wold-style-definition -D_FORTIFY_SOURCE=2 -I../../../../include
-I../../../../include -I../../../../include/old/   -L../../../../lib
mprotect04.c   -lltp -o mprotect04

# objdump -p mprotect04

mprotect04:     file format elf64-littleaarch64

Program Header:
    PHDR off    0x0000000000000040 vaddr 0x0000000000400040 paddr
0x0000000000400040 align 2**3
         filesz 0x00000000000001f8 memsz 0x00000000000001f8 flags r--
  INTERP off    0x0000000000000238 vaddr 0x0000000000400238 paddr
0x0000000000400238 align 2**0
         filesz 0x000000000000001b memsz 0x000000000000001b flags r--
    LOAD off    0x0000000000000000 vaddr 0x0000000000400000 paddr
0x0000000000400000 align 2**16
         filesz 0x000000000001a98c memsz 0x000000000001a98c flags r-x
    LOAD off    0x000000000001fde8 vaddr 0x000000000042fde8 paddr
0x000000000042fde8 align 2**16
         filesz 0x00000000000007fc memsz 0x0000000000003858 flags rw-
 DYNAMIC off    0x000000000001fdf8 vaddr 0x000000000042fdf8 paddr
0x000000000042fdf8 align 2**3
         filesz 0x00000000000001d0 memsz 0x00000000000001d0 flags rw-
    NOTE off    0x0000000000000254 vaddr 0x0000000000400254 paddr
0x0000000000400254 align 2**2
         filesz 0x0000000000000044 memsz 0x0000000000000044 flags r--
EH_FRAME off    0x00000000000171b0 vaddr 0x00000000004171b0 paddr
0x00000000004171b0 align 2**2
         filesz 0x00000000000006d4 memsz 0x00000000000006d4 flags r--
   STACK off    0x0000000000000000 vaddr 0x0000000000000000 paddr
0x0000000000000000 align 2**4
         filesz 0x0000000000000000 memsz 0x0000000000000000 flags rw-
   RELRO off    0x000000000001fde8 vaddr 0x000000000042fde8 paddr
0x000000000042fde8 align 2**0
         filesz 0x0000000000000218 memsz 0x0000000000000218 flags r--

>
>>
> Not sure if this question was meant for Li or me.
> On my system, the objdump output looks as follows:
>
> $ objdump -p out/target/product/crosshatch/system/bin/sh
>
> out/target/product/crosshatch/system/bin/sh:     file format
> elf64-littleaarch64
>
> Program Header:
>     PHDR off    0x0000000000000040 vaddr 0x0000000000000040 paddr
> 0x0000000000000040 align 2**3
>          filesz 0x0000000000000230 memsz 0x0000000000000230 flags r--
>   INTERP off    0x0000000000000270 vaddr 0x0000000000000270 paddr
> 0x0000000000000270 align 2**0
>          filesz 0x0000000000000015 memsz 0x0000000000000015 flags r--
>     LOAD off    0x0000000000000000 vaddr 0x0000000000000000 paddr
> 0x0000000000000000 align 2**12
>          filesz 0x0000000000009f94 memsz 0x0000000000009f94 flags r--
>     LOAD off    0x000000000000a000 vaddr 0x000000000000a000 paddr
> 0x000000000000a000 align 2**12
>          filesz 0x000000000003a450 memsz 0x000000000003a450 flags --x
>     LOAD off    0x0000000000045000 vaddr 0x0000000000045000 paddr
> 0x0000000000045000 align 2**12
>          filesz 0x00000000000025f0 memsz 0x0000000000004cc8 flags rw-
>  DYNAMIC off    0x0000000000046e80 vaddr 0x0000000000046e80 paddr
> 0x0000000000046e80 align 2**3
>          filesz 0x0000000000000200 memsz 0x0000000000000200 flags rw-
>    RELRO off    0x0000000000046000 vaddr 0x0000000000046000 paddr
> 0x0000000000046000 align 2**0
>          filesz 0x00000000000015f0 memsz 0x0000000000002000 flags r--
> EH_FRAME off    0x0000000000005498 vaddr 0x0000000000005498 paddr
> 0x0000000000005498 align 2**2
>          filesz 0x0000000000000d64 memsz 0x0000000000000d64 flags r--
>    STACK off    0x0000000000000000 vaddr 0x0000000000000000 paddr
> 0x0000000000000000 align 2**0
>          filesz 0x0000000000000000 memsz 0x0000000000000000 flags rw-
>     NOTE off    0x0000000000000288 vaddr 0x0000000000000288 paddr
> 0x0000000000000288 align 2**2
>          filesz 0x0000000000000038 memsz 0x0000000000000038 flags r--
>
> The second "LOAD" segment is defined with "flags --x". After looking at
> the kernel source file fs/binfmt_elf.c, my understanding is that this
> should translate into a VMA that is mapped execute-only. However, when
> looking at /proc//maps, the corresponding VMA is mapped "read and execute".
> I couldn't find out why there's a discrepancy. A different binary i.e.
> mprotect04 looked similar in "objdump -p", but its code segment got indeed
> mapped execute-only. I currently don't have the objdump output for that
> binary, but I can get it if needed. To conclude, I noticed that ELF
> segments marked as "--x" are sometimes mapped execute-only and sometimes
> read-and-execute.
> We are using an Android kernel based on Linux 4.9.153
>

-- 
Regards,
Li Wang
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.linux.it/pipermail/ltp/attachments/20190222/7981f1f0/attachment-0001.html>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [LTP] [PATCH v2] mprotect04: Support execute-only page access permissions
  2019-02-22  3:13           ` Li Wang
@ 2019-02-22 11:16             ` Will Deacon
  0 siblings, 0 replies; 9+ messages in thread
From: Will Deacon @ 2019-02-22 11:16 UTC (permalink / raw)
  To: ltp

On Fri, Feb 22, 2019 at 11:13:06AM +0800, Li Wang wrote:
> On Fri, Feb 22, 2019 at 4:44 AM Daniel Mentz <danielmentz@google.com> wrote:
>     On Thu, Feb 21, 2019 at 7:01 AM Will Deacon <will.deacon@arm.com> wrote:
>         On Wed, Feb 20, 2019 at 03:59:57PM +0800, Li Wang wrote:
>         > On Wed, Feb 20, 2019 at 8:21 AM Daniel Mentz <danielmentz@google.com>
>         wrote:
>         >     No, execute-only page access permissions don't need any special
>         >     configuration. They have been introduced by the following commit:
>         >
>         >     "arm64: Introduce execute-only page access permissions"
>         >     https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/
>         linux.git/commit/?
>         >     id=cab15ce604e550020bb7115b779013b91bcdbc21
>         >
>         >     /proc//maps for my mprotect04 executable looks as follows:
>         >
>         >     6458f5e000-6458f62000 r--p 00000000 fd:06 11691                 
>                 /
>         >     data/local/tmp/mprotect04
>         >     6458f62000-6458f67000 --xp 00004000 fd:06 11691                 
>                 /
>         >     data/local/tmp/mprotect04
>         >     6458f67000-6458f6a000 rw-p 00009000 fd:06 11691                 
>                 /
>         >     data/local/tmp/mprotect04
>         >     6458f6a000-6458f6d000 rw-p 00000000 00:00 0
>         >     70c5cc0000-70c5d11000 ---p 00000000 00:00 0
>         >
>         >     The notable difference are the access permissions of the second
>         VMA which
>         >     are "--xp". In your case, the permissions were "r-xp", hence
>         reading was
>         >     allowed in addition to execution. I should also note that most
>         other
>         >     binaries on my device like /system/bin/sh don't have the
>         execute-only
>         >     mapping "--xp". Instead, they only have an "r-xp" VMA like your
>         mprotect04.
>         >     In the end, I couldn't find out why there's a difference. Objdump
>         and
>         >     readelf both show that the respective segment is execute-only,
>         but it's
>         >     somehow still mapped readable and executable:
>         >
>         >
>         > Not sure if that's a issue or intentional in design, Cc'ing Deacon
>         and Catalin
>         > to have look.
> 
>         I suspect this depends on the flags that are emitted in the program
>         header
>         by your compiler. What does objdump -p say for your binary?
> 
> 
> My situation is different with Daniel's, on my aarch64 platform with upstream
> kernel-v5.0-rc7, mprotect04 binary code segment has "r-x" flag and maped as
> "r-x" permission in VMA, but with the "execute-only page access permissions"
> patch shouldn't it map with execute only permission? 

No; that just means your toolchain isn't emitting an execute-only text
segment, so the kernel is doing the right thing here.

Daniel's case is interesting, and I'm currently not sure what's going on
there. It would be interesting to know if there are differences between
the two binaries relating to things like PIE. I wonder if the dynamic
linker is changing the permissions at runtime.

Will

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [LTP] [PATCH v2] mprotect04: Support execute-only page access permissions
  2019-02-12  0:00 [LTP] [PATCH v2] mprotect04: Support execute-only page access permissions Daniel Mentz
  2019-02-19 13:34 ` Li Wang
@ 2019-02-25  7:39 ` Jan Stancek
  1 sibling, 0 replies; 9+ messages in thread
From: Jan Stancek @ 2019-02-25  7:39 UTC (permalink / raw)
  To: ltp



----- Original Message -----
> Linux version 4.9 introduced support for execute-only page access permissions
> on
> arm64. As a result, user space processes, by default, cannot read from
> their own .text sections. This change adds an extra call to mprotect()
> to explicitly change access protections to allow relevant parts of the
> .text section to be read.
> 
> Without this change, mprotect04 generates false TBROK results. We
> previously saw this test output:
> 
> mprotect04    1  TPASS  :  test PROT_NONE for mprotect success
> mprotect04    0  TINFO  :  exec_func: 0x5ac82d3588, page_to_copy:
> 0x5ac82d3000
> mprotect04    2  TBROK  :
> ltp/testcases/kernel/syscalls/mprotect/mprotect04.c:236: page_to_copy not
> present
> mprotect04    3  TBROK  :
> ltp/testcases/kernel/syscalls/mprotect/mprotect04.c:236: Remaining cases
> broken
> 
> Signed-off-by: Daniel Mentz <danielmentz@google.com>

Pushed with minor tweaks so it applies to my v3.

Thanks,
Jan

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2019-02-25  7:39 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-02-12  0:00 [LTP] [PATCH v2] mprotect04: Support execute-only page access permissions Daniel Mentz
2019-02-19 13:34 ` Li Wang
2019-02-20  0:21   ` Daniel Mentz
2019-02-20  7:59     ` Li Wang
2019-02-21 15:01       ` Will Deacon
2019-02-21 20:43         ` Daniel Mentz
2019-02-22  3:13           ` Li Wang
2019-02-22 11:16             ` Will Deacon
2019-02-25  7:39 ` Jan Stancek

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.