diff --git a/SOURCES/0077-lsipc-fix-semaphore-USED-counter.patch b/SOURCES/0077-lsipc-fix-semaphore-USED-counter.patch new file mode 100644 index 0000000..d293c9d --- /dev/null +++ b/SOURCES/0077-lsipc-fix-semaphore-USED-counter.patch @@ -0,0 +1,65 @@ +From 7e980efc7103d100fdf889a68b9d7c5e0bb7bf92 Mon Sep 17 00:00:00 2001 +From: Karel Zak +Date: Tue, 26 Mar 2024 12:45:24 +0100 +Subject: lsipc: fix semaphore USED counter + +The code incorrectly counts only with the first item in the linked +list (due to a typo). It seems rather fragile to use "semds" and +"semdsp" as variable names in the same code ... + + # lsipc -gs + +Old: + + KEY ID PERMS OWNER NSEMS RESOURCE DESCRIPTION LIMIT USED USE% + SEMMNI Number of semaphore identifiers 32000 3 0.01% + SEMMNS Total number of semaphores 1024000000 369 0.00% + SEMMSL Max semaphores per semaphore set. 32000 - - + SEMOPM Max number of operations per semop(2) 500 - - + SEMVMX Semaphore max value 32767 - - + +Fixed: + + KEY ID PERMS OWNER NSEMS RESOURCE DESCRIPTION LIMIT USED USE% + SEMMNI Number of semaphore identifiers 32000 3 0.01% + SEMMNS Total number of semaphores 1024000000 156 0.00% + SEMMSL Max semaphores per semaphore set. 32000 - - + SEMOPM Max number of operations per semop(2) 500 - - + SEMVMX Semaphore max value 32767 - - + +Addresses: https://issues.redhat.com/browse/RHEL-34165 +Upstream: http://github.com/util-linux/util-linux/commit/fa45a6e516065f489b1cfb924ec3fc06960e0839 +Signed-off-by: Karel Zak +--- + sys-utils/lsipc.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/sys-utils/lsipc.c b/sys-utils/lsipc.c +index aa1dd4540..3e2cd639d 100644 +--- a/sys-utils/lsipc.c ++++ b/sys-utils/lsipc.c +@@ -712,16 +712,18 @@ static void do_sem(int id, struct lsipc_control *ctl, struct libscols_table *tb) + + static void do_sem_global(struct lsipc_control *ctl, struct libscols_table *tb) + { +- struct sem_data *semds, *semdsp; ++ struct sem_data *semds; + struct ipc_limits lim; + int nsems = 0, nsets = 0; + + ipc_sem_get_limits(&lim); + + if (ipc_sem_get_info(-1, &semds) > 0) { +- for (semdsp = semds; semdsp->next != NULL; semdsp = semdsp->next) { ++ struct sem_data *p; ++ ++ for (p = semds; p->next != NULL; p = p->next) { + ++nsets; +- nsems += semds->sem_nsems; ++ nsems += p->sem_nsems; + } + ipc_sem_free_info(semds); + } +-- +2.46.0 + diff --git a/SOURCES/0078-libblkid-Check-offset-in-LUKS2-header.patch b/SOURCES/0078-libblkid-Check-offset-in-LUKS2-header.patch new file mode 100644 index 0000000..d89de7b --- /dev/null +++ b/SOURCES/0078-libblkid-Check-offset-in-LUKS2-header.patch @@ -0,0 +1,119 @@ +From a4348a44319a126b75c6a7b4ac82a4efb4d63466 Mon Sep 17 00:00:00 2001 +From: Milan Broz +Date: Fri, 16 Feb 2024 16:44:12 +0100 +Subject: libblkid: Check offset in LUKS2 header + +LUKS2 binary header contains offset field that describes where +the header should be located. + +If this offset is not correct, blkid should tread this header +as invalid. + +This patch fixes problem when both swap and LUKS headers are present +(LUKS header was swapped out) and detected LUKS header is at a wrong +offset. As LUKS has higher priority, it confuses detection. + +[kzak@redhat.com (RHEL-9): -removed ID_FS_* from expected test output; + not supported by RHEL yet] + +Signed-off-by: Milan Broz +Addresses: https://issues.redhat.com/browse/RHEL-25265 +Upstream: http://github.com/util-linux/util-linux/commit/e49de00f4a22f91ec5af08d97e30a198cd64e00d) +Signed-off-by: Karel Zak +--- + libblkid/src/superblocks/luks.c | 20 +++++++++++++++++--- + tests/expected/blkid/low-probe-swap-luks | 5 +++++ + tests/ts/blkid/images-fs/swap-luks.img.xz | Bin 0 -> 388 bytes + 3 files changed, 22 insertions(+), 3 deletions(-) + create mode 100644 tests/expected/blkid/low-probe-swap-luks + create mode 100644 tests/ts/blkid/images-fs/swap-luks.img.xz + +diff --git a/libblkid/src/superblocks/luks.c b/libblkid/src/superblocks/luks.c +index 0230b3492..4623c98fc 100644 +--- a/libblkid/src/superblocks/luks.c ++++ b/libblkid/src/superblocks/luks.c +@@ -1,6 +1,6 @@ + /* + * Copyright (C) 2008 Karel Zak +- * Copyright (C) 2018 Milan Broz ++ * Copyright (C) 2018-2024 Milan Broz + * + * Inspired by libvolume_id by + * Kay Sievers +@@ -15,6 +15,7 @@ + #include + #include + #include ++#include + + #include "superblocks.h" + +@@ -96,6 +97,19 @@ static int luks_attributes(blkid_probe pr, struct luks2_phdr *header, uint64_t o + return BLKID_PROBE_OK; + } + ++static bool luks_valid(struct luks2_phdr *header, const char *magic, uint64_t offset) ++{ ++ if (memcmp(header->magic, magic, LUKS_MAGIC_L)) ++ return false; ++ ++ /* LUKS2 header is not at expected offset */ ++ if (be16_to_cpu(header->version) == 2 && ++ be64_to_cpu(header->hdr_offset) != offset) ++ return false; ++ ++ return true; ++} ++ + static int probe_luks(blkid_probe pr, const struct blkid_idmag *mag __attribute__((__unused__))) + { + struct luks2_phdr *header; +@@ -105,7 +119,7 @@ static int probe_luks(blkid_probe pr, const struct blkid_idmag *mag __attribute_ + if (!header) + return errno ? -errno : BLKID_PROBE_NONE; + +- if (!memcmp(header->magic, LUKS_MAGIC, LUKS_MAGIC_L)) { ++ if (luks_valid(header, LUKS_MAGIC, 0)) { + /* LUKS primary header was found. */ + return luks_attributes(pr, header, 0); + } +@@ -118,7 +132,7 @@ static int probe_luks(blkid_probe pr, const struct blkid_idmag *mag __attribute_ + if (!header) + return errno ? -errno : BLKID_PROBE_NONE; + +- if (!memcmp(header->magic, LUKS_MAGIC_2, LUKS_MAGIC_L)) ++ if (luks_valid(header, LUKS_MAGIC_2, secondary_offsets[i])) + return luks_attributes(pr, header, secondary_offsets[i]); + } + +diff --git a/tests/expected/blkid/low-probe-swap-luks b/tests/expected/blkid/low-probe-swap-luks +new file mode 100644 +index 000000000..c1573b033 +--- /dev/null ++++ b/tests/expected/blkid/low-probe-swap-luks +@@ -0,0 +1,5 @@ ++ID_FS_TYPE=swap ++ID_FS_USAGE=other ++ID_FS_UUID=0eb5f96f-188d-4d61-9e9c-d89ce8206846 ++ID_FS_UUID_ENC=0eb5f96f-188d-4d61-9e9c-d89ce8206846 ++ID_FS_VERSION=1 +diff --git a/tests/ts/blkid/images-fs/swap-luks.img.xz b/tests/ts/blkid/images-fs/swap-luks.img.xz +new file mode 100644 +index 0000000000000000000000000000000000000000..9b5cb65a38e2b0f156d0e7c54f7e302e8be5d886 +GIT binary patch +literal 388 +zcmV-~0ek-aH+ooF000E$*0e?f03iVu0001VFXf}-|Nj9)T>t=Y{r~@?w|_@fn&#B$ +z;sb3rhc#v^S33qtu8bp#ELS`>#Df}I`JsnWWeI+83*NgdLzb2it-UN0L+%FFBw~Dh +z(hiYp26QOeLGz0*mT~CRG8teHg8cC)l^sS2)UT*j#1I|~nxWP(f_5R?;mz%uu}S(< +zrD9Ia@w4_^-(z=o9wHb+YSvk +Date: Tue, 20 Feb 2024 12:26:33 +0100 +Subject: more: fix poll() use + +The more(1) command utilizes signalfd() to monitor signals and reads +commands from the user via stderr (as stdin is typically used for +piping and not for user interaction). + +However, the current more_poll() implementation ignores stderr. As a result, +more(1) waits on read(stderr) while completely ignoring signals. This issue +becomes evident when using commands like: + + grep foo /path/file | more + +In such cases, it's only possible to exit 'more' by pressing 'q'; +CTRL+C does not work. + +Changes: + +- Refactor more_poll() code: + - Introduce an enum to access pfd[] items instead of using magical constants. + - Implement a while() loop to handle EAGAIN or POLLHUP. + +- Ignore stdin after POLLHUP (indicating that the pipe's peer closed). +- Ensure stderr is also checked. +- Use return codes akin to classic poll(). + +Note: I have doubts regarding the usability of stdin in more_poll(), +as the function is primarily used to wait for user input (via stderr) +and to monitor signals. Nevertheless, it is retained for potential use +in detecting when the pipe's peer (or the entire session) has been +terminated (see commit 68e14d3d5f4116ad3aca0e392d008645ea90cf70). + +Signed-off-by: Karel Zak +Upstream: http://github.com/util-linux/util-linux/commit/fe23722854f651984fad597cbb5b44653f72832a +Addresses: https://issues.redhat.com/browse/RHEL-25559 +--- + text-utils/more.c | 123 +++++++++++++++++++++++++++++++--------------- + 1 file changed, 83 insertions(+), 40 deletions(-) + +diff --git a/text-utils/more.c b/text-utils/more.c +index e2898e52f..a4fbe0220 100644 +--- a/text-utils/more.c ++++ b/text-utils/more.c +@@ -199,6 +199,7 @@ struct more_control { + magic_t magic; /* libmagic database entries */ + #endif + unsigned int ++ ignore_stdin:1, /* POLLHUP; peer closed pipe */ + bad_stdout:1, /* true if overwriting does not turn off standout */ + catch_suspend:1, /* we should catch the SIGTSTP signal */ + clear_line_ends:1, /* do not scroll, paint each screen from the top */ +@@ -1341,50 +1342,92 @@ static void read_line(struct more_control *ctl) + *p = '\0'; + } + ++/* returns: 0 timeout or nothing; <0 error, >0 success */ + static int more_poll(struct more_control *ctl, int timeout) + { +- struct pollfd pfd[2]; ++ enum { ++ POLLFD_SIGNAL = 0, ++ POLLFD_STDIN, ++ POLLFD_STDERR, ++ }; ++ struct pollfd pfd[] = { ++ [POLLFD_SIGNAL] = { .fd = ctl->sigfd, .events = POLLIN | POLLERR | POLLHUP }, ++ [POLLFD_STDIN] = { .fd = STDIN_FILENO, .events = POLLIN | POLLERR | POLLHUP }, ++ [POLLFD_STDERR] = { .fd = STDERR_FILENO, .events = POLLIN | POLLERR | POLLHUP } ++ }; ++ int has_data = 0; + +- pfd[0].fd = ctl->sigfd; +- pfd[0].events = POLLIN | POLLERR | POLLHUP; +- pfd[1].fd = STDIN_FILENO; +- pfd[1].events = POLLIN; ++ while (!has_data) { ++ int rc; + +- if (poll(pfd, 2, timeout) < 0) { +- if (errno == EAGAIN) +- return 1; +- more_error(ctl, _("poll failed")); +- return 1; +- } +- if (pfd[0].revents != 0) { +- struct signalfd_siginfo info; +- ssize_t sz; +- +- sz = read(pfd[0].fd, &info, sizeof(info)); +- assert(sz == sizeof(info)); +- switch (info.ssi_signo) { +- case SIGINT: +- more_exit(ctl); +- break; +- case SIGQUIT: +- sigquit_handler(ctl); +- break; +- case SIGTSTP: +- sigtstp_handler(ctl); +- break; +- case SIGCONT: +- sigcont_handler(ctl); +- break; +- case SIGWINCH: +- sigwinch_handler(ctl); +- break; +- default: +- abort(); ++ if (ctl->ignore_stdin) ++ pfd[POLLFD_STDIN].fd = -1; /* probably closed, ignore */ ++ ++ rc = poll(pfd, ARRAY_SIZE(pfd), timeout); ++ ++ /* error */ ++ if (rc < 0) { ++ if (errno == EAGAIN) ++ continue; ++ ++ more_error(ctl, _("poll failed")); ++ return rc; + } ++ ++ /* timeout */ ++ if (rc == 0) ++ return 0; ++ ++ /* event on signal FD */ ++ if (pfd[POLLFD_SIGNAL].revents) { ++ struct signalfd_siginfo info; ++ ssize_t sz; ++ ++ sz = read(pfd[POLLFD_SIGNAL].fd, &info, sizeof(info)); ++ assert(sz == sizeof(info)); ++ switch (info.ssi_signo) { ++ case SIGINT: ++ more_exit(ctl); ++ break; ++ case SIGQUIT: ++ sigquit_handler(ctl); ++ break; ++ case SIGTSTP: ++ sigtstp_handler(ctl); ++ break; ++ case SIGCONT: ++ sigcont_handler(ctl); ++ break; ++ case SIGWINCH: ++ sigwinch_handler(ctl); ++ break; ++ default: ++ abort(); ++ } ++ } ++ ++ /* event on stdin */ ++ if (pfd[POLLFD_STDIN].revents) { ++ /* Check for POLLERR and POLLHUP in stdin revents */ ++ if ((pfd[POLLFD_STDIN].revents & POLLERR) && ++ (pfd[POLLFD_STDIN].revents & POLLHUP)) ++ more_exit(ctl); ++ ++ /* poll() return POLLHUP event after pipe close() and POLLNVAL ++ * means that fd is already closed. */ ++ if ((pfd[POLLFD_STDIN].revents & POLLHUP) || ++ (pfd[POLLFD_STDIN].revents & POLLNVAL)) ++ ctl->ignore_stdin = 1; ++ else ++ has_data++; ++ } ++ ++ /* event on stderr (we reads user commands from stderr!) */ ++ if (pfd[POLLFD_STDERR].revents) ++ has_data++; + } +- if (pfd[1].revents == 0) +- return 1; +- return 0; ++ ++ return has_data; + } + + /* Search for nth occurrence of regular expression contained in buf in +@@ -1452,7 +1495,7 @@ static void search(struct more_control *ctl, char buf[], int n) + } + break; + } +- more_poll(ctl, 1); ++ more_poll(ctl, 0); + } + /* Move ctrl+c signal handling back to more_key_command(). */ + signal(SIGINT, SIG_DFL); +@@ -1616,7 +1659,7 @@ static int more_key_command(struct more_control *ctl, char *filename) + ctl->report_errors = 0; + ctl->search_called = 0; + for (;;) { +- if (more_poll(ctl, -1) != 0) ++ if (more_poll(ctl, -1) <= 0) + continue; + cmd = read_command(ctl); + if (cmd.key == more_kc_unknown_command) +-- +2.46.0 + diff --git a/SOURCES/0080-more-make-sure-we-have-data-on-stderr.patch b/SOURCES/0080-more-make-sure-we-have-data-on-stderr.patch new file mode 100644 index 0000000..f787d77 --- /dev/null +++ b/SOURCES/0080-more-make-sure-we-have-data-on-stderr.patch @@ -0,0 +1,96 @@ +From 04e37ba1b352de91ef28f9996ca3482987a31c3a Mon Sep 17 00:00:00 2001 +From: Karel Zak +Date: Thu, 22 Aug 2024 08:56:52 +0200 +Subject: more: make sure we have data on stderr +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +more(1) uses more_poll() to monitor data on stdin, stderr, and +signals. It is used before read_command(), but this function only +reads from stderr. Therefore, if any other non-stderr event occurs, +this function will wait on read(). In this case, more(1) will not +react to signals anymore. We need to ensure that more(1) only waits in +more_poll(). + +Try + + for x in {1..1000}; do echo "line $x"; done | more + +to reproduce. + +Addresses: https://issues.redhat.com/browse/RHEL-25559 +Reported-by: Radka Skvarilova +Signed-off-by: Karel Zak +--- + text-utils/more.c | 18 +++++++++++++----- + 1 file changed, 13 insertions(+), 5 deletions(-) + +diff --git a/text-utils/more.c b/text-utils/more.c +index a4fbe0220..c5a060424 100644 +--- a/text-utils/more.c ++++ b/text-utils/more.c +@@ -1343,7 +1343,7 @@ static void read_line(struct more_control *ctl) + } + + /* returns: 0 timeout or nothing; <0 error, >0 success */ +-static int more_poll(struct more_control *ctl, int timeout) ++static int more_poll(struct more_control *ctl, int timeout, int *stderr_active) + { + enum { + POLLFD_SIGNAL = 0, +@@ -1357,6 +1357,9 @@ static int more_poll(struct more_control *ctl, int timeout) + }; + int has_data = 0; + ++ if (stderr_active) ++ *stderr_active = 0; ++ + while (!has_data) { + int rc; + +@@ -1423,8 +1426,11 @@ static int more_poll(struct more_control *ctl, int timeout) + } + + /* event on stderr (we reads user commands from stderr!) */ +- if (pfd[POLLFD_STDERR].revents) ++ if (pfd[POLLFD_STDERR].revents) { + has_data++; ++ if (stderr_active) ++ *stderr_active = 1; ++ } + } + + return has_data; +@@ -1495,7 +1501,7 @@ static void search(struct more_control *ctl, char buf[], int n) + } + break; + } +- more_poll(ctl, 0); ++ more_poll(ctl, 0, NULL); + } + /* Move ctrl+c signal handling back to more_key_command(). */ + signal(SIGINT, SIG_DFL); +@@ -1649,7 +1655,7 @@ static int skip_forwards(struct more_control *ctl, int nlines, cc_t comchar) + static int more_key_command(struct more_control *ctl, char *filename) + { + int retval = 0; +- int done = 0, search_again = 0; ++ int done = 0, search_again = 0, stderr_active = 0; + char cmdbuf[INIT_BUF]; + struct number_command cmd; + +@@ -1659,7 +1665,9 @@ static int more_key_command(struct more_control *ctl, char *filename) + ctl->report_errors = 0; + ctl->search_called = 0; + for (;;) { +- if (more_poll(ctl, -1) <= 0) ++ if (more_poll(ctl, -1, &stderr_active) <= 0) ++ continue; ++ if (stderr_active == 0) + continue; + cmd = read_command(ctl); + if (cmd.key == more_kc_unknown_command) +-- +2.46.0 + diff --git a/SPECS/util-linux.spec b/SPECS/util-linux.spec index cf475f2..9ff1aad 100644 --- a/SPECS/util-linux.spec +++ b/SPECS/util-linux.spec @@ -2,7 +2,7 @@ Summary: A collection of basic system utilities Name: util-linux Version: 2.37.4 -Release: 18%{?dist} +Release: 20%{?dist} License: GPLv2 and GPLv2+ and LGPLv2+ and BSD with advertising and Public Domain URL: http://en.wikipedia.org/wiki/Util-linux @@ -219,6 +219,16 @@ Patch75: 0075-libmount-improve-act-file-close.patch # RHEL-12783 - lscpu: update tests, follow max freq for scaling Patch76: 0076-lscpu-update-tests-follow-max-freq-for-scaling.patch +### RHEL-9.5 +# +# RHEL-34165 - lsipc: fix semaphore USED counter +Patch77: 0077-lsipc-fix-semaphore-USED-counter.patch +# RHEL-25265 - libblkid: Check offset in LUKS2 header +Patch78: 0078-libblkid-Check-offset-in-LUKS2-header.patch +# RHEL-25559 - more: fix poll() use +Patch79: 0079-more-fix-poll-use.patch +Patch80: 0080-more-make-sure-we-have-data-on-stderr.patch + %description The util-linux package contains a large variety of low-level system @@ -1053,6 +1063,14 @@ fi %{_libdir}/python*/site-packages/libmount/ %changelog +* Thu Aug 22 2024 Karel Zak 2.37.4-20 +- fix RHEL-25559 - more: make sure we have data on stderr + +* Tue Aug 20 2024 Karel Zak 2.37.4-19 +- fix RHEL-34165 - lsipc: fix semaphore USED counter +- fix RHEL-25265 - libblkid: Check offset in LUKS2 header +- fix RHEL-25559 - more: fix poll() use + * Thu Feb 08 2024 Karel Zak 2.37.4-18 - lscpu: another tests update (RHEL-12783)