A previous fixup to this commit fixed one issue, but introduced another:
we're now overly strict when validating the src address for UFFDIO_COPY.
Most of the validation in validate_range is useful to apply to src as
well as dst, but page alignment is only a requirement for dst, not src.
So, split the function up so src can use an "unaligned" variant, while
still allowing us to share the majority of the code between the
different cases.
Reported-by: Ryan Roberts <ryan.roberts(a)arm.com>
Closes: https://lore.kernel.org/linux-mm/8fbb5965-28f7-4e9a-ac04-1406ed8fc2d4@arm.c…
Signed-off-by: Axel Rasmussen <axelrasmussen(a)google.com>
---
fs/userfaultfd.c | 18 +++++++++++++-----
1 file changed, 13 insertions(+), 5 deletions(-)
diff --git a/fs/userfaultfd.c b/fs/userfaultfd.c
index bb5c474a0a77..1091cb461747 100644
--- a/fs/userfaultfd.c
+++ b/fs/userfaultfd.c
@@ -1287,13 +1287,11 @@ static __always_inline void wake_userfault(struct userfaultfd_ctx *ctx,
__wake_userfault(ctx, range);
}
-static __always_inline int validate_range(struct mm_struct *mm,
- __u64 start, __u64 len)
+static __always_inline int validate_unaligned_range(
+ struct mm_struct *mm, __u64 start, __u64 len)
{
__u64 task_size = mm->task_size;
- if (start & ~PAGE_MASK)
- return -EINVAL;
if (len & ~PAGE_MASK)
return -EINVAL;
if (!len)
@@ -1309,6 +1307,15 @@ static __always_inline int validate_range(struct mm_struct *mm,
return 0;
}
+static __always_inline int validate_range(struct mm_struct *mm,
+ __u64 start, __u64 len)
+{
+ if (start & ~PAGE_MASK)
+ return -EINVAL;
+
+ return validate_unaligned_range(mm, start, len);
+}
+
static int userfaultfd_register(struct userfaultfd_ctx *ctx,
unsigned long arg)
{
@@ -1759,7 +1766,8 @@ static int userfaultfd_copy(struct userfaultfd_ctx *ctx,
sizeof(uffdio_copy)-sizeof(__s64)))
goto out;
- ret = validate_range(ctx->mm, uffdio_copy.src, uffdio_copy.len);
+ ret = validate_unaligned_range(ctx->mm, uffdio_copy.src,
+ uffdio_copy.len);
if (ret)
goto out;
ret = validate_range(ctx->mm, uffdio_copy.dst, uffdio_copy.len);
--
2.41.0.640.ga95def55d0-goog
As is described in the "How to use MPTCP?" section in MPTCP wiki [1]:
"Your app should create sockets with IPPROTO_MPTCP as the proto:
( socket(AF_INET, SOCK_STREAM, IPPROTO_MPTCP); ). Legacy apps can be
forced to create and use MPTCP sockets instead of TCP ones via the
mptcpize command bundled with the mptcpd daemon."
But the mptcpize (LD_PRELOAD technique) command has some limitations
[2]:
- it doesn't work if the application is not using libc (e.g. GoLang
apps)
- in some envs, it might not be easy to set env vars / change the way
apps are launched, e.g. on Android
- mptcpize needs to be launched with all apps that want MPTCP: we could
have more control from BPF to enable MPTCP only for some apps or all the
ones of a netns or a cgroup, etc.
- it is not in BPF, we cannot talk about it at netdev conf.
So this patchset attempts to use BPF to implement functions similer to
mptcpize.
The main idea is to add a hook in sys_socket() to change the protocol id
from IPPROTO_TCP (or 0) to IPPROTO_MPTCP.
[1]
https://github.com/multipath-tcp/mptcp_net-next/wiki
[2]
https://github.com/multipath-tcp/mptcp_net-next/issues/79
v11:
- add comments about outputs of 'ss' and 'nstat'.
- use "err = verify_mptcpify()" instead of using =+.
v10:
- drop "#ifdef CONFIG_BPF_JIT".
- include vmlinux.h and bpf_tracing_net.h to avoid defining some
macros.
- drop unneeded checks for mptcp.
v9:
- update comment for 'update_socket_protocol'.
v8:
- drop the additional checks on the 'protocol' value after the
'update_socket_protocol()' call.
v7:
- add __weak and __diag_* for update_socket_protocol.
v6:
- add update_socket_protocol.
v5:
- add bpf_mptcpify helper.
v4:
- use lsm_cgroup/socket_create
v3:
- patch 8: char cmd[128]; -> char cmd[256];
v2:
- Fix build selftests errors reported by CI
Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/79
Geliang Tang (5):
bpf: Add update_socket_protocol hook
selftests/bpf: Use random netns name for mptcp
selftests/bpf: Add two mptcp netns helpers
selftests/bpf: Drop unneeded checks for mptcp
selftests/bpf: Add mptcpify test
net/mptcp/bpf.c | 15 ++
net/socket.c | 24 +++
.../testing/selftests/bpf/prog_tests/mptcp.c | 139 +++++++++++++++---
tools/testing/selftests/bpf/progs/mptcpify.c | 20 +++
4 files changed, 179 insertions(+), 19 deletions(-)
create mode 100644 tools/testing/selftests/bpf/progs/mptcpify.c
--
2.35.3
iommufd gives userspace the capability to manipulate iommu subsytem.
e.g. DMA map/unmap etc. In the near future, it will support iommu nested
translation. Different platform vendors have different implementation for
the nested translation. For example, Intel VT-d supports using guest I/O
page table as the stage-1 translation table. This requires guest I/O page
table be compatible with hardware IOMMU. So before set up nested translation,
userspace needs to know the hardware iommu information to understand the
nested translation requirements.
This series reports the iommu hardware information for a given device
which has been bound to iommufd. It is preparation work for userspace to
allocate hwpt for given device. Like the nested translation support[1].
This series introduces an iommu op to report the iommu hardware info,
and an ioctl IOMMU_GET_HW_INFO is added to report such hardware info to
user. enum iommu_hw_info_type is defined to differentiate the iommu hardware
info reported to user hence user can decode them. This series only adds the
framework for iommu hw info reporting, the complete reporting path needs vendor
specific definition and driver support. The full code is available in [1]
as well.
[1] https://github.com/yiliu1765/iommufd/tree/wip/iommufd_nesting_08082023-yi
(only the hw_info report path is the latest, other parts is wip)
Change log:
v6:
- Add Jingqi's comment on patch 02
- Add Baolu's r-b to patch 03
- Address Jason's comment on patch 03
v5: https://lore.kernel.org/linux-iommu/20230803143144.200945-1-yi.l.liu@intel.…
- Return hw_info_type in the .hw_info op, hence drop hw_info_type field in iommu_ops (Kevin)
- Add Jason's r-b for patch 01
- Address coding style comments from Jason and Kevin w.r.t. patch 02, 03 and 04
v4: https://lore.kernel.org/linux-iommu/20230724105936.107042-1-yi.l.liu@intel.…
- Rename ioctl to IOMMU_GET_HW_INFO and structure to iommu_hw_info
- Move the iommufd_get_hw_info handler to main.c
- Place iommu_hw_info prior to iommu_hwpt_alloc
- Update the function namings accordingly
- Update uapi kdocs
v3: https://lore.kernel.org/linux-iommu/20230511143024.19542-1-yi.l.liu@intel.c…
- Add r-b from Baolu
- Rename IOMMU_HW_INFO_TYPE_DEFAULT to be IOMMU_HW_INFO_TYPE_NONE to
better suit what it means
- Let IOMMU_DEVICE_GET_HW_INFO succeed even the underlying iommu driver
does not have driver-specific data to report per below remark.
https://lore.kernel.org/kvm/ZAcwJSK%2F9UVI9LXu@nvidia.com/
v2: https://lore.kernel.org/linux-iommu/20230309075358.571567-1-yi.l.liu@intel.…
- Drop patch 05 of v1 as it is already covered by other series
- Rename the capability info to be iommu hardware info
v1: https://lore.kernel.org/linux-iommu/20230209041642.9346-1-yi.l.liu@intel.co…
Regards,
Yi Liu
Lu Baolu (1):
iommu: Add new iommu op to get iommu hardware information
Nicolin Chen (1):
iommufd/selftest: Add coverage for IOMMU_GET_HW_INFO ioctl
Yi Liu (2):
iommu: Move dev_iommu_ops() to private header
iommufd: Add IOMMU_GET_HW_INFO
drivers/iommu/iommu-priv.h | 11 +++
drivers/iommu/iommufd/iommufd_test.h | 9 ++
drivers/iommu/iommufd/main.c | 97 +++++++++++++++++++
drivers/iommu/iommufd/selftest.c | 16 +++
include/linux/iommu.h | 20 ++--
include/uapi/linux/iommufd.h | 45 +++++++++
tools/testing/selftests/iommu/iommufd.c | 17 +++-
tools/testing/selftests/iommu/iommufd_utils.h | 26 +++++
8 files changed, 229 insertions(+), 12 deletions(-)
--
2.34.1
Add new feature checks and provide testing item to support capturing
SIGBUS exception signal.
The following is a log snippet from my local testing environment:
~~~
TAP version 13
1..90
# CRC32 present
ok 1 cpuinfo_match_CRC32
ok 2 sigill_CRC32
ok 3 # SKIP sigbus_CRC32
ok 4 cpuinfo_match_CSSC
# sigill_reported for CSSC
ok 5 # SKIP sigill_CSSC
ok 6 # SKIP sigbus_CSSC
# FP present
ok 7 cpuinfo_match_FP
ok 8 sigill_FP
ok 9 # SKIP sigbus_FP
# LRCPC present
ok 10 cpuinfo_match_LRCPC
ok 11 sigill_LRCPC
ok 12 # SKIP sigbus_LRCPC
# LRCPC2 present
ok 13 cpuinfo_match_LRCPC2
ok 14 sigill_LRCPC2
ok 15 # SKIP sigbus_LRCPC2
# LSE present
ok 16 cpuinfo_match_LSE
ok 17 sigill_LSE
ok 18 # SKIP sigbus_LSE
# LSE2 present
ok 19 cpuinfo_match_LSE2
ok 20 sigill_LSE2
ok 21 sigbus_LSE2
ok 22 cpuinfo_match_MOPS
ok 23 sigill_MOPS
ok 24 # SKIP sigbus_MOPS
# RNG present
ok 25 cpuinfo_match_RNG
ok 26 sigill_RNG
ok 27 # SKIP sigbus_RNG
ok 28 cpuinfo_match_RPRFM
ok 29 # SKIP sigill_RPRFM
ok 30 # SKIP sigbus_RPRFM
ok 31 cpuinfo_match_SME
ok 32 sigill_SME
ok 33 # SKIP sigbus_SME
ok 34 cpuinfo_match_SME2
ok 35 sigill_SME2
ok 36 # SKIP sigbus_SME2
ok 37 cpuinfo_match_SME 2.1
# sigill_reported for SME 2.1
ok 38 # SKIP sigill_SME 2.1
ok 39 # SKIP sigbus_SME 2.1
ok 40 cpuinfo_match_SME I16I32
# sigill_reported for SME I16I32
ok 41 # SKIP sigill_SME I16I32
ok 42 # SKIP sigbus_SME I16I32
ok 43 cpuinfo_match_SME BI32I32
# sigill_reported for SME BI32I32
ok 44 # SKIP sigill_SME BI32I32
ok 45 # SKIP sigbus_SME BI32I32
ok 46 cpuinfo_match_SME B16B16
# sigill_reported for SME B16B16
ok 47 # SKIP sigill_SME B16B16
ok 48 # SKIP sigbus_SME B16B16
ok 49 cpuinfo_match_SME F16F16
# sigill_reported for SME F16F16
ok 50 # SKIP sigill_SME F16F16
ok 51 # SKIP sigbus_SME F16F16
# SVE present
ok 52 cpuinfo_match_SVE
ok 53 sigill_SVE
ok 54 # SKIP sigbus_SVE
ok 55 cpuinfo_match_SVE 2
# sigill_reported for SVE 2
ok 56 # SKIP sigill_SVE 2
ok 57 # SKIP sigbus_SVE 2
ok 58 cpuinfo_match_SVE 2.1
# sigill_reported for SVE 2.1
ok 59 # SKIP sigill_SVE 2.1
ok 60 # SKIP sigbus_SVE 2.1
ok 61 cpuinfo_match_SVE AES
# sigill_reported for SVE AES
ok 62 # SKIP sigill_SVE AES
ok 63 # SKIP sigbus_SVE AES
ok 64 cpuinfo_match_SVE2 PMULL
# sigill_reported for SVE2 PMULL
ok 65 # SKIP sigill_SVE2 PMULL
ok 66 # SKIP sigbus_SVE2 PMULL
ok 67 cpuinfo_match_SVE2 BITPERM
# sigill_reported for SVE2 BITPERM
ok 68 # SKIP sigill_SVE2 BITPERM
ok 69 # SKIP sigbus_SVE2 BITPERM
ok 70 cpuinfo_match_SVE2 SHA3
# sigill_reported for SVE2 SHA3
ok 71 # SKIP sigill_SVE2 SHA3
ok 72 # SKIP sigbus_SVE2 SHA3
ok 73 cpuinfo_match_SVE2 SM4
# sigill_reported for SVE2 SM4
ok 74 # SKIP sigill_SVE2 SM4
ok 75 # SKIP sigbus_SVE2 SM4
# SVE2 I8MM present
ok 76 cpuinfo_match_SVE2 I8MM
ok 77 sigill_SVE2 I8MM
ok 78 # SKIP sigbus_SVE2 I8MM
# SVE2 F32MM present
ok 79 cpuinfo_match_SVE2 F32MM
ok 80 sigill_SVE2 F32MM
ok 81 # SKIP sigbus_SVE2 F32MM
# SVE2 F64MM present
ok 82 cpuinfo_match_SVE2 F64MM
ok 83 sigill_SVE2 F64MM
ok 84 # SKIP sigbus_SVE2 F64MM
# SVE2 BF16 present
ok 85 cpuinfo_match_SVE2 BF16
ok 86 sigill_SVE2 BF16
ok 87 # SKIP sigbus_SVE2 BF16
ok 88 cpuinfo_match_SVE2 EBF16
ok 89 # SKIP sigill_SVE2 EBF16
ok 90 # SKIP sigbus_SVE2 EBF16
# Totals: pass:46 fail:0 xfail:0 xpass:0 skip:44 error:0
~~~
Zeng Heng (5):
kselftest/arm64: add float-point feature to hwcap test
kselftest/arm64: add crc32 feature to hwcap test
kselftest/arm64: add DEF_SIGHANDLER_FUNC() and DEF_INST_RAISE_SIG()
helpers
kselftest/arm64: add test item that support to capturing the SIGBUS
signal
kselftest/arm64: add lse and lse2 features to hwcap test
tools/testing/selftests/arm64/abi/hwcap.c | 201 ++++++++++++++++------
1 file changed, 151 insertions(+), 50 deletions(-)
---
v1 -> v2:
- switch fp and crc32 instructions from hand encode to assemble language.
There is no logical changes between versions.
--
2.25.1
Our ABI opts to provide future proofing by defining a much larger
SVE_VQ_MAX than the architecture actually supports. Since we use
this define to control the size of our vector data buffers this results
in a lot of overhead when we initialise which can be a very noticable
problem in emulation, we fill buffers that are orders of magnitude
larger than we will ever actually use even with virtual platforms that
provide the full range of architecturally supported vector lengths.
Define and use the actual architecture maximum to mitigate this.
Signed-off-by: Mark Brown <broonie(a)kernel.org>
---
tools/testing/selftests/arm64/abi/syscall-abi.c | 38 +++++++++++++++----------
1 file changed, 23 insertions(+), 15 deletions(-)
diff --git a/tools/testing/selftests/arm64/abi/syscall-abi.c b/tools/testing/selftests/arm64/abi/syscall-abi.c
index 18cc123e2347..d704511a0955 100644
--- a/tools/testing/selftests/arm64/abi/syscall-abi.c
+++ b/tools/testing/selftests/arm64/abi/syscall-abi.c
@@ -20,12 +20,20 @@
#include "syscall-abi.h"
+/*
+ * The kernel defines a much larger SVE_VQ_MAX than is expressable in
+ * the architecture, this creates a *lot* of overhead filling the
+ * buffers (especially ZA) on emulated platforms so use the actual
+ * architectural maximum instead.
+ */
+#define ARCH_SVE_VQ_MAX 16
+
static int default_sme_vl;
static int sve_vl_count;
-static unsigned int sve_vls[SVE_VQ_MAX];
+static unsigned int sve_vls[ARCH_SVE_VQ_MAX];
static int sme_vl_count;
-static unsigned int sme_vls[SVE_VQ_MAX];
+static unsigned int sme_vls[ARCH_SVE_VQ_MAX];
extern void do_syscall(int sve_vl, int sme_vl);
@@ -130,9 +138,9 @@ static int check_fpr(struct syscall_cfg *cfg, int sve_vl, int sme_vl,
#define SVE_Z_SHARED_BYTES (128 / 8)
-static uint8_t z_zero[__SVE_ZREG_SIZE(SVE_VQ_MAX)];
-uint8_t z_in[SVE_NUM_ZREGS * __SVE_ZREG_SIZE(SVE_VQ_MAX)];
-uint8_t z_out[SVE_NUM_ZREGS * __SVE_ZREG_SIZE(SVE_VQ_MAX)];
+static uint8_t z_zero[__SVE_ZREG_SIZE(ARCH_SVE_VQ_MAX)];
+uint8_t z_in[SVE_NUM_ZREGS * __SVE_ZREG_SIZE(ARCH_SVE_VQ_MAX)];
+uint8_t z_out[SVE_NUM_ZREGS * __SVE_ZREG_SIZE(ARCH_SVE_VQ_MAX)];
static void setup_z(struct syscall_cfg *cfg, int sve_vl, int sme_vl,
uint64_t svcr)
@@ -190,8 +198,8 @@ static int check_z(struct syscall_cfg *cfg, int sve_vl, int sme_vl,
return errors;
}
-uint8_t p_in[SVE_NUM_PREGS * __SVE_PREG_SIZE(SVE_VQ_MAX)];
-uint8_t p_out[SVE_NUM_PREGS * __SVE_PREG_SIZE(SVE_VQ_MAX)];
+uint8_t p_in[SVE_NUM_PREGS * __SVE_PREG_SIZE(ARCH_SVE_VQ_MAX)];
+uint8_t p_out[SVE_NUM_PREGS * __SVE_PREG_SIZE(ARCH_SVE_VQ_MAX)];
static void setup_p(struct syscall_cfg *cfg, int sve_vl, int sme_vl,
uint64_t svcr)
@@ -222,8 +230,8 @@ static int check_p(struct syscall_cfg *cfg, int sve_vl, int sme_vl,
return errors;
}
-uint8_t ffr_in[__SVE_PREG_SIZE(SVE_VQ_MAX)];
-uint8_t ffr_out[__SVE_PREG_SIZE(SVE_VQ_MAX)];
+uint8_t ffr_in[__SVE_PREG_SIZE(ARCH_SVE_VQ_MAX)];
+uint8_t ffr_out[__SVE_PREG_SIZE(ARCH_SVE_VQ_MAX)];
static void setup_ffr(struct syscall_cfg *cfg, int sve_vl, int sme_vl,
uint64_t svcr)
@@ -300,8 +308,8 @@ static int check_svcr(struct syscall_cfg *cfg, int sve_vl, int sme_vl,
return errors;
}
-uint8_t za_in[ZA_SIG_REGS_SIZE(SVE_VQ_MAX)];
-uint8_t za_out[ZA_SIG_REGS_SIZE(SVE_VQ_MAX)];
+uint8_t za_in[ZA_SIG_REGS_SIZE(ARCH_SVE_VQ_MAX)];
+uint8_t za_out[ZA_SIG_REGS_SIZE(ARCH_SVE_VQ_MAX)];
static void setup_za(struct syscall_cfg *cfg, int sve_vl, int sme_vl,
uint64_t svcr)
@@ -470,9 +478,9 @@ void sve_count_vls(void)
return;
/*
- * Enumerate up to SVE_VQ_MAX vector lengths
+ * Enumerate up to ARCH_SVE_VQ_MAX vector lengths
*/
- for (vq = SVE_VQ_MAX; vq > 0; vq /= 2) {
+ for (vq = ARCH_SVE_VQ_MAX; vq > 0; vq /= 2) {
vl = prctl(PR_SVE_SET_VL, vq * 16);
if (vl == -1)
ksft_exit_fail_msg("PR_SVE_SET_VL failed: %s (%d)\n",
@@ -496,9 +504,9 @@ void sme_count_vls(void)
return;
/*
- * Enumerate up to SVE_VQ_MAX vector lengths
+ * Enumerate up to ARCH_SVE_VQ_MAX vector lengths
*/
- for (vq = SVE_VQ_MAX; vq > 0; vq /= 2) {
+ for (vq = ARCH_SVE_VQ_MAX; vq > 0; vq /= 2) {
vl = prctl(PR_SME_SET_VL, vq * 16);
if (vl == -1)
ksft_exit_fail_msg("PR_SME_SET_VL failed: %s (%d)\n",
---
base-commit: 52a93d39b17dc7eb98b6aa3edb93943248e03b2f
change-id: 20230809-arm64-syscall-abi-perf-1e5876d161b2
Best regards,
--
Mark Brown <broonie(a)kernel.org>
Replace the original fixed-size log buffer with a dynamically-
extending log.
Patch 1 provides the basic implementation. The following patches
add test cases, support for logging long strings, and an optimization
to the string formatting that is now more thoroughly testable.
Changes since v2:
- Fixed uninitialized string bug in get_concatenated_log().
- Moved get_concatenated_log() into first patch so that
kunit_log_newline_test() dumps the entire log on error.
- Moved kunit_log_frag_sized_line_test() to the correct point in
the chain, after the change that it depends on. Also log another
line after the long line to test that the log extends correctly.
- Added kunit_log_init_frag_test() to test kunit_init_log_frag()
instead of testing it as part of every other test.
Richard Fitzgerald (7):
kunit: Replace fixed-size log with dynamically-extending buffer
kunit: kunit-test: Add test cases for extending log buffer
kunit: Handle logging of lines longer than the fragment buffer size
kunit: kunit-test: Test logging a line that exactly fills a fragment
kunit: kunit-test: Add test cases for logging very long lines
kunit: kunit-test: Add test of logging only a newline
kunit: Don't waste first attempt to format string in
kunit_log_append()
include/kunit/test.h | 25 ++-
lib/kunit/debugfs.c | 65 ++++++--
lib/kunit/kunit-test.c | 339 ++++++++++++++++++++++++++++++++++++++++-
lib/kunit/test.c | 127 ++++++++++++---
4 files changed, 507 insertions(+), 49 deletions(-)
--
2.30.2
It turns out arm32 doesn't handle syscall -1 gracefully, so skip testing
for that. Additionally skip tests that depend on clone3 when it is not
available (for example when building the seccomp selftests on an old arm
image without clone3 headers). And improve error reporting for when
nanosleep fails, as seen on arm32 since v5.15.
Cc: Lecopzer Chen <lecopzer.chen(a)mediatek.com>
Signed-off-by: Kees Cook <keescook(a)chromium.org>
---
tools/testing/selftests/seccomp/seccomp_bpf.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/seccomp/seccomp_bpf.c b/tools/testing/selftests/seccomp/seccomp_bpf.c
index f6a04d88e02f..38f651469968 100644
--- a/tools/testing/selftests/seccomp/seccomp_bpf.c
+++ b/tools/testing/selftests/seccomp/seccomp_bpf.c
@@ -2184,6 +2184,9 @@ FIXTURE_TEARDOWN(TRACE_syscall)
TEST(negative_ENOSYS)
{
+#if defined(__arm__)
+ SKIP(return, "arm32 does not support calling syscall -1");
+#endif
/*
* There should be no difference between an "internal" skip
* and userspace asking for syscall "-1".
@@ -3072,7 +3075,8 @@ TEST(syscall_restart)
timeout.tv_sec = 1;
errno = 0;
EXPECT_EQ(0, nanosleep(&timeout, NULL)) {
- TH_LOG("Call to nanosleep() failed (errno %d)", errno);
+ TH_LOG("Call to nanosleep() failed (errno %d: %s)",
+ errno, strerror(errno));
}
/* Read final sync from parent. */
@@ -3908,6 +3912,9 @@ TEST(user_notification_filter_empty)
TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!");
}
+ if (__NR_clone3 < 0)
+ SKIP(return, "Test not built with clone3 support");
+
pid = sys_clone3(&args, sizeof(args));
ASSERT_GE(pid, 0);
@@ -3962,6 +3969,9 @@ TEST(user_notification_filter_empty_threaded)
TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!");
}
+ if (__NR_clone3 < 0)
+ SKIP(return, "Test not built with clone3 support");
+
pid = sys_clone3(&args, sizeof(args));
ASSERT_GE(pid, 0);
--
2.34.1
This commit removed an extra check for zero-length ranges, and folded it
into the common validate_range() helper used by all UFFD ioctls.
It failed to notice though that UFFDIO_COPY *only* called validate_range
on the dst range, not the src range. So removing this check actually let
us proceed with zero-length source ranges, eventually hitting a BUG
further down in the call stack.
The correct fix seems clear: call validate_range() on the src range too.
Other ioctls are not affected by this, as they only have one range, not
two (src + dst).
Reported-by: syzbot+42309678e0bc7b32f8e9(a)syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=42309678e0bc7b32f8e9
Signed-off-by: Axel Rasmussen <axelrasmussen(a)google.com>
---
fs/userfaultfd.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/fs/userfaultfd.c b/fs/userfaultfd.c
index 53a7220c4679..36d233759233 100644
--- a/fs/userfaultfd.c
+++ b/fs/userfaultfd.c
@@ -1759,6 +1759,9 @@ static int userfaultfd_copy(struct userfaultfd_ctx *ctx,
sizeof(uffdio_copy)-sizeof(__s64)))
goto out;
+ ret = validate_range(ctx->mm, uffdio_copy.src, uffdio_copy.len);
+ if (ret)
+ goto out;
ret = validate_range(ctx->mm, uffdio_copy.dst, uffdio_copy.len);
if (ret)
goto out;
--
2.41.0.255.g8b1d071c50-goog