Hi,
Here's v3 of the bpf syscall patches, following on from the RFC[1],
v1[2] and v2[3].
The bpf syscall is updated to propagate user pointers as capabilities in
the pure-capability kernel-user ABI (PCuABI). It also includes an
approach to support the existing aarch64 ABI (compat64).
One complication here is from the fact this syscall supports many
multiplexed sub-commands, some of which are themselves multiplexed with
a number of nested multiplexed options.
A further complication is that the existing syscall uses a trick of
storing user pointers as u64 to avoid needing a compat handler for
32-bit systems. To retain compatibility with the aarch64 ABI and add
Morello support, special compat64 conversion and handling is
implemented.
Inbound (userspace->kernel) conversion between compat64/native struct
layouts is handled upfront on entry to the syscall (with the exception
of bpf_xyz_info structs). This minimises changes to subcommand handlers.
Some subcommands require conversion back out to userspace and that is by
necessity handled where it occurs.
Patch 1 is not essential to this series but it's a nice debug feature to
have and works[4]. It enables BPF_PROG_TYPE_TRACEPOINT which many eBPF
kselftests use.
Patches 5,6,8 implement the core compat64 handling. Each commit compiles
cleanly but relevant parts will be broken inbetween.
Patch 9 fixes the CHECK_ATTR macro to also check configs passed in via
compat64.
Patch 11 finally enables capabilities in the kernel.
Patches 12,13 handles uaccess that occurs in two eBPF helper functions.
The rest are setup/helper functions.
Testing wise, see associated LTP changes below as posted to LTP mailing
list[5]. The eBPF LTP tests are fairly minimal and test only a small
part of the changes here. There's a new test to test CHECK_ATTR from
patch 9.
The kernel kselftests contain many more extensive eBPF tests. They can
be built fairly easily natively on aarch64 which is useful for testing
compat64. More work needs to be done here though to:
a) enable out-of-tree cross-compilation for purecap as well as
x86->aarch64
b) replace ptr_to_u64() with casts to uintptr_t in tests
c) general libbpf/bpftool enablement and fixes since many tests rely
on this
d) CONFIG_DEBUG_INFO_BTF required for many tests but this requires the
build system to have a recent version of pahole tool
Next steps once we have the core kernel support would be porting libbpf
and bpftool for purecap plus work on enabling kselftests as above.
Kernel branch available at:
https://git.morello-project.org/zdleaf/linux/-/tree/morello/bpf_v3
Associated LTP test/changes at:
https://git.morello-project.org/zdleaf/morello-linux-test-project/-/tree/mo…
Thanks,
Zach
[1] [RFC PATCH 0/9] update bpf syscall for PCuABI/compat64
https://op-lists.linaro.org/archives/list/linux-morello@op-lists.linaro.org…
[2] [PATCH 00/10] update bpf syscall for PCuABI/compat64
https://op-lists.linaro.org/archives/list/linux-morello@op-lists.linaro.org…
[3] [PATCH v2 00/12] update bpf syscall for PCuABI/compat64
https://op-lists.linaro.org/archives/list/linux-morello@op-lists.linaro.org…
[4] [PATCH v3 0/5] Restore syscall tracing on Morello
https://op-lists.linaro.org/archives/list/linux-morello@op-lists.linaro.org…
[5] [PATCH 0/3] add eBPF support
https://op-lists.linaro.org/archives/list/linux-morello-ltp@op-lists.linaro…
-----------------------------------------------------------------------
v3:
- Renamed all {is,in}_32bit_... to compat32, e.g. is_32bit_compat_task
-> is_compat32 task, same for 64bit versions
- Removed dispatch_bpf() + bpf_check_perms() and merged back into
__sys_bpf - they no longer need to be split now we have no separate
compat64 handler
- Ensured we memset(0)/zero initialise all compat/non-compat structs for
bpf_attr, bpf_{prog,link,btf}_info as appropriate when copying in/out
from userspace
- Switched order of first two arguments of bpf_put_uattr() to align with
bpfptr_put_uattr() and more closely match put_user()
- Moved #include <linux/bpf_compat.h> into bpf.h
- Moved bpf_copy_{to,from}_user_with_ptr to bpf.h
- Renamed bpf_uattr_compat_ptr macro to bpf_compat_ptr_field
- Removed const arguments for bpf_copy_from_user(_task) helpers
- Fixed pointer type mismatch warnings in void *ptr =
in_compat64_syscall() ? type1 : type2; pattern
- Replace temporary #define bpfptr_copy with in_compat64_syscall
conditional in bpfptr.h:copy_from_bpfptr_with_ptr - only use _with_ptr
in purecap
v2:
- Fixed copy_from_bpfptr_offset_with_ptr - this no longer uses sockptr
as of 6.1 (see patch 9)
- Rebase on 6.4 - new struct members need conversion/handling:
- New BPF_PROG_TYPE_NETFILTER + associated bpf_attr BPF_LINK_CREATE
members
- New bpf_link_info types BPF_LINK_TYPE_NETFILTER +
BPF_LINK_TYPE_STRUCT_OPS
- Renamed in_32bit_compat_syscall() to in_compat32_syscall() and added
in_compat64_syscall()
- Handled uaccess from bpf helper programs
bpf/helpers.c:bpf_copy_from_user + bpf_copy_from_user_task
- Added new stddef.h macro copy_field() to simplify conversion
assignments
- bpf: compat64: add handler and convert bpf_attr in
- Replaced #ifdef CONFIG_COMPAT64 with in_compat64_syscall() + use
copy_bpf_attr_from_user() helper function for inbound compat
conversion
- This removes the __sys_compat_bpf compat64 handler, now using the
existing __sys_bpf + in_compat64_syscall() for reduced diff size,
less duplication and clearer code
- Conversion now happens in copy_bpf_attr_from_user() for better
encapsulation + stack usage
- bpf: compat64: bpf_attr convert out
- Renamed PUT_USER_ATTR() to bpf_put_uattr() + moved to bpf.h
- Introduced bpfptr_put_uattr() in bpfptr.h
- Originally missed handling cases writing out to userspace with
copy_to_bpfptr_offset() - now replaced with new bpfptr_put_uattr()
macro
- 6.4 now has a new field showing what log size will be needed - see
47a71c1f9af0 ("bpf: Add log_true_size output field to return
necessary log buffer size")
- This also requires new macro bpf_field_exists() to handle compat64
when checking that userspace supports this new field
- bpf: compat64: handle bpf_xyz_info
- Simplified bpf_link_info conversion handling using memcpy
- Removed bpf_map_info patch since struct is the same in
compat64/native (no ptrs)
- Replaced #ifdef CONFIG_COMPAT64 with in_compat64_syscall() + use
copy_bpf_xyz_info_{from,to}_user() helper functions for compat
conversions
- Merged bpf_{btf,prog,link}_info into a single patch
- bpf: use user pointer types in uAPI structs
- Added new compat_uptr_to_kern() macro to simplify casting/converting
in compat ptrs
- Usage of copy_{to,from}_user_with_ptr variants now correctly applied
with new helpers
-----------------------------------------------------------------------
Zachary Leaf (13):
arm64: morello: enable syscall tracing
arch: rename to 32bit_compat to compat32
arch: add compat helpers specific to 64-bit
stddef: introduce copy_field helper
bpf: compat64: add handler and convert bpf_attr in
bpf: compat64: bpf_attr convert out
bpf/btf: move zero check into btf.c
bpf: compat64: handle bpf_{btf,prog,link}_info
bpf: compat64: support CHECK_ATTR macro
bpf: copy_{to,from}_user_with_ptr helpers
bpf: use user pointer types in uAPI structs
bpf: use addr for bpf_copy_from_user_with_task
bpf: use addr for bpf_copy_from_user
.../morello_transitional_pcuabi_defconfig | 2 +-
arch/arm64/include/asm/compat.h | 11 +-
arch/arm64/include/asm/ftrace.h | 2 +-
arch/arm64/include/asm/mmu_context.h | 2 +-
arch/arm64/include/asm/syscall.h | 6 +-
arch/arm64/kernel/fpsimd.c | 6 +-
arch/arm64/kernel/hw_breakpoint.c | 2 +-
arch/arm64/kernel/perf_regs.c | 2 +-
arch/arm64/kernel/pointer_auth.c | 6 +-
arch/arm64/kernel/process.c | 16 +-
arch/arm64/kernel/ptrace.c | 10 +-
arch/arm64/kernel/signal.c | 2 +-
arch/arm64/kernel/syscall.c | 2 +-
arch/mips/include/asm/compat.h | 2 +-
arch/parisc/include/asm/compat.h | 2 +-
arch/powerpc/include/asm/compat.h | 2 +-
arch/s390/include/asm/compat.h | 2 +-
arch/sparc/include/asm/compat.h | 4 +-
arch/x86/include/asm/compat.h | 2 +-
drivers/gpu/drm/amd/amdkfd/kfd_chardev.c | 2 +-
drivers/gpu/drm/amd/amdkfd/kfd_process.c | 2 +-
drivers/input/input.c | 2 +-
drivers/media/rc/bpf-lirc.c | 6 +-
fs/ext4/dir.c | 2 +-
fs/nfs/dir.c | 2 +-
include/linux/bpf.h | 22 +
include/linux/bpf_compat.h | 415 +++++++++
include/linux/bpfptr.h | 30 +-
include/linux/compat.h | 16 +-
include/linux/stddef.h | 3 +
include/uapi/linux/bpf.h | 94 +-
kernel/bpf/bpf_iter.c | 2 +-
kernel/bpf/btf.c | 105 ++-
kernel/bpf/cgroup.c | 9 +-
kernel/bpf/hashtab.c | 12 +-
kernel/bpf/helpers.c | 9 +-
kernel/bpf/net_namespace.c | 6 +-
kernel/bpf/offload.c | 2 +-
kernel/bpf/syscall.c | 871 ++++++++++++++----
kernel/bpf/verifier.c | 20 +-
kernel/time/time.c | 2 +-
kernel/trace/bpf_trace.c | 6 +-
mm/util.c | 2 +-
net/bpf/bpf_dummy_struct_ops.c | 8 +-
net/bpf/test_run.c | 31 +-
net/core/sock_map.c | 6 +-
46 files changed, 1425 insertions(+), 345 deletions(-)
create mode 100644 include/linux/bpf_compat.h
--
2.34.1
Hi,
Here's v2 of the bpf syscall patches, following on from the RFC[1] and
v1[2].
The bpf syscall is updated to propagate user pointers as capabilities in
the pure-capability kernel-user ABI (PCuABI). It also includes an
approach to support the existing aarch64 ABI (compat64).
One complication here is from the fact this syscall supports many
multiplexed sub-commands, some of which are themselves multiplexed with
a number of nested multiplexed options.
A further complication is that the existing syscall uses a trick of
storing user pointers as u64 to avoid needing a compat handler for
32-bit systems. To retain compatibility with the aarch64 ABI and add
Morello support, special compat64 conversion and handling is
implemented.
Inbound (userspace->kernel) conversion between compat64/native struct
layouts is handled upfront on entry to the syscall (with the exception
of bpf_xyz_info structs). This minimises changes to subcommand handlers.
Some subcommands require conversion back out to userspace and that is by
necessity handled where it occurs.
Patch 1 is not essential to this series but it's a nice debug feature to
have and works[3]. It enables BPF_PROG_TYPE_TRACEPOINT which many eBPF
kselftests use.
Patches 2-4, 9 are setup and helper functions.
Patches 5-7 implement the core compat64 handling. Each commit compiles
cleanly but relevant parts will be broken inbetween.
Patch 8 fixes a check to also check configs passed in via compat64.
Patch 10 finally enables capabilities in the kernel.
Patches 11,12 handles uaccess that occurs in two eBPF helper functions.
Testing wise, see associated LTP changes below as posted to LTP mailing
list[4]. The eBPF LTP tests are fairly minimal and test only a small
part of the changes here. There's a new test to test CHECK_ATTR from
patch 8.
The kernel kselftests contain much more extensive eBPF tests. They can
be built fairly easily natively on aarch64 which is useful for testing
compat64. More work needs to be done here though to:
a) enable out-of-tree cross-compilation for purecap as well as
x86->aarch64
b) replace ptr_to_u64() with casts to uintptr_t in tests
c) general libbpf/bpftool enablement and fixes since many tests rely
on this
d) CONFIG_DEBUG_INFO_BTF required for many tests but this requires the
build system to have a recent version of pahole tool
Next steps once we have the core kernel support would be porting libbpf
and bpftool for purecap plus work on enabling kselftests as above.
Kernel branch available at:
https://git.morello-project.org/zdleaf/linux/-/tree/morello/bpf_v2
Associated LTP test/changes at:
https://git.morello-project.org/zdleaf/morello-linux-test-project/-/tree/mo…
Thanks,
Zach
[1] [RFC PATCH 0/9] update bpf syscall for PCuABI/compat64
https://op-lists.linaro.org/archives/list/linux-morello@op-lists.linaro.org…
[2] [PATCH 00/10] update bpf syscall for PCuABI/compat64
https://op-lists.linaro.org/archives/list/linux-morello@op-lists.linaro.org…
[3] [PATCH v3 0/5] Restore syscall tracing on Morello
https://op-lists.linaro.org/archives/list/linux-morello@op-lists.linaro.org…
[4] [PATCH 0/3] add eBPF support
https://op-lists.linaro.org/archives/list/linux-morello-ltp@op-lists.linaro…
-----------------------------------------------------------------------
v2:
- Fixed copy_from_bpfptr_offset_with_ptr - this no longer uses sockptr
as of 6.1 (see patch 9)
- Rebase on 6.4 - new struct members need conversion/handling:
- New BPF_PROG_TYPE_NETFILTER + associated bpf_attr BPF_LINK_CREATE
members
- New bpf_link_info types BPF_LINK_TYPE_NETFILTER +
BPF_LINK_TYPE_STRUCT_OPS
- Renamed in_32bit_compat_syscall() to in_compat32_syscall() and added
in_compat64_syscall()
- Handled uaccess from bpf helper programs
bpf/helpers.c:bpf_copy_from_user + bpf_copy_from_user_task
- Added new stddef.h macro copy_field() to simplify conversion
assignments
- bpf: compat64: add handler and convert bpf_attr in
- Replaced #ifdef CONFIG_COMPAT64 with in_compat64_syscall() + use
copy_bpf_attr_from_user() helper function for inbound compat
conversion
- This removes the __sys_compat_bpf compat64 handler, now using the
existing __sys_bpf + in_compat64_syscall() for reduced diff size,
less duplication and clearer code
- Conversion now happens in copy_bpf_attr_from_user() for better
encapsulation + stack usage
- bpf: compat64: bpf_attr convert out
- Renamed PUT_USER_ATTR() to bpf_put_uattr() + moved to bpf.h
- Introduced bpfptr_put_uattr() in bpfptr.h
- Originally missed handling cases writing out to userspace with
copy_to_bpfptr_offset() - now replaced with new bpfptr_put_uattr()
macro
- 6.4 now has a new field showing what log size will be needed - see
47a71c1f9af0 ("bpf: Add log_true_size output field to return
necessary log buffer size")
- This also requires new macro bpf_field_exists() to handle compat64
when checking that userspace supports this new field
- bpf: compat64: handle bpf_xyz_info
- Simplified bpf_link_info conversion handling using memcpy
- Removed bpf_map_info patch since struct is the same in
compat64/native (no ptrs)
- Replaced #ifdef CONFIG_COMPAT64 with in_compat64_syscall() + use
copy_bpf_xyz_info_{from,to}_user() helper functions for compat
conversions
- Merged bpf_{btf,prog,link}_info into a single patch
- bpf: use user pointer types in uAPI structs
- Added new compat_uptr_to_kern() macro to simplify casting/converting
in compat ptrs
- Usage of copy_{to,from}_user_with_ptr variants now correctly applied
with new helpers
-----------------------------------------------------------------------
Zachary Leaf (12):
arm64: morello: enable syscall tracing
arch: rename to in_compat32_syscall
arch: add compat helpers specific to 64-bit
stddef: introduce copy_field helper
bpf: compat64: add handler and convert bpf_attr in
bpf: compat64: bpf_attr convert out
bpf: compat64: handle bpf_xyz_info
bpf: compat64: support CHECK_ATTR macro
bpf: copy_{to,from}_user_with_ptr helpers
bpf: use user pointer types in uAPI structs
bpf: use addr for bpf_copy_from_user_with_task
bpf: use addr for bpf_copy_from_user
.../morello_transitional_pcuabi_defconfig | 3 +-
arch/arm64/include/asm/compat.h | 5 +
arch/sparc/include/asm/compat.h | 2 +-
arch/x86/include/asm/compat.h | 2 +-
drivers/gpu/drm/amd/amdkfd/kfd_chardev.c | 2 +-
drivers/gpu/drm/amd/amdkfd/kfd_process.c | 2 +-
drivers/input/input.c | 2 +-
drivers/media/rc/bpf-lirc.c | 7 +-
fs/ext4/dir.c | 2 +-
fs/nfs/dir.c | 2 +-
include/linux/bpf.h | 13 +
include/linux/bpf_compat.h | 423 ++++++++
include/linux/bpfptr.h | 27 +-
include/linux/compat.h | 14 +-
include/linux/stddef.h | 3 +
include/uapi/linux/bpf.h | 94 +-
kernel/bpf/bpf_iter.c | 2 +-
kernel/bpf/btf.c | 100 +-
kernel/bpf/cgroup.c | 10 +-
kernel/bpf/hashtab.c | 13 +-
kernel/bpf/helpers.c | 9 +-
kernel/bpf/net_namespace.c | 7 +-
kernel/bpf/offload.c | 2 +-
kernel/bpf/syscall.c | 991 ++++++++++++++----
kernel/bpf/verifier.c | 21 +-
kernel/time/time.c | 2 +-
kernel/trace/bpf_trace.c | 6 +-
net/bpf/bpf_dummy_struct_ops.c | 9 +-
net/bpf/test_run.c | 32 +-
net/core/sock_map.c | 7 +-
30 files changed, 1449 insertions(+), 365 deletions(-)
create mode 100644 include/linux/bpf_compat.h
--
2.34.1
Next version of Harry's tcp_zerocopy_receive series. It aims to enable
purecap applications to utilise tcp_zerocopy_receive to map packets
directly from a network interface card into a shared space with the
process and kernel.
v3..v4:
- Remove function tcp_zerocopy_receive_size() as it's used in only
one spot
- Change form compat to compat64 in the commit messages.
- Make initialisation of compat_zc more compact in
set_compat64_tcp_zerocopy_receive()
- Split copy_{from,to}_sockptr_with_ptr() into a separate commit
- Leave address tcp_zerocopy_vm_insert_batch() as just an address, not
a pointer
- Change the check_user_ptr_read() to a check for CHERI_PERM_SW_VMEM
v2..v3:
- Fix the split between compat enablement and capability support
- Reorganise comments in struct tcp_zerocopy_receive
- Fix the order of arguments for the *_to_sockptr functions
- Change a few variables to user_uintptr_t as they were originally
unsigned long
- Remove unnecessary checks
- Fix cast warnings
- Add compat handling for offsetofend
- Move a check_user_ptr closer to where its metadata is dropped
- Format misc nits
Gitlab Issue:
https://git.morello-project.org/morello/kernel/linux/-/issues/46
Review branch:
https://git.morello-project.org/tudcre01/linux/-/commits/morello/tcp_v4
Cc: Harry Ramsey <harry.ramsey(a)arm.com>
Harry Ramsey (3):
sockptr: Preserve capability tags with copy_{from,to}_sockptr_with_ptr
tcp: Implement compat64 handling for struct tcp_zerocopy_receive
tcp: Support capabilities in tcp_zerocopy_receive
include/linux/sockptr.h | 28 ++++++++
include/uapi/linux/tcp.h | 10 +--
net/ipv4/tcp.c | 148 +++++++++++++++++++++++++++++++--------
3 files changed, 151 insertions(+), 35 deletions(-)
--
2.34.1
Next version of Harry's tcp_zerocopy_receive series. It aims to enable
purecap applications to utilise tcp_zerocopy_receive to map packets
directly from a network interface card into a shared space with the
process and kernel.
v2..v3:
- Fix the split between compat enablement and capability support
- Reorganise comments in struct tcp_zerocopy_receive
- Fix the order of arguments for the *_to_sockptr functions
- Change a few variables to user_uintptr_t as they were originally
unsigned long
- Remove unnecessary checks
- Fix cast warnings
- Add compat handling for offsetofend
- Move a check_user_ptr closer to where its metadata is dropped
- Format misc nits
Gitlab Issue:
https://git.morello-project.org/morello/kernel/linux/-/issues/46
Review branch:
https://git.morello-project.org/tudcre01/linux/-/commits/morello/tcp_v3
Cc: Harry Ramsey <harry.ramsey(a)arm.com>
Harry Ramsey (2):
tcp: Implement compat handling for struct tcp_zerocopy_receive
tcp: Support capabilities in tcp_zerocopy_receive
include/linux/sockptr.h | 28 +++++++
include/uapi/linux/tcp.h | 10 +--
net/ipv4/tcp.c | 157 +++++++++++++++++++++++++++++++--------
3 files changed, 157 insertions(+), 38 deletions(-)
--
2.34.1
Hello,
This patch series enables purecap applications to utilise
tcp_zerocopy_receive to map packets directly from a network interface
card into a shared space with the process and kernel.
I do not think I shall have time to continue revising this patch series
and debugging the bus error generated by the latest patch. Hopefully
this provides a start to tcp_zerocopy_receive for capability
architecture.
v2:
- There appears to be a new error generated against musl resulting in a
BUS error when using memcpy to copy between allocated shared space
and other regions of memory.
- Rebase patch order to ensure aarch64 support throughout commits.
- Fix naming convention format issues for compat structs and functions.
- Remove uaddr_to_user_ptr usage to enforce capability model.
v1:
I have tested these changes against musl and there still exists an issue
in this implementation with copybuf and potentially msg_control
generating an EFAULT error.
Gitlab Issue:
- https://git.morello-project.org/morello/kernel/linux/-/issues/46
Review branch:
- https://git.morello-project.org/harryramsey/linux/-/commits/tcp_zerocopy
Thanks,
Harry
Harry Ramsey (2):
tcp: Implement compat version of tcp_zerocopy_receive
tcp: Support userspace capabilities for tcp_zerocopy_receive
include/linux/sockptr.h | 28 ++++++++
include/uapi/linux/tcp.h | 6 +-
net/ipv4/tcp.c | 135 ++++++++++++++++++++++++++++++++++-----
3 files changed, 149 insertions(+), 20 deletions(-)
--
2.34.1
Hello,
This patch series enables purecap applications to utilise
tcp_zerocopy_receive to map packets directly from a network interface
card into a shared space with the process and kernel.
I have tested these changes against musl and there still exists an issue
in this implementation with copybuf and potentially msg_control
generating an EFAULT error.
Gitlab Issue:
- https://git.morello-project.org/morello/kernel/linux/-/issues/46
Review branch:
- https://git.morello-project.org/harryramsey/linux/-/commits/tcp_zerocopy
Thanks,
Harry
Harry Ramsey (2):
tcp: Support userspace capabilities for tcp_zerocopy_receive
tcp: Implement compat version of tcp_zerocopy_receive
include/linux/sockptr.h | 28 ++++++++++
include/uapi/linux/tcp.h | 27 +++++++---
net/ipv4/tcp.c | 111 +++++++++++++++++++++++++++++++++------
3 files changed, 145 insertions(+), 21 deletions(-)
--
2.34.1
Now that explicit capability checking is carried out in the core
kernel and the drivers that are already supported in PCuABI, add a
section to the porting guide explaining in which situations explicit
checking might be required and what should be done.
Also add a few notes to the table of code examples, to make it clear
that using the new user pointer API is not necessarily enough in
itself.
Signed-off-by: Kevin Brodsky <kevin.brodsky(a)arm.com>
---
A follow-up to Luca's explicit checking series.
Rendered doc:
https://git.morello-project.org/kbrodsky-arm/linux/-/blob/porting_guide_exp…
Documentation/cheri/pcuabi-porting.rst | 81 +++++++++++++++++++++-----
1 file changed, 67 insertions(+), 14 deletions(-)
diff --git a/Documentation/cheri/pcuabi-porting.rst b/Documentation/cheri/pcuabi-porting.rst
index 2a38862e869a..fcda3b0f1d83 100644
--- a/Documentation/cheri/pcuabi-porting.rst
+++ b/Documentation/cheri/pcuabi-porting.rst
@@ -15,20 +15,25 @@ The appropriate API to represent and convert user pointers is described
in the `user pointer documentation`_. A few examples of modifications
required for PCuABI compliance:
-+--------------------------------+------------------------------------+
-| Invalid code | Potential replacement |
-+================================+====================================+
-| ``(unsigned long)uptr`` | ``user_ptr_addr(uptr)`` |
-+--------------------------------+------------------------------------+
-| ``(void __user *)u64`` | | ``uaddr_to_user_ptr(u64)`` |
-| | | ``as_user_ptr(u64)`` |
-+--------------------------------+------------------------------------+
-| ``get_user(uptr, &uarg->ptr)`` | ``get_user_ptr(uptr, &uarg->ptr)`` |
-+--------------------------------+------------------------------------+
-| ``IS_ERR(ubuf)`` | ``USER_PTR_IS_ERR(ubuf)`` |
-+--------------------------------+------------------------------------+
-| ... | ... |
-+--------------------------------+------------------------------------+
++--------------------------------+------------------------------------+------------------------------------------+
+| Invalid code | Potential replacement | Notes |
++================================+====================================+==========================================+
+| ``(unsigned long)uptr`` | ``user_ptr_addr(uptr)`` | Extracting the address of a user pointer |
+| | | may indicate that explicit capability |
+| | | checking is required, see the |
+| | | `Explicit capability checking`_ section. |
++--------------------------------+------------------------------------+------------------------------------------+
+| ``(void __user *)u64`` | | ``uaddr_to_user_ptr(u64)`` | Creating a user pointer from an address |
+| | | ``as_user_ptr(u64)`` | should be avoided. |
+| | | uapi structs may need to be modified to |
+| | | hold full user pointers. |
++--------------------------------+------------------------------------+------------------------------------------+
+| ``get_user(uptr, &uarg->ptr)`` | ``get_user_ptr(uptr, &uarg->ptr)`` | |
++--------------------------------+------------------------------------+------------------------------------------+
+| ``IS_ERR(ubuf)`` | ``USER_PTR_IS_ERR(ubuf)`` | |
++--------------------------------+------------------------------------+------------------------------------------+
+| ... | ... | |
++--------------------------------+------------------------------------+------------------------------------------+
``ioctl`` handlers' third argument
==================================
@@ -363,6 +368,54 @@ of the `PCuABI documentation`_. For instance::
Fortunately, ``__user`` is mostly used in simple types, and such fixups
are rarely needed in driver code.
+Explicit capability checking
+============================
+
+In the vast majority of cases, the memory referenced by user pointers is
+accessed through the user mapping, using uaccess functions such as
+``copy_from_user()``. As long as the original user pointer is wholly
+propagated to the uaccess function, no particular attention is required.
+
+In certain situations, such accesses may instead occur via a kernel
+mapping (of the same underlying pages). Often, this kernel mapping is
+created by a function in the GUP family (``get_user_pages()``,
+``pin_user_pages()``). These cases should be carefully considered and
+typically require the user pointer to be explicitly checked (see below).
+
+The following code patterns may indicate that user memory is being
+accessed via a kernel mapping:
+
+* A call to any function named ``get_user_pages*`` or
+ ``pin_user_pages*``. Explicit checking is generally required before
+ calling such a function. Note that this does not normally apply to
+ ``{get,pin}_user_pages_remote()``, because they are intended to access
+ another process's memory and such an operation does not need to (and
+ typically cannot) be authorised by a capability.
+
+* Casting a user pointer to an integer (``(unsigned long)uptr``). This
+ typically indicates that an address-based operation, such as GUP, is
+ going to be carried out. ``user_ptr_addr()`` should be used instead of
+ the cast, but the way the address is used should also be carefully
+ considered.
+
+* Calling ``access_ok()``. Standard uaccess functions call that function
+ themselves, so an explicit call indicates either that a low-level
+ uaccess function (e.g. ``__copy_from_user()``) is going to be used -
+ which is fine - or that the access is not going to be done via uaccess
+ at all - which requires explicit checking. Note that ``access_ok()``
+ does not itself require a valid capability (i.e. it only considers the
+ address) and ``as_user_ptr()`` may occasionally be needed to pass it
+ a raw user address, but in general a full user pointer should be
+ provided by userspace and validated (either by uaccess or explicit
+ checking).
+
+Explicit checking should be done using one of the ``check_user_ptr_*()``
+functions, see the "Explicit checking" section of the `user pointer
+documentation`_. The required permissions (R/W/RW) should be minimal: if
+the kernel only reads memory via the pointer, then
+``check_user_ptr_read()`` should be used, so that a pointer without
+write permission will pass the check.
+
.. _user pointer documentation: Documentation/core-api/user_ptr.rst
.. _PCuABI documentation: Documentation/cheri/pcuabi.rst
.. _pure-capability kernel-user ABI: `PCuABI documentation`_
--
2.38.1
Hi,
This small series disables KSM (Kernel Samepage Merging) in the Morello
defconfig, as it is currently unsafe in the presence of tags - see patch
1 for details. To guarantee correctness even if it is manually enabled,
patch 2 forces memcmp_pages() to report a difference.
It is quite possible that KSM would still be worthwhile even with the
extra cost of comparing tags. Issue #62 [1] covers that investigation.
Review branch:
https://git.morello-project.org/kbrodsky-arm/linux/-/commits/morello/disabl…
Cheers,
Kevin
[1] https://git.morello-project.org/morello/kernel/linux/-/issues/62
Kevin Brodsky (2):
arm64: morello: Disable KSM in defconfig
arm64: morello: Make memcmp_pages() always report a difference
.../configs/morello_transitional_pcuabi_defconfig | 1 -
arch/arm64/kernel/morello.c | 14 ++++++++++++++
2 files changed, 14 insertions(+), 1 deletion(-)
--
2.38.1
Hi,
This is a short series that makes a few simplifications we can now
afford: getting rid of morello_capcpy(), as it is unnecessary now that
the kernel is a "proper" hybrid binary with a tag-preserving memcpy();
and making use of <linux/cheri.h> to simplify includes.
The Morello helpers could be further simplified by reimplementing many
of them in C instead of assembly, issue #61 [1] was created to that end.
Review branch:
https://git.morello-project.org/kbrodsky-arm/linux/-/commits/morello/cheri_…
Cheers,
Kevin
[1] https://git.morello-project.org/morello/kernel/linux/-/issues/61
Kevin Brodsky (3):
arm64: morello: Replace morello_capcpy() with standard copy
arm64: Replace cheriintrin.h with linux/cheri.h
lib: Replace cheriintrin.h with linux/cheri.h
arch/arm64/include/asm/morello.h | 6 ------
arch/arm64/kernel/process.c | 9 +--------
arch/arm64/kernel/signal.c | 5 +----
arch/arm64/lib/morello.S | 18 ------------------
lib/test_printf.c | 4 +---
lib/vsprintf.c | 5 +----
6 files changed, 4 insertions(+), 43 deletions(-)
--
2.38.1