PCuABI itself is defined by the PCuABI specification. However, the
specification only documents the ABI itself and not internal kernel
implementation aspects. To that effect, create a document under a
new cheri/ subfolder, as well as an index file with some information
about CHERI support in general.
Now that we have a generic PCuABI document, link to it from the
related documents, and remove a now-redundant section from the user
pointer doc. All CHERI / PCuABI-related documents are now reachable
from Documentation/cheri/index.rst.
The PCuABI porting guide was initially added to the root of
Documentation/ for lack of relevant subfolder, we can now move it to
a more appropriate home.
Reviewed-by: Vincenzo Frascino <vincenzo.frascino(a)arm.com>
Signed-off-by: Kevin Brodsky <kevin.brodsky(a)arm.com>
---
Rendered version:
https://git.morello-project.org/kbrodsky-arm/linux/-/tree/pcuabi_doc/Docume…
Documentation/arm64/morello.rst | 14 +-
Documentation/cheri/index.rst | 22 +++
Documentation/{ => cheri}/pcuabi-porting.rst | 18 +-
Documentation/cheri/pcuabi.rst | 177 +++++++++++++++++++
Documentation/core-api/user_ptr.rst | 25 +--
5 files changed, 220 insertions(+), 36 deletions(-)
create mode 100644 Documentation/cheri/index.rst
rename Documentation/{ => cheri}/pcuabi-porting.rst (96%)
create mode 100644 Documentation/cheri/pcuabi.rst
diff --git a/Documentation/arm64/morello.rst b/Documentation/arm64/morello.rst
index bc0d98596762..00f28b76d1a6 100644
--- a/Documentation/arm64/morello.rst
+++ b/Documentation/arm64/morello.rst
@@ -231,12 +231,12 @@ ABIs
In the default kernel configuration, existing aspects of the standard
AArch64 kernel-user ABI remain unchanged.
-As a highly experimental feature, it is possible to choose a different
-kernel-user ABI, the **pure-capability ABI** (PCuABI), by selecting the
-``CONFIG_CHERI_PURECAP_UABI`` option. In this ABI, all pointers at the
-kernel-user boundary are capabilities, providing a native interface for
-pure-capability executables; see the CHERI C/C++ Programming Guide [4]_
-for an overview of this programming model.
+As an experimental feature, it is possible to choose a different
+kernel-user ABI, the `pure-capability kernel-user ABI`_ (PCuABI), by
+selecting the ``CONFIG_CHERI_PURECAP_UABI`` option. In this ABI, all
+pointers at the kernel-user boundary are capabilities, providing a
+native interface for pure-capability executables; see the CHERI C/C++
+Programming Guide [4]_ for an overview of this programming model.
When ``CONFIG_CHERI_PURECAP_UABI`` is selected, the meaning of
``CONFIG_COMPAT`` is modified: instead of providing support for AArch32
@@ -280,6 +280,8 @@ ABI**. These extensions are also available in PCuABI, with a number of
differences. The transitional PCuABI specification [5]_ takes precedence
where it differs from the present document.
+.. _pure-capability kernel-user ABI: Documentation/cheri/pcuabi.rst
+
Register handling
-----------------
diff --git a/Documentation/cheri/index.rst b/Documentation/cheri/index.rst
new file mode 100644
index 000000000000..6955e298b88e
--- /dev/null
+++ b/Documentation/cheri/index.rst
@@ -0,0 +1,22 @@
+=============
+CHERI support
+=============
+
+This directory contains documents related to the support of `CHERI`_.
+CHERI is an architectural extension introducing the concept of hardware
+capabilities. The CHERI model is available on a number of architectures;
+many aspects of CHERI support are arch-agnostic, however lower-level
+arch-specific enablement is also required. The following CHERI-enabled
+architectures are currently supported in Linux:
+
+* `Morello`_ (arm64-based experimental architecture)
+
+Documentation in this directory pertains only to arch-agnostic aspects of
+CHERI support.
+
+.. toctree::
+ pcuabi
+ pcuabi-porting
+
+.. _CHERI: https://www.cl.cam.ac.uk/research/security/ctsrd/cheri/
+.. _Morello: Documentation/arm64/morello.rst
diff --git a/Documentation/pcuabi-porting.rst b/Documentation/cheri/pcuabi-porting.rst
similarity index 96%
rename from Documentation/pcuabi-porting.rst
rename to Documentation/cheri/pcuabi-porting.rst
index a3ff0c98e6b0..2a38862e869a 100644
--- a/Documentation/pcuabi-porting.rst
+++ b/Documentation/cheri/pcuabi-porting.rst
@@ -3,12 +3,10 @@ Adding PCuABI support to drivers
=================================
This document provides a non-exhaustive overview of the most common
-changes required to support the pure-capability user ABI (PCuABI) in
-arbitrary drivers. It may also be helpful for core subsystems, though
-note that more extensive changes may be required compared to drivers
-with straightforward interactions with userspace.
-
-.. _user pointer documentation: core-api/user_ptr.rst
+changes required to support the `pure-capability kernel-user ABI`_
+(PCuABI) in arbitrary drivers. It may also be helpful for core
+subsystems, though note that more extensive changes may be required
+compared to drivers with straightforward interactions with userspace.
User pointer representation and conversions
===========================================
@@ -342,8 +340,8 @@ typically throw the following error::
error: use of __capability is ambiguous
-A fixup is then required, as described in section "PCuABI-specific
-changes" of the `user pointer documentation`_. For instance::
+A fixup is then required, as described in section "Leveraging ``__user``"
+of the `PCuABI documentation`_. For instance::
diff --git a/net/socket.c b/net/socket.c
index 8597fbacb089..ab2a610825cc 100644
@@ -364,3 +362,7 @@ changes" of the `user pointer documentation`_. For instance::
Fortunately, ``__user`` is mostly used in simple types, and such fixups
are rarely needed in driver code.
+
+.. _user pointer documentation: Documentation/core-api/user_ptr.rst
+.. _PCuABI documentation: Documentation/cheri/pcuabi.rst
+.. _pure-capability kernel-user ABI: `PCuABI documentation`_
diff --git a/Documentation/cheri/pcuabi.rst b/Documentation/cheri/pcuabi.rst
new file mode 100644
index 000000000000..90e8a4200826
--- /dev/null
+++ b/Documentation/cheri/pcuabi.rst
@@ -0,0 +1,177 @@
+===================================
+The pure-capability kernel-user ABI
+===================================
+
+CHERI capabilities can be used in many ways. In the so-called
+pure-capability model, all pointers are represented as capabilities,
+whether they are manipulated explicitly or not. This approach is highly
+attractive as it leverages many of the CHERI mechanisms to strengthen
+memory safety, without disrupting the vast majority of existing C/C++
+software.
+
+The pure-capability model requires a major ABI break, as the
+representation of pointers is fundamentally different from "traditional"
+ABIs, where pointers are simply integer addresses. Supporting such a
+model in userspace therefore requires the introduction of a new
+kernel-user ABI, the pure-capability kernel-user ABI (PCuABI).
+
+A specification for this new uABI, complemented with rationale about its
+design and objectives, is available in the following document:
+
+ `PCuABI specification`_
+
+This specification is currently limited to the Morello architecture, as
+it is the only CHERI-enabled architecture supported in Linux. Adding
+support for other architectures would entail extending the specification
+accordingly.
+
+The present document deals with implementation aspects that are beyond
+the scope of the specification. It aims to provide kernel developers
+with an overview of the changes that have been made to various internal
+kernel APIs in order to support PCuABI.
+
+Note: current limitations
+ Support for PCuABI in Linux is a work in progress, and at this stage
+ it is mostly of a functional nature, with only limited enforcement of
+ capability-related restrictions. The variant of the ABI that is
+ currently implemented in Linux is documented in the `transitional
+ PCuABI specification`_, which is forward-compatible with the full
+ specification. Only **a limited set of syscalls** is supported in this
+ ABI.
+
+Config option
+=============
+
+Selecting the option ``CONFIG_CHERI_PURECAP_UABI`` enables support for
+the pure-capability uABI; in other words, the native userspace ABI
+becomes PCuABI instead of the "traditional" uABI. This option is not
+tied to any particular architecture, but naturally it is only available
+on CHERI-enabled architectures.
+
+
+The hybrid approach
+===================
+
+The way in which PCuABI is currently implemented in Linux is a hybrid
+approach: the native userspace ABI becomes pure-capability while **the
+in-kernel ABI remains unchanged**. Concretely, this means that kernel
+pointers and user pointers are no longer intercompatible; specifically,
+a kernel pointer - still an integer - cannot represent a user pointer -
+now a capability.
+
+Note: different approaches
+ This is only one of a number of plausible strategies to support PCuABI.
+ A more natural approach is to change the in-kernel ABI in line with
+ the userspace ABI, that is to make the kernel itself a pure-capability
+ binary. While this simplifies the handling of user pointers compared
+ to the hybrid approach, and strengthens the kernel itself, building
+ the kernel in the pure-capability ABI is a major undertaking, mainly
+ due to the extremely widespread representation of kernel pointers as
+ ``long``-sized integers. To keep the level of effort reasonable and
+ achieve a complete implementation of PCuABI in a realistic timescale,
+ the hybrid approach has therefore been chosen as a starting point.
+
+
+Leveraging __user
+-----------------
+
+User pointers are currently turned into capabilities by redefining the
+``__user`` macro to expand to ``__capability``. This is a convenient
+approach as all user pointers should already be annotated with
+``__user``, thereby avoiding the extensive changes a new annotation
+would entail.
+
+Unfortunately, the ``_user`` annotation prefixes ``*``, for instance::
+
+ void __user *
+
+This is problematic as ``void __capability *`` is deprecated;
+``__capability`` is only unambiguous when used as a suffix for ``*``.
+In more complex cases, such as double pointers, the compiler is only
+able to parse ``__capability`` as a suffix.
+
+It is therefore occasionally necessary to introduce PCuABI-specific fixup
+blocks to remove that ambiguity by moving ``__capability`` from prefix to
+suffix. It is typically done as follows::
+
+ #ifdef CONFIG_CHERI_PURECAP_UABI
+ void * __capability * __capability p;
+ #else
+ void __user * __user *p;
+ #endif
+
+Fortunately, in the vast majority of cases simple user pointers are used
+and no such fixup is required.
+
+
+Pointer and address types
+=========================
+
+As mentioned previously, user pointers are larger than kernel pointers
+when ``CONFIG_CHERI_PURECAP_UABI`` is selected. Indeed, user pointers
+are represented as capabilities; they are therefore 129-bit wide on
+64-bit architectures: twice the address size, plus an out-of-band tag
+bit. This tag bit is an integral part of the user pointer and can only
+be preserved by representing the user pointer with a compiler-provided
+capability type, such as ``void * __capability`` or ``__uintcap_t``.
+
+For this reason, the representation of certain types changes when the
+kernel is built to support PCuABI. The table below provides the
+*representation* of various types **in the kernel** on a 64-bit
+architecture, depending on the supported user ABI:
+
++----------------------------------+------------------+----------------+--------------------------------------------------------------------------+
+| Type | Traditional uABI | PCuABI | Notes |
++==================================+==================+================+==========================================================================+
+| ``void *`` | 64-bit integer | 64-bit integer | |
++----------------------------------+------------------+----------------+--------------------------------------------------------------------------+
+| ``uintptr_t`` | 64-bit integer | 64-bit integer | |
++----------------------------------+------------------+----------------+--------------------------------------------------------------------------+
+| | ``(unsigned) long`` | 64-bit integer | 64-bit integer | ``ptraddr_t`` is a new generic type that represents an address. |
+| | ``(unsigned) long long`` | | | |
+| | ``ptraddr_t`` | | | |
++----------------------------------+------------------+----------------+--------------------------------------------------------------------------+
+| ``void __user *`` | 64-bit integer | Capability | |
++----------------------------------+------------------+----------------+--------------------------------------------------------------------------+
+| ``user_uintptr_t`` | 64-bit integer | Capability | Represented as ``uintcap_t`` in PCuABI, see below. |
++----------------------------------+------------------+----------------+--------------------------------------------------------------------------+
+| | ``__kernel_uintptr_t`` | 64-bit integer | Capability | * Represented as ``uintcap_t`` in PCuABI, see below. |
+| | ``__kernel_aligned_uintptr_t`` | | | * At least 64-bit regardless of the ABI. |
++----------------------------------+------------------+----------------+--------------------------------------------------------------------------+
+| | ``void __capability *`` | Capability | Capability | Only available on CHERI-enabled architectures (``__CHERI__`` defined). |
+| | ``void * __capability`` | | | |
++----------------------------------+------------------+----------------+--------------------------------------------------------------------------+
+| ``uintcap_t`` | Capability | Capability | * Only available on CHERI-enabled architectures (``__CHERI__`` defined). |
+| | | | * Represented as a capability, but otherwise behaves as a 64-bit integer |
+| | | | (when performing arithmetic, converting to other integer types, etc.). |
++----------------------------------+------------------+----------------+--------------------------------------------------------------------------+
+
+For reference, the table below provides the representation of relevant
+types **in userspace**, depending on the chosen ABI:
+
++----------------------------------+-----------------+---------------------+------------------------------------------------------------------------+
+| Type | Traditional ABI | Pure-capability ABI | Notes |
++==================================+=================+=====================+========================================================================+
+| ``void *`` | 64-bit integer | Capability | |
++----------------------------------+-----------------+---------------------+------------------------------------------------------------------------+
+| ``uintptr_t`` | 64-bit integer | Capability | Represented as ``uintcap_t`` in purecap. |
++----------------------------------+-----------------+---------------------+------------------------------------------------------------------------+
+| | ``(unsigned) long`` | 64-bit integer | 64-bit integer | |
+| | ``(unsigned) long long`` | | | |
+| | ``ptraddr_t`` | | | |
++----------------------------------+-----------------+---------------------+------------------------------------------------------------------------+
+| | ``__kernel_uintptr_t`` | 64-bit integer | Capability | * Represented as ``uintcap_t`` in purecap. |
+| | ``__kernel_aligned_uintptr_t`` | | | * At least 64-bit regardless of the ABI. |
++----------------------------------+-----------------+---------------------+------------------------------------------------------------------------+
+| | ``void __capability *`` | Capability | Capability | Only available on CHERI-enabled architectures (``__CHERI__`` defined). |
+| | ``void * __capability`` | | | |
++----------------------------------+-----------------+---------------------+------------------------------------------------------------------------+
+| ``uintcap_t`` | Capability | Capability | Only available on CHERI-enabled architectures (``__CHERI__`` defined). |
++----------------------------------+-----------------+---------------------+------------------------------------------------------------------------+
+
+For more information about user pointers and related conversions, please
+refer to the `user pointer documentation`_.
+
+.. _PCuABI specification: https://git.morello-project.org/morello/kernel/linux/-/wikis/Morello-pure-c…
+.. _Transitional PCuABI specification: https://git.morello-project.org/morello/kernel/linux/-/wikis/Transitional-M…
+.. _user pointer documentation: Documentation/core-api/user_ptr.rst
diff --git a/Documentation/core-api/user_ptr.rst b/Documentation/core-api/user_ptr.rst
index 21e02d4bd11b..0e14616c0499 100644
--- a/Documentation/core-api/user_ptr.rst
+++ b/Documentation/core-api/user_ptr.rst
@@ -12,7 +12,7 @@ regions:
These two categories of pointers are not interchangeable and, in
particular, the kernel should never directly dereference a user pointer.
-The introduction of the pure-capability kernel-user ABI (PCuABI) has
+The introduction of the `pure-capability kernel-user ABI`_ (PCuABI) has
made this distinction even more important, as in that configuration user
pointers are of a different type altogether and cannot be represented by
kernel pointers or most integer types.
@@ -20,6 +20,8 @@ kernel pointers or most integer types.
This document outlines the available API to represent and manipulate
user pointers in a way that is safe in any kernel-user ABI.
+.. _pure-capability kernel-user ABI: Documentation/cheri/pcuabi.rst
+
Representing user pointers
==========================
@@ -52,27 +54,6 @@ integer types such as ``long``. User **addresses** may however still be
represented like kernel addresses, e.g. using ``long``. The recommended
type for addresses when writing new code is ``ptraddr_t``.
-PCuABI-specific changes
------------------------
-
-When PCuABI is targeted by selecting the ``CONFIG_CHERI_PURECAP_UABI``
-option, user pointers are turned into capabilities by making the
-``__user`` annotation expand to ``__capability``. Unfortunately,
-``_user`` precedes ``*`` and using ``__capability`` as a prefix of ``*``
-is deprecated. It does work in most cases, but in more complex
-situations, such as double pointers, it becomes ambiguous and fails to
-compile.
-
-It is therefore occasionally necessary to have PCuABI-specific fixup
-blocks to solve that ambiguity by moving ``__capability`` as a suffix of
-``*``. It is typically done as follows::
-
- #ifdef CONFIG_CHERI_PURECAP_UABI
- void * __capability * __capability p;
- #else
- void __user * __user *p;
- #endif
-
Converting user pointers
========================
--
2.38.1
Hi,
This series is a follow-up to the RFC "New CHERI API and rehauled
user_ptr.h", with a slightly different scope to make it more
self-contained.
There are two main focuses for this series:
1. Introducing linux/cheri.h. There is no fundamental change compared to
v1 here.
2. Deriving all capabilities from an appropriate userspace root
capability (cheri_user_root_*) instead of morello_root_cap. v1 started
this by reimplementing uaddr_to_user_ptr*, this series finishes up
the work.
The focus of v1, adding generic functions to linux/user_ptr.h, has been
dropped and will reappear in a separate series.
Some more details on the choice of root capabilities (see the comment in
patch 5 regarding cheri_user_root_*):
* In purecap, the PCuABI spec gives us good guidance on which root
capability we should use where. Namely:
- cheri_user_root_cap for almost all capabilities. The permissions
correspond to the maximum permissions obtainable via mmap(). As we
progress through the second phase, the bounds/permissions of
capabilities derived from this root will be restricted as specified,
and DDC will be set to null.
- cheri_user_root_{seal,cid}_cap for the AT_CHERI_{SEAL,CID}_CAP.
These capabilities exist precisely because their permissions
(Seal/Unseal/CompartmentID) are not provided in regular
capabilities (derived from cheri_user_root_cap).
- cheri_user_root_all_cap for capabilities created via (privileged)
ptrace. See patch 13 for some details on this.
* In hybrid, the de facto ABI is what Documentation/arm64/morello.rst
says. As there is no mechanism to obtain special permissions, all
capabilities are derived from cheri_user_root_all_cap. The
documentation is updated accordingly.
This series introduces functional changes by restricting the
bounds/permissions of all userspace capabilities, but these restrictions
should not affect any valid use-case. More specifically:
* In purecap, the bounds of all capabilities are restricted to the user
address space. See above for details on permissions.
* In hybrid, the bounds of capabilities are also restricted to the user
address space. All relevant permissions remain available. CSP is no
longer initialised to a valid capability, as this is neither required
nor documented.
More detailed changelog below.
v1..v2:
* Addressing review comments:
- Reformatted the function documentation to make kernel-doc -v
(mostly) happy.
- Added some comment clarifying what CHERI_PERM_SW_VMEM is about.
- Renamed ARCH_HAS_CHERI_H to HAVE_ARCH_CHERI_H.
- Renamed cheri_root*_cap_userspace to cheri_user_root_*cap and added
some description of each.
- Renamed cheri_check_cap_data_access() to cheri_check_cap().
* New patches:
- Derive compat_ptr() from cheri_user_root_all_cap (deriving from DDC
proved more complicated than expected, created a ticket for that [1])
- Derive AT_CHERI_{SEAL,CID}_CAP from cheri_user_root_{seal,cid}_cap
- Initialisation of capability registers from cheri_user_root_* (with
a clear separation between purecap and hybrid)
- Capabilities created via (privileged) ptrace now derived from
cheri_user_root_all_cap
- Remove morello_root_cap (no longer used)
- Update documentation to reflect cheri_user_root_all_cap being the
new root capability in hybrid
* Other changes:
- As per a recent update to the PCuABI spec, the BranchSealedPair is
no longer part of the rootcap permission set. It is still needed in
certain user capabilities, so moved it from CHERI_PERMS_ROOTCAP to
explicit addition to cheri_user_root_cap in morello.c.
- Added cheri_user_root_all_cap, the "root of roots" with all
permissions. cheri_user_root_cid_cap is now derived from it too, so
its bounds are not the whole address space any more.
- Patch 8/9 (new functions in user_ptr.h) dropped.
- Rebased on next.
Review branch:
https://git.morello-project.org/kbrodsky-arm/linux/-/commits/cheri_ptr_api_…
Thanks,
Kevin
[1] https://git.morello-project.org/morello/kernel/linux/-/issues/40
Kevin Brodsky (15):
pps: Add missing #include
linux/user_ptr.h: Remove kaddr_to_user_ptr()
linux/user_ptr.h: Improve comment formatting
arm64: uapi: Add asm/cheri.h
linux/cheri.h: Introduce CHERI helpers
arm64: morello: Implement cheri.h
fs/binfmt_elf: Use appropriate caps for AT_CHERI_{SEAL,CID}_CAP
arm64: compat: Use appropriate root cap in compat_ptr() in PCuABI
linux/user_ptr.h: Generic PCuABI impl for uaddr_to_user_ptr*
arm64: Remove asm/user_ptr.h
arm64: morello: Initialise user capabilities from cheri_user_root_*
arm64: morello: Initialise user DDC from cheri_user_root_*
arm64: morello: Build arbitrary user caps using appropriate root
arm64: morello: Remove morello_root_cap
arm64: morello: Update root capability in documentation
Documentation/arm64/morello.rst | 23 +++--
Documentation/core-api/user_ptr.rst | 8 --
arch/Kconfig | 2 +-
arch/arm64/Kconfig | 2 +-
arch/arm64/include/asm/cheri.h | 11 +++
arch/arm64/include/asm/compat.h | 9 +-
arch/arm64/include/asm/morello.h | 12 ++-
arch/arm64/include/asm/user_ptr.h | 43 ---------
arch/arm64/include/uapi/asm/cheri.h | 11 +++
arch/arm64/kernel/morello.c | 143 +++++++++++++++++-----------
arch/arm64/kernel/process.c | 2 +-
arch/arm64/kernel/ptrace.c | 2 +-
arch/arm64/lib/morello.S | 17 ++--
drivers/pps/pps.c | 1 +
fs/binfmt_elf.c | 10 +-
include/linux/cheri.h | 132 +++++++++++++++++++++++++
include/linux/user_ptr.h | 69 ++++++--------
lib/Makefile | 3 +
lib/cheri.c | 72 ++++++++++++++
lib/user_ptr.c | 26 +++++
20 files changed, 413 insertions(+), 185 deletions(-)
create mode 100644 arch/arm64/include/asm/cheri.h
delete mode 100644 arch/arm64/include/asm/user_ptr.h
create mode 100644 arch/arm64/include/uapi/asm/cheri.h
create mode 100644 include/linux/cheri.h
create mode 100644 lib/cheri.c
create mode 100644 lib/user_ptr.c
--
2.38.1
preadv, pwritev and their variants (preadv2/pwritev2) do have compat
handlers defined in generic code. However, these handlers are
completely specific to 32-bit, as they expect the offset to be
passed in two consecutive 32-bit integers.
Since the compat handlers do not perform any other conversion, we
can simply use the native handlers instead in compat64.
Note that using the 64-suffixed compat handlers (e.g.
compat_sys_preadv64) would not be any better, and in fact would not
work in the case of preadv2/pwritev2. Indeed, these syscalls accept
another argument after the offset, but
compat_sys_{preadv64v2,pwrite64v2} take just one 64-bit integer as
offset. This is incompatible with the prototype of native handlers,
as they take two 64-bit integers for the offset and ignore the
second one.
Signed-off-by: Kevin Brodsky <kevin.brodsky(a)arm.com>
---
arch/arm64/kernel/sys_compat64.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/arch/arm64/kernel/sys_compat64.c b/arch/arm64/kernel/sys_compat64.c
index b3c4cf9f3af8..41d72554907a 100644
--- a/arch/arm64/kernel/sys_compat64.c
+++ b/arch/arm64/kernel/sys_compat64.c
@@ -29,6 +29,16 @@
#define __arm64_compatentry_compat_sys_readahead __arm64_compatentry_sys_readahead
#define __arm64_compatentry_compat_sys_fadvise64_64 __arm64_compatentry_sys_fadvise64_64
+/*
+ * The compat_sys_{preadv,pwritev}{,2} handlers are not appropriate for 64-bit
+ * tasks, as they expect the offset to be split in two 32-bit integers. The
+ * native handlers work fine in 64-bit compat too so just use those instead.
+ */
+#define __arm64_compatentry_compat_sys_preadv __arm64_compatentry_sys_preadv
+#define __arm64_compatentry_compat_sys_preadv2 __arm64_compatentry_sys_preadv2
+#define __arm64_compatentry_compat_sys_pwritev __arm64_compatentry_sys_pwritev
+#define __arm64_compatentry_compat_sys_pwritev2 __arm64_compatentry_sys_pwritev2
+
/*
* 64-bit tasks use mmap (not mmap2).
*/
--
2.38.1
A subtle ABI change was introduced in compat64 by "clone: Alter
clone to accept capabilities". Indeed, since there is no compat
handler for clone, the native one is also used for compat, including
64-bit compat (compat64). This is where the way we convert compat64
syscall arguments to native (PCuABI) is showing its limits: if a
syscall wrapper expects a capability-sized argument, compat_ptr() is
used to convert the user-provided 64-bit value to a capability.
In general, this is what we want, and in fact it is the case for the
parent_tidptr and child_tidptr arguments of clone, which are
ordinary pointers to user data. However, the newsp and tls arguments
are special: they specify the value to set registers to. We should
not alter these values in any way: in arm64/PCuABI, they are
capabilities and we set CSP/CTPIDR accordingly, but in hybrid, they
are still 64-bit values and we should only set the lower 64 bits of
CSP/CTPIDR. This is not the case in compat64 as compat_ptr() is
called to turn these 64-bit values into capabilities.
The most correct solution would be to introduce a compat clone
wrapper, but this is rather painful as clone has 4 possible
prototypes depending on the architecture. The approach taken here is
a middle ground, narrowing down the stack / TLS pointer arguments
in the native handler if we got called from compat. This effectively
cancels out the automatic creation of capabilities in the compat
syscall wrapper, which is not ideal but considered acceptable in
this very particular situation.
Fixes: ("clone: Alter clone to accept capabilities")
Co-developed-by: Beata Michalska <beata.michalska(a)arm.com>
Signed-off-by: Kevin Brodsky <kevin.brodsky(a)arm.com>
---
kernel/fork.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/kernel/fork.c b/kernel/fork.c
index 94777ac4d455..73fe97ad471e 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -2743,14 +2743,19 @@ SYSCALL_DEFINE5(clone, unsigned long, clone_flags, user_uintptr_t, newsp,
user_uintptr_t, tls)
#endif
{
+ bool compat_mode = in_compat_syscall();
struct kernel_clone_args args = {
.flags = (lower_32_bits(clone_flags) & ~CSIGNAL),
.pidfd = parent_tidptr,
.child_tid = child_tidptr,
.parent_tid = parent_tidptr,
.exit_signal = (lower_32_bits(clone_flags) & CSIGNAL),
- .stack = newsp,
- .tls = tls,
+ .stack = (compat_mode ?
+ (user_uintptr_t)(compat_ulong_t)newsp :
+ newsp),
+ .tls = (compat_mode ?
+ (user_uintptr_t)(compat_ulong_t)tls :
+ tls),
};
return kernel_clone(&args);
--
2.38.1
A subtle ABI change was introduced in compat64 by "clone: Alter
clone to accept capabilities". Indeed, since there is no compat
handler for clone, the native one is also used for compat64. This is
where the way we convert compat64 syscall arguments to native is
showing its limits: if a syscall wrapper expects a capability-sized
argument, compat_ptr() is used to convert the user-provided 64-bit
value to a capability.
In general, this is what we want, and in fact it is the case for the
parent_tidptr and child_tidptr arguments of clone, which are
ordinary pointers to user data. However, the newsp and tls arguments
are special: they specify the value to set registers to. We should
not alter these values in any way: in PCuABI, they are capabilities
and we set CSP/CTPIDR accordingly, but in hybrid, they are still
64-bit values and we should only set the lower 64 bits of
CSP/CTPIDR. This is not the case in compat64 as compat_ptr() is
called to turn these 64-bit values into capabilities.
The most correct solution would be to introduce a generic compat
clone wrapper, but this is rather painful as clone has 4 possible
prototypes depending on the architecture. Given that the issue is
completely specific to the hybrid ABI, overriding the compat64
syscall wrapper in sys_compat64.c feels like a reasonable
compromise.
Signed-off-by: Kevin Brodsky <kevin.brodsky(a)arm.com>
---
I've realised this inconsistency while thinking about the initialisation
of capability registers ("New CHERI API and separation root
capabilities" series), as well as reviewing the clone3 series. We are
already doing the right thing for clone3, time to align clone.
arch/arm64/kernel/sys_compat64.c | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/arch/arm64/kernel/sys_compat64.c b/arch/arm64/kernel/sys_compat64.c
index 819b895ec21d..b3c4cf9f3af8 100644
--- a/arch/arm64/kernel/sys_compat64.c
+++ b/arch/arm64/kernel/sys_compat64.c
@@ -9,6 +9,7 @@
#include <linux/compat.h>
#include <linux/compiler.h>
+#include <linux/sched/task.h>
#include <linux/syscalls.h>
#include <asm/syscall.h>
@@ -83,6 +84,33 @@
#define __arm64_compatentry_compat_sys_setitimer __arm64_compatentry_sys_setitimer
#define __arm64_compatentry_compat_sys_getrusage __arm64_compatentry_sys_getrusage
+/*
+ * This is exactly the same definition as the native clone, except that newsp
+ * and tls are defined as unsigned long, not user_uintptr_t. When the native ABI
+ * is PCuABI, this prevents capabilities from being implicitly created for the
+ * stack/TLS in compat64 by the syscall wrapper. This ensures alignment with the
+ * hybrid ABI (i.e. CSP/CTPIDR are set to the 64-bit values passed to clone()).
+ */
+COMPAT_SYSCALL_DEFINE5(arm64_clone, unsigned long, clone_flags, unsigned long, newsp,
+ int __user *, parent_tidptr,
+ unsigned long, tls,
+ int __user *, child_tidptr)
+{
+ struct kernel_clone_args args = {
+ .flags = (lower_32_bits(clone_flags) & ~CSIGNAL),
+ .pidfd = parent_tidptr,
+ .child_tid = child_tidptr,
+ .parent_tid = parent_tidptr,
+ .exit_signal = (lower_32_bits(clone_flags) & CSIGNAL),
+ .stack = newsp,
+ .tls = tls,
+ };
+
+ return kernel_clone(&args);
+}
+
+#define __arm64_compatentry_sys_clone __arm64_compatentry_compat_sys_arm64_clone
+
asmlinkage long sys_ni_syscall(void);
asmlinkage long __arm64_compatentry_sys_ni_syscall(const struct pt_regs *__unused)
--
2.38.1
From: Carsten Haitzler <carsten.haitzler(a)foss.arm.com>
In one case the arg is actually just an int passed into the arg and
was being casted from ptr -> long -> int. Now goes through user_intptr_t.
Signed-off-by: Carsten Haitzler <Carsten.Haitzler(a)arm.com>
---
drivers/input/evdev.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index ea4dab2a53f7..066dd1d8cfe4 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -1074,7 +1074,7 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd,
return 0;
case EVIOCRMFF:
- return input_ff_erase(dev, (int)(unsigned long) p, file);
+ return input_ff_erase(dev, (int)(user_intptr_t) p, file);
case EVIOCGEFFECTS:
i = test_bit(EV_FF, dev->evbit) ?
--
2.25.1
Enable the required config options to run panfrost/komeda in the
default defconfig for Morello Transitional PureCap User ABI (PCuABI)
(morello_transitional_pcuabi_defconfig).
Note: The series was verified only by CI and at framebuffer level.
Further testing is required to exercise all the components.
To simplify future testing of this series the complete patch set
applied on top of recent morello kernel can be found at [1].
[1] https://git.morello-project.org/vincenzo/linux morello/drm/v1
Co-developed-by: Kevin Brodsky <kevin.brodsky(a)arm.com>
Co-developed-by: Carsten Haitzler <Carsten.Haitzler(a)arm.com>
Signed-off-by: Vincenzo Frascino <vincenzo.frascino(a)arm.com>
Liviu Dudau (1):
drm/komeda: Fix handling of atomic commits in the atomic_commit_tail
hook
Vincenzo Frascino (9):
morello: dt: Add support for the FVP, SoC
Revert "drm/komeda - Fix handling of pending crtc state commit to
avoid lock-up"
drm: drm_legacy: Fix CONFIG_DRM_LEGACY guards in drm_legacy.h
media: cec: Use proper type to represent user pointers
fbdev: Use proper typecast for capability type
drm: i2c: Include hdmi-codec definitions only when required
rtc: Use proper type to represent user pointers
morello: Enable GPU/DPU in defconfig
morello: Enable RTC support
arch/arm64/boot/dts/arm/Makefile | 1 +
arch/arm64/boot/dts/arm/morello-fvp.dts | 171 +++++++++++
arch/arm64/boot/dts/arm/morello-soc.dts | 278 ++++++++++++++++++
arch/arm64/boot/dts/arm/morello.dtsi | 124 ++++++++
.../morello_transitional_pcuabi_defconfig | 11 +
.../gpu/drm/arm/display/komeda/komeda_crtc.c | 14 +-
.../gpu/drm/arm/display/komeda/komeda_kms.c | 40 +--
.../gpu/drm/arm/display/komeda/komeda_kms.h | 5 +-
drivers/gpu/drm/drm_legacy.h | 2 +-
drivers/gpu/drm/i2c/tda998x_drv.c | 13 +
drivers/media/cec/core/cec-api.c | 4 +-
drivers/rtc/dev.c | 4 +-
drivers/video/fbdev/core/fbmem.c | 7 +-
13 files changed, 633 insertions(+), 41 deletions(-)
create mode 100644 arch/arm64/boot/dts/arm/morello-fvp.dts
create mode 100644 arch/arm64/boot/dts/arm/morello-soc.dts
create mode 100644 arch/arm64/boot/dts/arm/morello.dtsi
--
2.39.0