[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20241203-udmabuf-fixes-v1-0-f99281c345aa@google.com>
Date: Tue, 03 Dec 2024 18:25:34 +0100
From: Jann Horn <jannh@...gle.com>
To: Gerd Hoffmann <kraxel@...hat.com>,
Vivek Kasireddy <vivek.kasireddy@...el.com>,
Sumit Semwal <sumit.semwal@...aro.org>,
Christian König <christian.koenig@....com>,
Simona Vetter <simona.vetter@...ll.ch>,
John Stultz <john.stultz@...aro.org>,
Andrew Morton <akpm@...ux-foundation.org>,
"Joel Fernandes (Google)" <joel@...lfernandes.org>
Cc: dri-devel@...ts.freedesktop.org, linux-media@...r.kernel.org,
linaro-mm-sig@...ts.linaro.org, linux-kernel@...r.kernel.org,
Jann Horn <jannh@...gle.com>, Julian Orth <ju.orth@...il.com>,
stable@...r.kernel.org
Subject: [PATCH 0/3] fixes for udmabuf (memfd sealing checks and a leak)
I have tested that patches 2 and 3 work using the following reproducers.
I did not write a reproducer for the issue described in patch 1.
Reproducer for F_SEAL_FUTURE_WRITE not being respected:
```
#define _GNU_SOURCE
#include <err.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <linux/udmabuf.h>
#define SYSCHK(x) ({ \
typeof(x) __res = (x); \
if (__res == (typeof(x))-1) \
err(1, "SYSCHK(" #x ")"); \
__res; \
})
int main(void) {
int memfd = SYSCHK(memfd_create("test", MFD_ALLOW_SEALING));
SYSCHK(ftruncate(memfd, 0x1000));
SYSCHK(fcntl(memfd, F_ADD_SEALS, F_SEAL_SHRINK|F_SEAL_FUTURE_WRITE));
int udmabuf_fd = SYSCHK(open("/dev/udmabuf", O_RDWR));
struct udmabuf_create create_arg = {
.memfd = memfd,
.flags = 0,
.offset = 0,
.size = 0x1000
};
int buf_fd = SYSCHK(ioctl(udmabuf_fd, UDMABUF_CREATE, &create_arg));
printf("created udmabuf buffer fd %d\n", buf_fd);
char *map = SYSCHK(mmap(NULL, 0x1000, PROT_READ|PROT_WRITE, MAP_SHARED, buf_fd, 0));
*map = 'a';
}
```
Reproducer for the memory leak (if you run this for a while, your memory
usage will steadily go up, and /sys/kernel/debug/dma_buf/bufinfo will
contain a ton of entries):
```
#define _GNU_SOURCE
#include <err.h>
#include <errno.h>
#include <assert.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/resource.h>
#include <linux/udmabuf.h>
#define SYSCHK(x) ({ \
typeof(x) __res = (x); \
if (__res == (typeof(x))-1) \
err(1, "SYSCHK(" #x ")"); \
__res; \
})
int main(void) {
int memfd = SYSCHK(memfd_create("test", MFD_ALLOW_SEALING));
SYSCHK(ftruncate(memfd, 0x1000));
SYSCHK(fcntl(memfd, F_ADD_SEALS, F_SEAL_SHRINK));
int udmabuf_fd = SYSCHK(open("/dev/udmabuf", O_RDWR));
// prevent creating new FDs
struct rlimit rlim = { .rlim_cur = 1, .rlim_max = 1 };
SYSCHK(setrlimit(RLIMIT_NOFILE, &rlim));
while (1) {
struct udmabuf_create create_arg = {
.memfd = memfd,
.flags = 0,
.offset = 0,
.size = 0x1000
};
int buf_fd = ioctl(udmabuf_fd, UDMABUF_CREATE, &create_arg);
assert(buf_fd == -1);
assert(errno == EMFILE);
}
}
```
Signed-off-by: Jann Horn <jannh@...gle.com>
---
Jann Horn (3):
udmabuf: fix racy memfd sealing check
udmabuf: also check for F_SEAL_FUTURE_WRITE
udmabuf: fix memory leak on last export_udmabuf() error path
drivers/dma-buf/udmabuf.c | 36 ++++++++++++++++++++----------------
1 file changed, 20 insertions(+), 16 deletions(-)
---
base-commit: b86545e02e8c22fb89218f29d381fa8e8b91d815
change-id: 20241203-udmabuf-fixes-d0435ebab663
--
Jann Horn <jannh@...gle.com>
Powered by blists - more mailing lists