Hi,
This series introduces new user_ptr helpers to help in certain
uaccess-related situations. This is a follow-up to my previous series
"New CHERI API and separation of root capabilities"; the CHERI helpers
it introduced are used to implement the new generic user_ptr helpers in
PCuABI.
The new helpers are (see patch 1 for details):
* make_user_ptr_for_<perms>_uaccess(), to create user pointers in order
to perform uaccess, with appropriate bounds and permissions.
* check_user_ptr_<perms>(), to perform explicit checking of user
pointers.
This series does not actually make use of check_user_ptr_<perms>(),
rather it prepares the ground for implementing explicit checking when
user memory is accessed via kernel mappings [1].
The rest of the series (patch 2-9) is about converting existing uses of
uaddr_to_user_ptr_safe(), as it should now only be used for *providing*
user pointers to userspace, and not for uaccess.
After this series, the only remaining users of uaddr_to_user_ptr_safe()
are:
- fs/binfmt_elf.c to provide all the initial capabilities (stack,
AT_CHERI_*_CAP, etc.). uaddr_to_user_ptr_safe() is still used to write
the initial data on the stack too; it didn't seem worthwhile to
refactor this code as it is going to change anyway as part of [2]
and [3].
- mmap / mremap / shmat to return a valid capability.
To clarify which helper should be used in which situation, here are two
tables specifying the helper to use depending on whether the address is
specified by userspace or the kernel itself, and whether the pointer is
provided to userspace or used by the kernel itself.
*Before* this series:
+-----------------------------------+---------------------+--------------------------+
| Pointer for \ Address provided by | User | Kernel |
+===================================+=====================+==========================+
| User | - | uaddr_to_user_ptr_safe() |
+-----------------------------------+---------------------+--------------------------+
| Kernel (uaccess) | uaddr_to_user_ptr() | uaddr_to_user_ptr_safe() |
+-----------------------------------+---------------------+--------------------------+
*After* this series:
+-----------------------------------+---------------------+-------------------------------+
| Pointer for \ Address provided by | User | Kernel |
+===================================+=====================+===============================+
| User | - | uaddr_to_user_ptr_safe() |
+-----------------------------------+---------------------+-------------------------------+
| Kernel (uaccess) | uaddr_to_user_ptr() | make_user_ptr_*_for_uaccess() |
+-----------------------------------+---------------------+-------------------------------+
Eventually both uaddr_to_user_ptr() and uaddr_to_user_ptr_safe() should
disappear, the first thanks to userspace always providing full pointers
and the second being replaced by handcrafted code creating capabilities
in line with the PCuABI spec (whose bounds give access to only the
intended object and potentially padding).
Note that patch 1 and 4 were included in the first RFC of the CHERI API
series [4]. They remain broadly the same, but:
- make_privileged_user_ptr and check_user_ptr() have been renamed, and the
permissions are now specified by calling the right variant of the function
instead of passing a bitfield. They are now called respectively
make_user_ptr_for_<perms>_uaccess() and check_user_ptr_<perms>().
- The user_ptr documentation has been updated accordingly.
- The commit messages have been improved to reflect the overall
intention better.
Review branch:
https://git.morello-project.org/kbrodsky-arm/linux/-/commits/morello/user_p…
Rendered doc:
https://git.morello-project.org/kbrodsky-arm/linux/-/blob/morello/user_ptr_…
Thanks,
Kevin
[1] https://git.morello-project.org/morello/kernel/linux/-/issues/7
[2] https://git.morello-project.org/morello/kernel/linux/-/issues/19
[3] https://git.morello-project.org/morello/kernel/linux/-/issues/22
[4] https://op-lists.linaro.org/archives/list/linux-morello@op-lists.linaro.org…
Kevin Brodsky (9):
linux/user_ptr.h: Introduce uaccess-related helpers
fs/binfmt_elf: Create appropriate user pointer for uaccess
coredump: Create appropriate user pointer for uaccess
mm/memory: Create appropriate user pointer for uaccess
Revert "mm/hugetlb: Use appropriate user pointer conversions"
Revert "mm/shmem: Use appropriate user pointer conversions"
audit: Create appropriate user pointer for uaccess
perf: Avoid uaddr_to_user_ptr_safe() for arbitrary user address
arm64: Create appropriate user pointer for uaccess
Documentation/core-api/user_ptr.rst | 100 ++++++++++++++++++----------
arch/arm64/kernel/debug-monitors.c | 3 +-
arch/arm64/kernel/traps.c | 2 +-
fs/binfmt_elf.c | 14 ++--
fs/coredump.c | 4 +-
include/linux/user_ptr.h | 86 ++++++++++++++++++++++--
kernel/auditsc.c | 3 +-
kernel/events/internal.h | 2 +-
lib/user_ptr.c | 46 +++++++++++++
mm/hugetlb.c | 2 +-
mm/memory.c | 2 +-
mm/shmem.c | 2 +-
12 files changed, 216 insertions(+), 50 deletions(-)
--
2.38.1
This series makes it possible for purecap apps to use the io_uring
system.
With these patches, all io_uring LTP tests pass in both Purecap and
plain AArch64 modes. Note that the LTP tests only address the basic
functionality of the io_uring system and a significant portion of the
multiplexed functionality is untested in LTP.
I have finished investigating Purecap and plain AArch64 liburing tests
and examples and the series is updated accordingly.
v5:
- Revert changes in trace/events/io_uring.h
- Add new header trace/events/io_uring.h for compat structs
- Change cqe_cached/ccqe_sentinel to indices
- Move print_sqe and print_cqe macros outside of the function
- Rename is_compat64_io_ring_ctx to io_in_compat64
- Add helper for user_data values comparison
- Add condition to not change addr fielt to a compat_ptr for opcodes where
it's a user_data value stored
- Other small fixes suggested by Kevin
v4:
- Rebase on top of morello/next
- Remove the union for flags in struct compat_io_uring_sqe and only
kept a single member
- Improve format and move functions as per feedback on v3
- Add a new helper for checking if context is compat
- Remove struct conversion in fdinfo and just use macros
- Remove the union from struct io_overflow_cqe and just leave the
native struct
- Fix the cqe_cached/cqe_sentinel mechanism
- Separate the fix for the shared ring size's off-by-one error into a
new PATCH 6
- Remove the compat_ptr for addr fields that represent user_data values
- Extend the trace events accordingly to propagate capabilities
- Use copy*_with_ptr routine for copy_msghdr_from_user in a new PATCH 1
- Fix the misuse of addr2 and off in IORING_OP_CONNECT and
IORING_OP_POLL_REMOVE
v3:
- Introduce Patch 5 which exposes the compat handling logic for
epoll_event. This is used then in io_uring/epoll.c.
- Introduce Patch 6 which makes sure that when struct iovec is copied
from userspace, the capability tags are preserved.
- Fix a few sizeof(var) to sizeof(*var).
- Use iovec_from_user so that compat handling logic is applied instead
of copying directly from user
- Add a few missing copy_from_user_with_ptr where suitable.
v2:
- Rebase on top of release 6.1
- Remove VM_READ_CAPS/VM_LOAD_CAPS patches as they are already merged
- Update commit message in PATCH 1
- Add the generic changes PATCH 2 and PATCH 3 to avoid copying user
pointers from/to userspace unnecesarily. These could be upstreamable.
- Split "pulling the cqes memeber out" change into PATCH 4
- The changes for PATCH 5 and 6 are now split into their respective
files after the rebase.
- Format and change organization based on the feedback on the
previous version, including creating helpers copy_*_from_* for various
uAPI structs
- Add comments related to handling of setup flags IORING_SETUP_SQE128
and IORING_SETUP_CQE32
- Add handling for new uAPI structs: io_uring_buf, io_uring_buf_ring,
io_uring_buf_reg, io_uring_sync_cancel_reg.
Gitlab issue:
https://git.morello-project.org/morello/kernel/linux/-/issues/2
Review branch:
https://git.morello-project.org/tudcre01/linux/-/commits/morello/io_uring_v5
Tudor Cretu (10):
net: socket: use copy_from_user_with_ptr for struct user_msghdr
io_uring/rw: Restrict copy to only uiov->len from userspace
io_uring/tctx: Copy only the offset field back to user
io_uring: Pull cqes member out from rings struct
epoll: Expose compat handling logic of epoll_event
io_uring/kbuf: Fix size for shared buffer ring
io_uring: Make cqe_cached and cqe_sentinel indices instead of pointers
io_uring: Implement compat versions of uAPI structs and handle them
io_uring: Allow capability tag access on the shared memory
io_uring: Use user pointer type in the uAPI structs
fs/eventpoll.c | 38 ++--
include/linux/eventpoll.h | 4 +
include/linux/io_uring_compat.h | 129 +++++++++++++
include/linux/io_uring_types.h | 35 ++--
include/uapi/linux/io_uring.h | 76 ++++----
io_uring/advise.c | 7 +-
io_uring/cancel.c | 32 +++-
io_uring/cancel.h | 2 +-
io_uring/epoll.c | 4 +-
io_uring/fdinfo.c | 82 +++++---
io_uring/fs.c | 16 +-
io_uring/io_uring.c | 321 +++++++++++++++++++++++---------
io_uring/io_uring.h | 147 +++++++++++++--
io_uring/kbuf.c | 111 +++++++++--
io_uring/kbuf.h | 8 +-
io_uring/msg_ring.c | 4 +-
io_uring/net.c | 25 +--
io_uring/openclose.c | 4 +-
io_uring/poll.c | 8 +-
io_uring/rsrc.c | 138 +++++++++++---
io_uring/rw.c | 22 +--
io_uring/statx.c | 4 +-
io_uring/tctx.c | 56 +++++-
io_uring/timeout.c | 14 +-
io_uring/uring_cmd.c | 5 +
io_uring/uring_cmd.h | 4 +
io_uring/xattr.c | 12 +-
net/socket.c | 2 +-
28 files changed, 1000 insertions(+), 310 deletions(-)
create mode 100644 include/linux/io_uring_compat.h
--
2.34.1
Hi,
This is a small update to Vincenzo's series enabling TUN/TAP support.
v1..v2:
- Brought back tun_chr_compat_ioctl(), as we need to keep the handling
of struct compat_ifreq being of a different size. The behaviour is
otherwise unchanged from v1 (arg is always converted to a user pointer
via compat_ptr(), just like when using compat_ptr_ioctl).
- Adjusted the commit message in patch 1 accordingly, changed commit
title as I suggested in v1.
Review branch:
https://git.morello-project.org/kbrodsky-arm/linux/-/commits/morello/tun_v2
Thanks,
Kevin
Vincenzo Frascino (2):
net: tun: Fix ioctl handler argument type
arm64: morello: Enable TUN in defconfig
.../morello_transitional_pcuabi_defconfig | 1 +
drivers/net/tun.c | 22 ++++---------------
2 files changed, 5 insertions(+), 18 deletions(-)
--
2.38.1
When Morello support is enabled, there is no guarantee that the view
of a task's X and C registers (e.g. regs->regs and regs->cregs) is
coherent (see also the note on "write coalescing" in
Documentation/arm64/morello.rst). X/C merging always happens when
returning to userspace, but the value of a task's X registers may be
updated without the task being scheduled. This may happen due to
ptrace(PTRACE_SETREGSET), but also, crucially, when multiple pending
signals are delivered at the same time (typically when the task
unblocks them).
All capability registers are read in preserve_morello_context(), in
order to store them in the signal frame, and
morello_merge_cap_regs() is called beforehand to update the view of
capability registers.
However, there was an oversight in one of the initial Morello
support commits ("arm64: morello: Context-switch Restricted
registers"): regs->csp is also read in signal_sp(), which is called
before preserve_morello_context(). signal_sp() may therefore read a
stale SP value.
signal_sp() has changed several times since that commit, especially
to add PCuABI support. The last commit ("arm64: signal: Fix
signal_sp() in compat64") made the issue resurface, as regs->csp is
now used in compat64 too.
The error condition is indeed difficult to hit in PCuABI, as it
requires using ptrace with a very precise timing. On the other hand,
it can be reliably triggered in compat64 by delivering two signals
at the same time: regs->sp is set in setup_return() when the first
signal frame is set up, leaving regs->csp unchanged, and signal_sp()
will then read a stale SP value through regs->csp to set up the
second signal frame.
This situation is precisely what the sigpending02 LTP test creates,
allowing the bug to be finally caught.
To avoid any further issue, the call to morello_merge_cap_regs() is
therefore moved to the very beginning of setup_rt_frame(), before
any register is read.
Note that signal_sp() is also called from the rt_sigreturn handler,
but this is not a concern as the register view is up-to-date at the
point where a syscall handler is called.
Signed-off-by: Kevin Brodsky <kevin.brodsky(a)arm.com>
---
arch/arm64/kernel/signal.c | 20 ++++++++++++--------
1 file changed, 12 insertions(+), 8 deletions(-)
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index 183293d77f80..81130cc42696 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -275,14 +275,6 @@ static int preserve_morello_context(struct morello_context __user *ctx,
__put_user_error(sizeof(struct morello_context), &ctx->head.size, err);
__put_user_error(0, &ctx->__pad, err);
- /*
- * current's 64-bit registers may have been modified (e.g. through
- * ptrace) since the last time it was scheduled.
- * Perform the standard 64-bit / capability register merging, to ensure
- * that both views in the signal frame are consistent.
- */
- morello_merge_cap_regs(regs);
-
for (i = 0; i < ARRAY_SIZE(regs->cregs); i++)
__morello_put_user_cap_error(regs->cregs[i], &ctx->cregs[i], err);
__morello_put_user_cap_error(regs->csp, &ctx->csp, err);
@@ -1108,6 +1100,18 @@ static int setup_rt_frame(int usig, struct ksignal *ksig, sigset_t *set,
int err = 0;
fpsimd_signal_preserve_current_state();
+#ifdef CONFIG_ARM64_MORELLO
+ /*
+ * current's 64-bit registers may have been modified since the last
+ * time it was scheduled. This may have happened through ptrace, but
+ * also if another signal frame just got set up without returning to
+ * userspace.
+ * Perform the standard 64-bit / capability register merging to ensure
+ * that both views are consistent, as we will need to read the current
+ * value of all (C/X) registers.
+ */
+ morello_merge_cap_regs(regs);
+#endif
if (get_sigframe(&user, ksig, regs))
return 1;
--
2.38.1
This series makes it possible for purecap apps to use the io_uring
system.
With these patches, all io_uring LTP tests pass in both Purecap and
compat modes. Note that the LTP tests only address the basic
functionality of the io_uring system and a significant portion of the
multiplexed functionality is untested in LTP.
I have finished investigating Purecap and plain AArch64 liburing tests
and examples and the series is updated accordingly.
v4:
- Rebase on top of morello/next
- Remove the union for flags in struct compat_io_uring_sqe and only
kept a single member
- Improve format and move functions as per feedback on v3
- Add a new helper for checking if context is compat
- Remove struct conversion in fdinfo and just use macros
- Remove the union from struct io_overflow_cqe and just leave the
native struct
- Fix the cqe_cached/cqe_sentinel mechanism
- Separate the fix for the shared ring size's off-by-one error into a
new PATCH 6
- Remove the compat_ptr for addr fields that represent user_data values
- Extend the trace events accordingly to propagate capabilities
- Use copy*_with_ptr routine for copy_msghdr_from_user in a new PATCH 1
- Fix the misuse of addr2 and off in IORING_OP_CONNECT and
IORING_OP_POLL_REMOVE
v3:
- Introduce Patch 5 which exposes the compat handling logic for
epoll_event. This is used then in io_uring/epoll.c.
- Introduce Patch 6 which makes sure that when struct iovec is copied
from userspace, the capability tags are preserved.
- Fix a few sizeof(var) to sizeof(*var).
- Use iovec_from_user so that compat handling logic is applied instead
of copying directly from user
- Add a few missing copy_from_user_with_ptr where suitable.
v2:
- Rebase on top of release 6.1
- Remove VM_READ_CAPS/VM_LOAD_CAPS patches as they are already merged
- Update commit message in PATCH 1
- Add the generic changes PATCH 2 and PATCH 3 to avoid copying user
pointers from/to userspace unnecesarily. These could be upstreamable.
- Split "pulling the cqes memeber out" change into PATCH 4
- The changes for PATCH 5 and 6 are now split into their respective
files after the rebase.
- Format and change organization based on the feedback on the
previous version, including creating helpers copy_*_from_* for various
uAPI structs
- Add comments related to handling of setup flags IORING_SETUP_SQE128
and IORING_SETUP_CQE32
- Add handling for new uAPI structs: io_uring_buf, io_uring_buf_ring,
io_uring_buf_reg, io_uring_sync_cancel_reg.
Gitlab issue:
https://git.morello-project.org/morello/kernel/linux/-/issues/2
Review branch:
https://git.morello-project.org/tudcre01/linux/-/commits/morello/io_uring_v4
Tudor Cretu (9):
net: socket: use copy_from_user_with_ptr for struct user_msghdr
io_uring/rw: Restrict copy to only uiov->len from userspace
io_uring/tctx: Copy only the offset field back to user
io_uring: Pull cqes member out from rings struct
epoll: Expose compat handling logic of epoll_event
io_uring/kbuf: Fix size for shared buffer ring
io_uring: Implement compat versions of uAPI structs and handle them
io_uring: Allow capability tag access on the shared memory
io_uring: Use user pointer type in the uAPI structs
fs/eventpoll.c | 38 ++--
include/linux/eventpoll.h | 4 +
include/linux/io_uring_types.h | 155 +++++++++++++--
include/trace/events/io_uring.h | 46 ++---
include/uapi/linux/io_uring.h | 76 ++++----
io_uring/advise.c | 7 +-
io_uring/cancel.c | 28 ++-
io_uring/cancel.h | 2 +-
io_uring/epoll.c | 4 +-
io_uring/fdinfo.c | 80 +++++---
io_uring/fs.c | 16 +-
io_uring/io_uring.c | 324 +++++++++++++++++++++++---------
io_uring/io_uring.h | 124 +++++++++---
io_uring/kbuf.c | 109 +++++++++--
io_uring/kbuf.h | 8 +-
io_uring/msg_ring.c | 4 +-
io_uring/net.c | 25 +--
io_uring/openclose.c | 4 +-
io_uring/poll.c | 6 +-
io_uring/rsrc.c | 136 +++++++++++---
io_uring/rw.c | 22 +--
io_uring/statx.c | 4 +-
io_uring/tctx.c | 56 +++++-
io_uring/timeout.c | 10 +-
io_uring/uring_cmd.c | 5 +
io_uring/uring_cmd.h | 5 +
io_uring/xattr.c | 12 +-
net/socket.c | 2 +-
28 files changed, 978 insertions(+), 334 deletions(-)
--
2.34.1
Hi,
These 3 patch fixes the failure in clone test with Gcc toolchain. They
need the recent v4 version of Gcc support patches posted earlier [1].
The full patch series can be found here [2].
Changes in v4:
* Removed struct test_fixture.result field as suggested by Kevin.
* Commit log updated.
[1]: git@git.morello-project.org:amitdaniel/linux.git gcc_kselftests_support_v4
[2]: git@git.morello-project.org:amitdaniel/linux.git gcc_kselftests_clone_fixes_v4
Thanks,
Amit Daniel
Amit Daniel Kachhap (3):
kselftests/arm64: morello: Fix restricted mode tests with Gcc
kselftests/arm64: morello: Add a waitpid() syscall
kselftests/arm64: morello: clone: Remove loop check
tools/testing/selftests/arm64/morello/clone.c | 57 ++++++++++---------
.../selftests/arm64/morello/freestanding.h | 12 ++++
.../testing/selftests/arm64/morello/signal.c | 12 ++--
3 files changed, 48 insertions(+), 33 deletions(-)
--
2.25.1
Hi All,
This series are modifications in kselftests required to compile
with alpha version of Morello Gnu toochain recently released [1].
The whole series can also be found here [2].
Changes in v4 as reviewed by Kevin:
* Patch 5 modified for indentation.
* Patch 9 modified for cleaning up extra header.
* Patch 10 modified to shrink the extra code.
Thanks,
Amit Daniel
[1]: https://developer.arm.com/downloads/-/arm-gnu-toolchain-for-morello-downloa…
[2]: git@git.morello-project.org:amitdaniel/linux.git gcc_kselftests_support_v4
Amit Daniel Kachhap (10):
kselftests/arm64: morello: Fix inline assembly syntax
kselftests/arm64: morello: Define uintcap_t for GCC
kselftests/arm64: morello: Fix the -Wcast-function-type warnings
kselftests/arm64: morello: Fix the fallthrough warning
kselftests/arm64: morello: Avoid limits.h for Gcc
kselftests/arm64: morello: clone: Initialize the local variable
kselftests/arm64: morello: clone: Guard if clause to avoid warning
kselftests/arm64: morello: Process the dynamic relocations
kselftests/arm64: morello: Add optimized routine for memcpy
kselftests/arm64: morello: Enable Gcc toolchain support
.../testing/selftests/arm64/morello/Makefile | 19 +-
.../selftests/arm64/morello/bootstrap.c | 7 +-
tools/testing/selftests/arm64/morello/clone.c | 6 +-
.../selftests/arm64/morello/freestanding.h | 7 +
.../arm64/morello/freestanding_init_globals.c | 133 ++++-
.../arm64/morello/freestanding_start.S | 5 +-
.../selftests/arm64/morello/morello_memcpy.S | 530 ++++++++++++++++++
.../testing/selftests/arm64/morello/signal.c | 4 +-
8 files changed, 689 insertions(+), 22 deletions(-)
create mode 100644 tools/testing/selftests/arm64/morello/morello_memcpy.S
--
2.25.1
There are two issues with signal_sp() in compat64:
1. It uses regs->sp, which is not always the Executive SP.
2. It uses uaddr_to_user_ptr_safe(), which shouldn't be used to
create user pointers in compat.
The comment in signal_sp() also became meaningless, as it should
refer to regs->sp and not regs->csp.
Fix both issuses and expand the comment, as the situation is clearly
complicated enough to warrant more explanations.
Fixes: ("arm64: signal: Add support for 64-bit compat signal handling")
Signed-off-by: Kevin Brodsky <kevin.brodsky(a)arm.com>
---
arch/arm64/kernel/signal.c | 20 +++++++++++++++-----
1 file changed, 15 insertions(+), 5 deletions(-)
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index 80289e90fc66..183293d77f80 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -184,15 +184,25 @@ static user_uintptr_t signal_sp(struct pt_regs *regs)
{
#ifdef CONFIG_ARM64_MORELLO
/*
- * If the interrupted context was in Restricted, regs->csp is actually
- * RCSP_EL0, which is usually what we want but not here, because signal
- * handlers are always executed in Executive and therefore on the
- * Executive stack. Read the actual (Executive) CSP_EL0 instead.
+ * Callers of this function want a valid user pointer to the stack.
+ * There are a number of situations to consider:
+ * - In PCuABI, CSP is expected to be a valid capability to access the
+ * stack, so we just return that.
+ * - In compat64, userspace uses only SP; we create a valid user pointer
+ * from SP using compat_ptr().
+ * - In the standard ABI (PCuABI not selected), user pointers are still
+ * 64-bit integers so we just need to return SP.
+ *
+ * Signal handlers are always run in Executive. We therefore need to
+ * return a pointer to the Executive stack. As a result we cannot use
+ * regs->sp, as it is actually RSP_EL0 if the interrupted context was in
+ * Restricted. For this reason we use regs->csp even when we just want
+ * the (64-bit) SP.
*/
#ifndef SIGNAL_COMPAT64
return (user_uintptr_t)regs->csp;
#else /* SIGNAL_COMPAT64 */
- return (user_uintptr_t)uaddr_to_user_ptr_safe(regs->sp);
+ return (user_uintptr_t)compat_ptr((ptraddr_t)regs->csp);
#endif /* SIGNAL_COMPAT64 */
#else /* !CONFIG_ARM64_MORELLO */
return regs->sp;
--
2.38.1