chiark
/
gitweb
/
~ianmdlvl
/
elogind.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
bus: add minimal locking around the memfd cache
[elogind.git]
/
src
/
libsystemd-bus
/
bus-kernel.c
diff --git
a/src/libsystemd-bus/bus-kernel.c
b/src/libsystemd-bus/bus-kernel.c
index ede78d7befa98969f2f4c47f07d3b32c987f2507..699d24185ea1e1c521fd87c009a58c66030f01bc 100644
(file)
--- a/
src/libsystemd-bus/bus-kernel.c
+++ b/
src/libsystemd-bus/bus-kernel.c
@@
-721,6
+721,7
@@
int bus_kernel_create(const char *name, char **s) {
int bus_kernel_pop_memfd(sd_bus *bus, void **address, size_t *size) {
struct memfd_cache *c;
int bus_kernel_pop_memfd(sd_bus *bus, void **address, size_t *size) {
struct memfd_cache *c;
+ int fd;
assert(address);
assert(size);
assert(address);
assert(size);
@@
-728,8
+729,12
@@
int bus_kernel_pop_memfd(sd_bus *bus, void **address, size_t *size) {
if (!bus || !bus->is_kernel)
return -ENOTSUP;
if (!bus || !bus->is_kernel)
return -ENOTSUP;
+ assert_se(pthread_mutex_lock(&bus->memfd_cache_mutex) == 0);
+
if (bus->n_memfd_cache <= 0) {
if (bus->n_memfd_cache <= 0) {
- int fd, r;
+ int r;
+
+ assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) == 0);
r = ioctl(bus->input_fd, KDBUS_CMD_MEMFD_NEW, &fd);
if (r < 0)
r = ioctl(bus->input_fd, KDBUS_CMD_MEMFD_NEW, &fd);
if (r < 0)
@@
-747,8
+752,18
@@
int bus_kernel_pop_memfd(sd_bus *bus, void **address, size_t *size) {
*address = c->address;
*size = c->size;
*address = c->address;
*size = c->size;
+ fd = c->fd;
+
+ assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) == 0);
- return c->fd;
+ return fd;
+}
+
+static void close_and_munmap(int fd, void *address, size_t size) {
+ if (size > 0)
+ assert_se(munmap(address, PAGE_ALIGN(size)) == 0);
+
+ close_nointr_nofail(fd);
}
void bus_kernel_push_memfd(sd_bus *bus, int fd, void *address, size_t size) {
}
void bus_kernel_push_memfd(sd_bus *bus, int fd, void *address, size_t size) {
@@
-757,13
+772,17
@@
void bus_kernel_push_memfd(sd_bus *bus, int fd, void *address, size_t size) {
assert(fd >= 0);
assert(size == 0 || address);
assert(fd >= 0);
assert(size == 0 || address);
- if (!bus || !bus->is_kernel ||
- bus->n_memfd_cache >= ELEMENTSOF(bus->memfd_cache)) {
+ if (!bus || !bus->is_kernel) {
+ close_and_munmap(fd, address, size);
+ return;
+ }
+
+ assert_se(pthread_mutex_lock(&bus->memfd_cache_mutex) == 0);
- if (size > 0)
-
assert_se(munmap(address, PAGE_ALIGN(size)
) == 0);
+ if (bus->n_memfd_cache >= ELEMENTSOF(bus->memfd_cache)) {
+
assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex
) == 0);
- close_
nointr_nofail(fd
);
+ close_
and_munmap(fd, address, size
);
return;
}
return;
}
@@
-780,6
+799,8
@@
void bus_kernel_push_memfd(sd_bus *bus, int fd, void *address, size_t size) {
c->size = MEMFD_CACHE_ITEM_SIZE_MAX;
} else
c->size = size;
c->size = MEMFD_CACHE_ITEM_SIZE_MAX;
} else
c->size = size;
+
+ assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) == 0);
}
void bus_kernel_flush_memfd(sd_bus *b) {
}
void bus_kernel_flush_memfd(sd_bus *b) {