!685 sync patches from systemd community

From: @wangyuhang27 
Reviewed-by: @licunlong 
Signed-off-by: @licunlong
This commit is contained in:
openeuler-ci-bot 2024-07-05 07:59:07 +00:00 committed by Gitee
commit bd81551f5b
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
2 changed files with 169 additions and 1 deletions

View File

@ -0,0 +1,164 @@
From a4bb56c61a7bfef9bab3380b3c18709ab8fef3d8 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Mon, 22 Apr 2024 05:22:24 +0900
Subject: [PATCH] sd-event: fix fd leak when fd is owned by IO event source
When an IO event source owns relevant fd, replacing with a new fd leaks
the previously assigned fd.
===
sd_event_add_io(event, &s, fd, ...);
sd_event_source_set_io_fd_own(s, true);
sd_event_source_set_io_fd(s, new_fd); <-- The previous fd is not closed.
sd_event_source_unref(s); <-- new_fd is closed as expected.
===
Without the change, valgrind reports the leak:
==998589==
==998589== FILE DESCRIPTORS: 4 open (3 std) at exit.
==998589== Open file descriptor 4:
==998589== at 0x4F119AB: pipe2 (in /usr/lib64/libc.so.6)
==998589== by 0x408830: test_sd_event_source_set_io_fd (test-event.c:862)
==998589== by 0x403302: run_test_table (tests.h:171)
==998589== by 0x408E31: main (test-event.c:935)
==998589==
==998589==
==998589== HEAP SUMMARY:
==998589== in use at exit: 0 bytes in 0 blocks
==998589== total heap usage: 33,305 allocs, 33,305 frees, 1,283,581 bytes allocated
==998589==
==998589== All heap blocks were freed -- no leaks are possible
==998589==
==998589== For lists of detected and suppressed errors, rerun with: -s
==998589== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
(cherry picked from commit 2fa480592d4f4334881361c5558f563e5ea4c9c3)
(cherry picked from commit 6d2dd436429aafcbb3fd8c99f6b69c9a108bf7f9)
(cherry picked from commit 5f8cf63f17c2ab4fecb0e65e6231ae6931270893)
Conflict:test case adaptation
Reference:https://github.com/systemd/systemd-stable/commit/a4bb56c61a7bfef9bab3380b3c18709ab8fef3d8
---
man/sd_event_add_io.xml | 24 ++++++++++++++----------
src/libsystemd/sd-event/sd-event.c | 17 ++++++++---------
src/libsystemd/sd-event/test-event.c | 20 ++++++++++++++++++++
3 files changed, 42 insertions(+), 19 deletions(-)
diff --git a/man/sd_event_add_io.xml b/man/sd_event_add_io.xml
index 323e57c..34d9173 100644
--- a/man/sd_event_add_io.xml
+++ b/man/sd_event_add_io.xml
@@ -217,16 +217,20 @@
source object and returns the non-negative file descriptor
or a negative error number on error (see below).</para>
- <para><function>sd_event_source_set_io_fd()</function>
- changes the UNIX file descriptor of an I/O event source created
- previously with <function>sd_event_add_io()</function>. It takes
- the event source object and the new file descriptor.</para>
-
- <para><function>sd_event_source_set_io_fd_own()</function> controls whether the file descriptor of the event source
- shall be closed automatically when the event source is freed, i.e. whether it shall be considered 'owned' by the
- event source object. By default it is not closed automatically, and the application has to do this on its own. The
- <parameter>b</parameter> parameter is a boolean parameter: if zero, the file descriptor is not closed automatically
- when the event source is freed, otherwise it is closed.</para>
+ <para><function>sd_event_source_set_io_fd()</function> changes the UNIX file descriptor of an I/O event
+ source created previously with <function>sd_event_add_io()</function>. It takes the event source object
+ and the new file descriptor. If the event source takes the ownership of the previous file descriptor,
+ that is, <function>sd_event_source_set_io_fd_own()</function> was called for the event source with a
+ non-zero value, then the previous file descriptor will be closed and the event source will also take the
+ ownership of the new file descriptor on success.</para>
+
+ <para><function>sd_event_source_set_io_fd_own()</function> controls whether the file descriptor of the
+ event source shall be closed automatically when the event source is freed (or when the file descriptor
+ assigned to the event source is replaced by <function>sd_event_source_set_io_fd()</function>), i.e.
+ whether it shall be considered 'owned' by the event source object. By default it is not closed
+ automatically, and the application has to do this on its own. The <parameter>b</parameter> parameter is a
+ boolean parameter: if zero, the file descriptor is not closed automatically when the event source is
+ freed, otherwise it is closed.</para>
<para><function>sd_event_source_get_io_fd_own()</function> may be used to query the current setting of the file
descriptor ownership boolean flag as set with <function>sd_event_source_set_io_fd_own()</function>. It returns
diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c
index bdb60c7..ecc1e4f 100644
--- a/src/libsystemd/sd-event/sd-event.c
+++ b/src/libsystemd/sd-event/sd-event.c
@@ -2141,7 +2141,7 @@ _public_ int sd_event_source_get_io_fd(sd_event_source *s) {
}
_public_ int sd_event_source_set_io_fd(sd_event_source *s, int fd) {
- int r;
+ int saved_fd, r;
assert_return(s, -EINVAL);
assert_return(fd >= 0, -EBADF);
@@ -2151,16 +2151,12 @@ _public_ int sd_event_source_set_io_fd(sd_event_source *s, int fd) {
if (s->io.fd == fd)
return 0;
- if (event_source_is_offline(s)) {
- s->io.fd = fd;
- s->io.registered = false;
- } else {
- int saved_fd;
+ saved_fd = s->io.fd;
+ s->io.fd = fd;
- saved_fd = s->io.fd;
- assert(s->io.registered);
+ assert(event_source_is_offline(s) == !s->io.registered);
- s->io.fd = fd;
+ if (s->io.registered) {
s->io.registered = false;
r = source_io_register(s, s->enabled, s->io.events);
@@ -2173,6 +2169,9 @@ _public_ int sd_event_source_set_io_fd(sd_event_source *s, int fd) {
(void) epoll_ctl(s->event->epoll_fd, EPOLL_CTL_DEL, saved_fd, NULL);
}
+ if (s->io.owned)
+ safe_close(saved_fd);
+
return 0;
}
diff --git a/src/libsystemd/sd-event/test-event.c b/src/libsystemd/sd-event/test-event.c
index f793f9e..5c4a2ea 100644
--- a/src/libsystemd/sd-event/test-event.c
+++ b/src/libsystemd/sd-event/test-event.c
@@ -724,6 +724,24 @@ static void test_simple_timeout(void) {
assert_se(t >= usec_add(f, some_time));
}
+static void test_sd_event_source_set_io_fd(void) {
+ _cleanup_(sd_event_source_unrefp) sd_event_source *s = NULL;
+ _cleanup_(sd_event_unrefp) sd_event *e = NULL;
+ _cleanup_close_pair_ int pfd_a[2] = { -EBADF, -EBADF }, pfd_b[2] = { -EBADF, -EBADF };
+
+ assert_se(sd_event_default(&e) >= 0);
+
+ assert_se(pipe2(pfd_a, O_CLOEXEC) >= 0);
+ assert_se(pipe2(pfd_b, O_CLOEXEC) >= 0);
+
+ assert_se(sd_event_add_io(e, &s, pfd_a[0], EPOLLIN, NULL, INT_TO_PTR(-ENOANO)) >= 0);
+ assert_se(sd_event_source_set_io_fd_own(s, true) >= 0);
+ TAKE_FD(pfd_a[0]);
+
+ assert_se(sd_event_source_set_io_fd(s, pfd_b[0]) >= 0);
+ TAKE_FD(pfd_b[0]);
+}
+
int main(int argc, char *argv[]) {
test_setup_logging(LOG_DEBUG);
@@ -742,5 +760,7 @@ int main(int argc, char *argv[]) {
test_ratelimit();
+ test_sd_event_source_set_io_fd();
+
return 0;
}
--
2.33.0

View File

@ -21,7 +21,7 @@
Name: systemd
Url: https://systemd.io/
Version: 249
Release: 80
Release: 81
License: MIT and LGPLv2+ and GPLv2+
Summary: System and Service Manager
@ -671,6 +671,7 @@ Patch6622: backport-test-validate-that-fdstore-pinning-works.patch
Patch6623: backport-core-Don-t-GC-unit-if-it-is-in-cgroup_empty_queue.patch
Patch6624: backport-unit-don-t-gc-unit-in-oom-queue.patch
Patch6625: backport-core-do-not-GC-units-jobs-that-are-in-the-D-Bus-queu.patch
Patch6626: backport-sd-event-fix-fd-leak-when-fd-is-owned-by-IO-event-so.patch
Patch9001: update-rtc-with-system-clock-when-shutdown.patch
Patch9002: udev-add-actions-while-rename-netif-failed.patch
@ -2185,6 +2186,9 @@ grep -q -E '^KEYMAP="?fi-latin[19]"?' /etc/vconsole.conf 2>/dev/null &&
/usr/bin/systemd-cryptenroll
%changelog
* Fri Jul 5 2024 wangyuhang <wangyuhang27@huawei.com> - 249-81
- add backport-sd-event-fix-fd-leak-when-fd-is-owned-by-IO-event-so.patch
* Mon Jun 17 2024 zhangyao <zhangyao108@huawei.com> - 249-80
- Add the FileDescriptorStorePreserve= option to the service