Add memory clobber for writing to the POR_EL0 register since a change
to this register affects subsequent memory accesses.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Several tests rely on a madvise syscall to appear in strace output
(or not appear in case of 'disable' tests). This syscall may occur
in malloc. To avoid this from happening, we use malloc tunable to
disable hugetlb for these tests.
Suggested-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Introduce ifuncs and resolvers for functions pertinent to the
malloc interface on the AArch64 target: malloc, calloc, free,
realloc, memalign, valloc, pvalloc, posix_memalign, aligned_alloc,
free_sized, free_aligned_sized, malloc_usable_size.
A target can define the USE_MULTIARCH_MALLOC macro. In this case
it must provide alternative aliases for the malloc functions that
point to the ifuncs.
This implementation respects the --disable-multi-arch configure
flag. If multi-arch support is disabled, the generic aliases
are used on aarch64.
This patch contains aarch64-specific resolvers. At this point they
return core implementations but in the future they can be changed
to support for features, e.g. to handle memory tagging.
Reviewed-by: Wilco Dijkstra <Wilco.Dijkstra@arm.com>
This commit moves declarations for various malloc functions from
the malloc.c file to a separate header that can be used to include
these declarations in other source files.
No functional change intended.
Reviewed-by: Wilco Dijkstra <Wilco.Dijkstra@arm.com>
Introduce ifuncs and resolvers for functions pertinent to the
malloc interface on the AArch64 target: malloc, calloc, free,
realloc, memalign, valloc, pvalloc, posix_memalign, aligned_alloc,
free_sized, free_aligned_sized, malloc_usable_size.
A target can define the USE_MULTIARCH_MALLOC macro. In this case
it must provide alternative aliases for the malloc functions that
point to the ifuncs.
This implementation respects the --disable-multi-arch configure
flag. If multi-arch support is disabled, the generic aliases
are used on aarch64.
This patch contains aarch64-specific resolvers. At this moment they
return core implementations but in the future they can be changed
to support for features, e.g. to handle memory tagging.
Remove the --enable-memory-tagging configure option along with
all associated variables and macros.
Removing the glibc.mem.tagging tunable.
Remove the memory-tagging makefile variable.
Remove the USE_MTAG macro definition and code that is conditionally
compiled when this macro is defined.
As a result, we change 'mtag_mmap_flags' to 'extra_mmap_prot' that
is now always defined. Change of the name due to this being used
as part of PROT options in mmap syscalls rather than part of flags.
Remove 'mtag_enabled' that would become compile-time false. Also
remove any code that would never be compiled when 'mtag_enabled'
is false.
Remove AArch64-specific code pertinent to memory tagging, that is
currently broken, from the core malloc implementation. We keep
the assembly code, since we are going to need it in the future. to
preserve Git history.
Reviewed-by: Wilco Dijkstra <Wilco.Dijkstra@arm.com>
A couple of small fixes for code readability, no functional change.
- Add missing comments for #endif statements.
- Move inclusion of string.h from malloc.c to calloc-clear-memory.h
where it is actually used.
- Re-order alias definitions for malloc functions.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Some tests use pointers after the associated memory has been freed.
On targets that support memory tagging, using such pointers even
for test purposes might be impossible. To work around this, we add
new function that would allow to clear a pointer in a target-specific
way.
We modify 3 relevant malloc tests: tst-malloc-backtrace, tst-tcfree3,
and tst-safe-linking.
Reviewed-by: Wilco Dijkstra <Wilco.Dijkstra@arm.com>
Use new way of handling test tunables for BTI and GCS tests.
Fix tests that would fail when ambient GLIBC_TUNABLES variable
is used with the aarch64_gcs tunable.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Many tests use Glibc tunables, and the values of the tunables are
provided via the GLIBC_TUNABLES env variable. Tests set it in
makefiles using
tst-foo-ENV = GLIBC_TUNABLES=tunable=value
This overwrites environment for this test, so if another env var is
set elsewhere, one of these changes would be lost. The correct way
should be to append to test's environment:
tst-foo-ENV += GLIBC_TUNABLES=tunable=value
However, if two or more tunables need to be set for the same test,
the 'tunable=value' part should be appended to previously defined
GLIBC_TUNABLES env variable, and it's not easy to achieve this via
existing tools available for tests.
Additionally, there are cases when it is useful to set ambient env
var GLIBC_TUNABLES in order to apply it to most of the tests except
those that require specific tunables. The existing mechanism that
relies on tst-foo-ENV would always override the ambient env var
even when it is not desirable.
To address all of this, in this commit we add support for using
constructs like
tst-foo-TUNABLES += tunable=value
Using this, the test will receive appropriate GLIBC_TUNABLES contents,
and if there is an ambient env var GLIBC_TUNABLES, its value will be
prepended to the env var used by the test. Even if the ambient env var
contains the same tunable that is used by a test, the test's value will
override the ambient value, and the test will be executed correctly.
Additionally, we support cases when tests must have specific value
of the GLIBC_TUNABLES env var (ignoring any ambient value):
tst-foo-TUNABLES-only += tunable=value
The existing mechanism that uses tst-foo-ENV will continue to work,
however if the same test uses both, the new mechanism will override
the old one.
Additional benefit is that the code in makefiles becomes shorter.
We also change tunable handling for malloc tests in this commit.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Some malloc tests compare pointers meaning to compare addresses.
On AArch64, the 64-bit value of the pointer may contain metadata
along with the values of the address.
In order to correctly compare addresses, we add new function for
AArch64 target that will use the AArch64 64 SUBP (subtract pointer)
instruction when it is available. This instruction uses the 56-bit
addresses ignoring top-byte metadata.
Best implementation is selected using ifunc resolver.
On other targets and also on AArch64 when MTE is not available this
function defaults to PTR_DIFF defined in libc-pointer-arith.h.
Three malloc tests are modified accordingly:
- tst-memalign-2.c
- tst-memalign-3.c
- tst-realloc.c
Reviewed-by: Wilco Dijkstra <Wilco.Dijkstra@arm.com>
On some emulated targets sleep may result in inconsistent wait
times which will lead to the failure of the tst-chmod test.
To account for this we use the CLOCK_PROCESS_CPUTIME_ID clock ID
while also consuming CPU time by repeatedly calling clock_gettime.
Reviewed-by: DJ Delorie <dj@redhat.com>
Check that GCS is locked properly based on the value of the
glibc.cpu.aarch64_gcs tunable.
Test tst-gcs-execv checks that a child process can be spawned correctly
when GCS is locked for the parent process.
Test tst-gcs-fork checks that if GCS is not locked for the parent
process, the forked child can disable GCS.
Tests tst-gcs-lock and tst-gcs-lock-static check that GCS is locked
for dynamic and static executables when run with aarch64_gcs=1.
Tests tst-gcs-unlock and tst-gcs-unlock-static check that GCS is not
locked for dynamic and static executables when run with aarch64_gcs=0.
Test tst-gcs-lock-ptrace checks via ptrace that when GCS is locked,
all GCS features are locked.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
If GCS is enabled (see tunable glibc.cpu.aarch64_gcs), we lock all GCS
operations (including status, write on shadow stack, and push to shadow
stack) unless OPTIONAL policy is used.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Some BTI tests in the sysdeps/unix/sysv/linux/aarch64 directory use
test shared objects via dlopen. Due to lack of direct makefile level
dependencies on these modules these tests could be run before the
required .so files would be created. This could lead to flaky test
results when running make check with -j flag. This commit fixes it.
Reviewed-by: Wilco Dijkstra <Wilco.Dijkstra@arm.com>
No functional change. BTI tests check Linux-related functionality
and belong in the linux/aarch64 directory.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Introduce DL_DEBUG_SECURITY mask to enable messages related to
loading modules that lack certain target-dependent hardening
or security features.
Use this mask for warnings related to AArch64 BTI and GCS.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
When either program path of module name is empty, don't print an
empty string followed by a colon.
Also fix-up test for a static BTI binary to check error message
for this case.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
All checks related to the PT_GNU_PROPERTY bits would be skipped
if the binary had no PT_GNU_PROPERTY note at all. This meant that
enforcing an abort when some bits are not present was not possible.
Fixes BZ 33713
Reviewed-by: Wilco Dijkstra <Wilco.Dijkstra@arm.com>
Check that the new tunable changes behaviour correctly:
* When BTI is enforced, any unmarked binary that is loaded
results in an error: either an abort or dlopen error when
this binary is loaded via dlopen.
* When BTI is not enforced, it is OK to load an unmarked
binary.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Add glibc.cpu.aarch64_bti tunable with 2 values:
- permissive (default)
- enforced
and use this tunable to enforce BTI marking on dependencies
when the enforced option is selected.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Tested-by: Jeremy Linton <jeremy.linton@arm.com>
We add configure checks for 3 things:
- Compiler (both CC and TEST_CC) supports -mbranch-protection=bti.
- Linker supports -z force-bti.
- The toolchain supplies object files and target libraries with
the BTI marking.
All three must be true in order for the tests to be valid, so
we check all flags and set the makefile variable accordingly.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Use environment variables to provide mirror URLs to checkout
sources from Git. Each component has a corresponding env var
that will be used if it's present: <component>_GIT_MIRROR.
Note that '<component>' should be upper case, e.g. GLIBC.
Co-authored-by: Carlos O'Donell <carlos@redhat.com>
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
Allow to use custom mirror URLs to download tarballs from a mirror
of ftp.gnu.org using the FTP_GNU_ORG_MIRROR env variable (default
value is 'https://ftp.gnu.org').
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
Test wrapper script was used twice: once to run the test
command and second time within the text command which
seems unnecessary and results in false errors when running
this test.
Fixes 332f8e62af
Reviewed-by: Frédéric Bérat <fberat@redhat.com>
We only need to enable GCS tests on AArch64 targets, however previously
the configure checks for GCS support in compiler and linker were added
for all targets which was not efficient.
To enable tests for GCS we need 4 things to be true:
- Compiler supports GCS branch protection.
- Test compiler supports GCS branch protection.
- Linker supports GCS marking of binaries.
- The CRT objects provided by the toolchain have GCS marking.
To check for the latter, we add new macro to aclocal.m4 that allows to
grep output from readelf.
We check all four and then put the result in one make variable to
simplify checks in makefiles.
Reviewed-by: Wilco Dijkstra <Wilco.Dijkstra@arm.com>
Two tests fail from time to time when a new flag is added for the
p{write,read}v2 functions in a new Linux kernel:
- misc/tst-preadvwritev2
- misc/tst-preadvwritev64v2
This disrupts when testing Glibc on a system with a newer kernel
and it seems we can try improve testing for invalid flags setting
all the bits that are not supposed to be supported (rather than
setting only the next unsupported bit).
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
When building with -Og to enable debugging, there is currently a compiler error
because if __libc_message_wrapper() is not inline, the __va_arg_pack_len macro
cannot be used.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
This commit adds tests for the following use cases relevant to handing of
the SME state:
- fork() and vfork()
- clone() and clone3()
- signal handler
While most cases are trivial, the case of clone3() is more complicated since
the clone3() symbol is not public in Glibc.
To avoid having to check all possible ways clone3() may be called via other
public functions (e.g. vfork() or pthread_create()), we put together a test
that links directly with clone3.o. All the existing functions that have calls
to clone3() may not actually use it, in which case the outcome of such tests
would be unexpected. Having a direct call to the clone3() symbol in the test
allows to check precisely what we need to test: that the __arm_za_disable()
function is indeed called and has the desired effect.
Linking to clone3.o also requires linking to __arm_za_disable.o that in
turn requires the _dl_hwcap2 hidden symbol which to provide in the test
and initialise it before using.
Co-authored-by: Adhemerval Zanella Netto <adhemerval.zanella@linaro.org>
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
This change adds a call to the __arm_za_disable() function immediately
before the SVC instruction inside clone() and clone3() wrappers. It also
adds a macro for inline clone() used in fork() and adds the same call to
the vfork implementation. This sets the ZA state of SME to "off" on return
from these functions (for both the child and the parent).
The __arm_za_disable() function is described in [1] (8.1.3). Note that
the internal Glibc name for this function is __libc_arm_za_disable().
When this change was originally proposed [2,3], it generated a long
discussion where several questions and concerns were raised. Here we
will address these concerns and explain why this change is useful and,
in fact, necessary.
In a nutshell, a C library that conforms to the AAPCS64 spec [1] (pertinent
to this change, mainly, the chapters 6.2 and 6.6), should have a call to the
__arm_za_disable() function in clone() and clone3() wrappers. The following
explains in detail why this is the case.
When we consider using the __arm_za_disable() function inside the clone()
and clone3() libc wrappers, we talk about the C library subroutines clone()
and clone3() rather than the syscalls with similar names. In the current
version of Glibc, clone() is public and clone3() is private, but it being
private is not pertinent to this discussion.
We will begin with stating that this change is NOT a bug fix for something
in the kernel. The requirement to call __arm_za_disable() does NOT come from
the kernel. It also is NOT needed to satisfy a contract between the kernel
and userspace. This is why it is not for the kernel documentation to describe
this requirement. This requirement is instead needed to satisfy a pure userspace
scheme outlined in [1] and to make sure that software that uses Glibc (or any
other C library that has correct handling of SME states (see below)) conforms
to [1] without having to unnecessarily become SME-aware thus losing portability.
To recap (see [1] (6.2)), SME extension defines SME state which is part of
processor state. Part of this SME state is ZA state that is necessary to
manage ZA storage register in the context of the ZA lazy saving scheme [1]
(6.6). This scheme exists because it would be challenging to handle ZA
storage of SME in either callee-saved or caller-saved manner.
There are 3 kinds of ZA state that are defined in terms of the PSTATE.ZA
bit and the TPIDR2_EL0 register (see [1] (6.6.3)):
- "off": PSTATE.ZA == 0
- "active": PSTATE.ZA == 1 TPIDR2_EL0 == null
- "dormant": PSTATE.ZA == 1 TPIDR2_EL0 != null
As [1] (6.7.2) outlines, every subroutine has exactly one SME-interface
depending on the permitted ZA-states on entry and on normal return from
a call to this subroutine. Callers of a subroutine must know and respect
the ZA-interface of the subroutines they are using. Using a subroutine
in a way that is not permitted by its ZA-interface is undefined behaviour.
In particular, clone() and clone3() (the C library functions) have the
ZA-private interface. This means that the permitted ZA-states on entry
are "off" and "dormant" and that the permitted states on return are "off"
or "dormant" (but if and only if it was "dormant" on entry).
This means that both functions in question should correctly handle both
"off" and "dormant" ZA-states on entry. The conforming states on return
are "off" and "dormant" (if inbound state was already "dormant").
This change ensures that the ZA-state on return is always "off". Note,
that, in the context of clone() and clone3(), "on return" means a point
when execution resumes at certain address after transferring from clone()
or clone3(). For the caller (we may refer to it as "parent") this is the
return address in the link register where the RET instruction jumps. For
the "child", this is the target branch address.
So, the "off" state on return is permitted and conformant. Why can't we
retain the "dormant" state? In theory, we can, but we shouldn't, here is
why.
Every subroutine with a private-ZA interface, including clone() and clone3(),
must comply with the lazy saving scheme [1] (6.7.2). This puts additional
responsibility on a subroutine if ZA-state on return is "dormant" because
this state has special meaning. The "caller" (that is the place in code
where execution is transferred to, so this include both "parent" and "child")
may check the ZA-state and use it as per the spec of the "dormant" state that
is outlined in [1] (6.6.6 and 6.6.7).
Conforming to this would require more code inside of clone() and clone3()
which hardly is desirable.
For the return to "parent" this could be achieved in theory, but given that
neither clone() nor clone3() are supposed to be used in the middle of an
SME operation, if wouldn't be useful. For the "return" to "child" this
would be particularly difficult to achieve given the complexity of these
functions and their interfaces. Most importantly, it would be illegal
and somewhat meaningless to allow a "child" to start execution in the
"dormant" ZA-state because the very essence of the "dormant" state implies
that there is a place to return and that there is some outer context that
we are allowed to interact with.
To sum up, calling __arm_za_disable() to ensure the "off" ZA-state when the
execution resumes after a call to clone() or clone3() is correct and also
the most simple way to conform to [1].
Can there be situations when we can avoid calling __arm_za_disable()?
Calling __arm_za_disable() implies certain (sufficiently small) overhead,
so one might rightly ponder avoiding making a call to this function when
we can afford not to. The most trivial cases like this (e.g. when the
calling thread doesn't have access to SME or to the TPIDR2_EL0 register)
are already handled by this function (see [1] (8.1.3 and 8.1.2)). Reasoning
about other possible use cases would require making code inside clone() and
clone3() more complicated and it would defeat the point of trying to make
an optimisation of not calling __arm_za_disable().
Why can't the kernel do this instead?
The handling of SME state by the kernel is described in [4]. In short,
kernel must not impose a specific ZA-interface onto a userspace function.
Interaction with the kernel happens (among other thing) via system calls.
In Glibc many of the system calls (notably, including SYS_clone and
SYS_clone3) are used via wrappers, and the kernel has no control of them
and, moreover, it cannot dictate how these wrappers should behave because
it is simply outside of the kernel's remit.
However, in certain cases, the kernel may ensure that a "child" doesn't
start in an incorrect state. This is what is done by the recent change
included in 6.16 kernel [5]. This is not enough to ensure that code that
uses clone() and clone3() function conforms to [1] when it runs on a
system that provides SME, hence this change.
[1]: https://github.com/ARM-software/abi-aa/blob/main/aapcs64/aapcs64.rst
[2]: https://inbox.sourceware.org/libc-alpha/20250522114828.2291047-1-yury.khrustalev@arm.com
[3]: https://inbox.sourceware.org/libc-alpha/20250609121407.3316070-1-yury.khrustalev@arm.com
[4]: https://www.kernel.org/doc/html/v6.16/arch/arm64/sme.html
[5]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=cde5c32db55740659fca6d56c09b88800d88fd29
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
A common sequence of instructions is used in several places
in assembly files, so define it in one place as an assembly
macro.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
The syscall() function allows to make system calls directly, however,
in the case of system calls that affect internal state of process or
thread, the caller would have to take care of extensive setup necessary
for the internals of Glibc to work correctly in the child threads. This
may make using syscall() with these syscall numbers impractical and
prone to undefined behaviour.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
On some targets using bool in support/check_mem_access.h resulted
in build error due to stdbool.h not being included, fix this.
See 9be489d778 for details.
Reported-by: Joseph Myers <josmyers@redhat.com>
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Add check_mem_access(addr) function to check if memory at addr can
be written or read returning false if memory is not accessible.
This function changes signal handler for SIGSEGV and SIGBUS signals
when it is called first, and it is not thread-safe.
Co-authored-by: Adhemerval Zanella Netto <adhemerval.zanella@linaro.org>
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
There is no functional change in this patch.
We remove stores and loads to stack, return address signing, and redundant
CFI directives before and after call to __libc_arm_za_disable().
The __libc_arm_za_disable implementation follows special calling convention
that allows to avoid most of the operations that would be necessary for a
call to a normal function (see [1] for details).
First, we rely on __libc_arm_za_disable() not clobbering certain registers,
and we put return address into one of these registers. Now we don't need
to store it on stack, so we don't need to sign return address using PAC.
Second, as a result of the above, we don't need to update the CFI offset.
This patch provides small optimisation avoiding unnecessary store and load
on stack also simplifies assembly code and CFI directives.
[1]: https://github.com/ARM-software/abi-aa/blob/main/aapcs64/aapcs64.rst
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
No functional change here, just a small refactoring to simplify
using __alloc_gcs() for allocating shadow stacks.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Add a new helper function __ifunc_hwcap() as a portable way to
access HWCAP elements via the parameter(s) passed to an ifunc
resolver checking the _IFUNC_ARG_HWCAP bit in the first parameter
and size of the buffer in the second parameter.
Note that 0 is returned when the requested element is not available
or does not correspond to a valid AT_HWCAP{,2,...} value.
Also add relevant tests.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Add basic support for hwcap3 and hwcap4 in dynamic loader and
ifunc resolvers.
Describe new backward-compatible prototype for GNU indirect
function resolvers that use a pointer to uint64_t array in
stead of a pointer to the __ifunc_arg_t struct.
This patch also adds macro _IFUNC_HWCAP_MAX to specify current
number of hwcap elements.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Add test that checks that ZA state is disabled after setjmp and sigsetjmp
Update existing SME test that uses setjmp
Reviewed-by: Wilco Dijkstra <Wilco.Dijkstra@arm.com>
Due to the nature of the ZA state, setjmp() should clear it in the
same manner as it is already done by longjmp.
Reviewed-by: Wilco Dijkstra <Wilco.Dijkstra@arm.com>
Previously, longjmp() on aarch64 was using CFI directives around the
call to __libc_arm_za_disable() after CFA was redefined at the start
of longjmp(). This may result in unwinding issues. Move the call and
surrounding CFI directives to the beginning of longjmp().
Suggested-by: Wilco Dijkstra <wilco.dijkstra@arm.com>
Test that when we return from a function that enabled GCS at runtime
we get SIGSEGV. Also test that ucontext contains GCS block with the
GCS pointer.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
These tests validate that GCS tunable works as expected depending
on the GCS markings in the test binaries.
Tests validate both static and dynamically linked binaries.
These new tests are AArch64 specific. Moreover, they are included only
if linker supports the "-z gcs=<value>" option. If built, these tests
will run on systems with and without HWCAP_GCS. In the latter case the
tests will be reported as UNSUPPORTED.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
- Add check that linker supports -z gcs=...
- Add checks that main and test compiler support
-mbranch-protection=gcs
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
- Add GCS marking to some of the tests when target supports GCS
- Fix tst-ro-dynamic-mod.map linker script to avoid removing
GNU properties
- Add header with macros for GNU properties
Reviewed-by: Wilco Dijkstra <Wilco.Dijkstra@arm.com>
Describe AArch64 specific flags PKEY_DISABLE_READ and PKEY_DISABLE_EXECUTE that
are available on AArch64 systems with enabled Stage 1 permission overlays
feature introduced in Armv8.9 / 9.4 (FEAT_S1POE).
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
This patch adds support for memory protection keys on AArch64 systems with
enabled Stage 1 permission overlays feature introduced in Armv8.9 / 9.4
(FEAT_S1POE) [1].
1. Internal functions "pkey_read" and "pkey_write" to access data
associated with memory protection keys.
2. Implementation of API functions "pkey_get" and "pkey_set" for
the AArch64 target.
3. AArch64-specific PKEY flags for READ and EXECUTE (see below).
4. New target-specific test that checks behaviour of pkeys on
AArch64 targets.
5. This patch also extends existing generic test for pkeys.
6. HWCAP constant for Permission Overlay Extension feature.
To support more accurate mapping of underlying permissions to the
PKEY flags, we introduce additional AArch64-specific flags. The full
list of flags is:
- PKEY_UNRESTRICTED: 0x0 (for completeness)
- PKEY_DISABLE_ACCESS: 0x1 (existing flag)
- PKEY_DISABLE_WRITE: 0x2 (existing flag)
- PKEY_DISABLE_EXECUTE: 0x4 (new flag, AArch64 specific)
- PKEY_DISABLE_READ: 0x8 (new flag, AArch64 specific)
The problem here is that PKEY_DISABLE_ACCESS has unusual semantics as
it overlaps with existing PKEY_DISABLE_WRITE and new PKEY_DISABLE_READ.
For this reason mapping between permission bits RWX and "restrictions"
bits awxr (a for disable access, etc) becomes complicated:
- PKEY_DISABLE_ACCESS disables both R and W
- PKEY_DISABLE_{WRITE,READ} disables W and R respectively
- PKEY_DISABLE_EXECUTE disables X
Combinations like the one below are accepted although they are redundant:
- PKEY_DISABLE_ACCESS | PKEY_DISABLE_READ | PKEY_DISABLE_WRITE
Reverse mapping tries to retain backward compatibility and ORs
PKEY_DISABLE_ACCESS whenever both flags PKEY_DISABLE_READ and
PKEY_DISABLE_WRITE would be present.
This will break code that compares pkey_get output with == instead
of using bitwise operations. The latter is more correct since PKEY_*
constants are essentially bit flags.
It should be noted that PKEY_DISABLE_ACCESS does not prevent execution.
[1] https://developer.arm.com/documentation/ddi0487/ka/ section D8.4.1.4
Co-authored-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Change name of the access_rights argument to access_restrictions
of the following functions:
- pkey_alloc()
- pkey_set()
as this argument refers to access restrictions rather than access
rights and previous name might have been misleading.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Update the name of the argument in several pkey_*() functions that refers
to access restrictions rather than access rights: change access "rights"
to access "restrictions".
Specify that the result of the pkey_get() should be checked using bitwise
operations rather than plain equals comparison.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
This patch adds new flag --glibctunables to the cross-test-ssh.sh script
to pass Glibc tunables to the system on which tests are executed.
The value to pass can be also provided via the GLIBC_TUNABLES environment
variable.
This works similar to the TIMEOUTFACTOR variable.
Sometimes it is useful to cross test glibc with some non-default tunable,
and a global environment variable is the easiest way to inject some
tunable value into most tests. With this patch using cross-test-ssh.sh
script becomes very similar to running a test natively on the local host
when using non-default tunable is important.
Reviewed-by: Arjun Shankar <arjun@redhat.com>