UDMABUF_CREATE and UDMABUF_CREATE_LIST only define UDMABUF_FLAGS_CLOEXEC. Unknown flag bits were silently masked before returning a dmabuf fd, so userspace could not detect unsupported flags. Reject them with -EINVAL, consistent with dma-heap flag validation.
Document the flag semantics in udmabuf.h and add a selftest. Signed-off-by: Iván Ezequiel Rodriguez <[email protected]> --- drivers/dma-buf/udmabuf.c | 3 +++ include/uapi/linux/udmabuf.h | 13 +++++++++++++ tools/testing/selftests/drivers/dma-buf/udmabuf.c | 14 +++++++++++++- 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c index bced421c0d65..fb36c0d9ffe7 100644 --- a/drivers/dma-buf/udmabuf.c +++ b/drivers/dma-buf/udmabuf.c @@ -358,6 +358,9 @@ static long udmabuf_create(struct miscdevice *device, long ret = -EINVAL; u32 i, flags; + if (head->flags & ~UDMABUF_FLAGS_CLOEXEC) + return -EINVAL; + ubuf = kzalloc(sizeof(*ubuf), GFP_KERNEL); if (!ubuf) return -ENOMEM; diff --git a/include/uapi/linux/udmabuf.h b/include/uapi/linux/udmabuf.h index 46b6532ed855..e267856dd510 100644 --- a/include/uapi/linux/udmabuf.h +++ b/include/uapi/linux/udmabuf.h @@ -7,6 +7,13 @@ #define UDMABUF_FLAGS_CLOEXEC 0x01 +/** + * struct udmabuf_create - parameters for %UDMABUF_CREATE + * @memfd: memfd containing the memory to export + * @flags: %UDMABUF_FLAGS_CLOEXEC only; unknown bits are rejected + * @offset: byte offset into @memfd (page aligned) + * @size: number of bytes to export (page aligned, non-zero) + */ struct udmabuf_create { __u32 memfd; __u32 flags; @@ -21,6 +28,12 @@ struct udmabuf_create_item { __u64 size; }; +/** + * struct udmabuf_create_list - parameters for %UDMABUF_CREATE_LIST + * @flags: %UDMABUF_FLAGS_CLOEXEC only; unknown bits are rejected + * @count: number of entries in @list (non-zero, capped by driver) + * @list: flexible array of memfd regions to combine + */ struct udmabuf_create_list { __u32 flags; __u32 count; diff --git a/tools/testing/selftests/drivers/dma-buf/udmabuf.c b/tools/testing/selftests/drivers/dma-buf/udmabuf.c index d78aec662586..95c781855404 100644 --- a/tools/testing/selftests/drivers/dma-buf/udmabuf.c +++ b/tools/testing/selftests/drivers/dma-buf/udmabuf.c @@ -138,7 +138,7 @@ int main(int argc, char *argv[]) void *addr1, *addr2; ksft_print_header(); - ksft_set_plan(7); + ksft_set_plan(8); devfd = open("/dev/udmabuf", O_RDWR); if (devfd < 0) { @@ -189,6 +189,18 @@ int main(int argc, char *argv[]) else ksft_test_result_pass("%s: [PASS,test-2]\n", TEST_PREFIX); + /* should fail (unknown flags) */ + create.memfd = memfd; + create.offset = 0; + create.size = size; + create.flags = UDMABUF_FLAGS_CLOEXEC | 0x2; + buf = ioctl(devfd, UDMABUF_CREATE, &create); + if (buf >= 0) + ksft_test_result_fail("%s: [FAIL,test-unknown-flags]\n", TEST_PREFIX); + else + ksft_test_result_pass("%s: [PASS,test-unknown-flags]\n", TEST_PREFIX); + create.flags = 0; + /* should fail (not memfd) */ create.memfd = 0; /* stdin */ create.offset = 0; -- 2.43.0
