summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--debian/changelog7
-rw-r--r--debian/patches/series5
-rw-r--r--debian/patches/upstream-master/libmount-Fix-atime-remount-for-new-API.patch81
-rw-r--r--debian/patches/upstream-master/libsmartcols-fix-reduction-stages-use.patch53
-rw-r--r--debian/patches/upstream-master/libuuid-clear-uuidd-cache-on-fork.patch81
-rw-r--r--debian/patches/upstream-master/libuuid-drop-check-for-HAVE_TLS.patch49
-rw-r--r--debian/patches/upstream-master/libuuid-split-uuidd-cache-into-dedicated-struct.patch116
7 files changed, 392 insertions, 0 deletions
diff --git a/debian/changelog b/debian/changelog
index 487660b..3e648ff 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,10 @@
+util-linux (2.40.1-2) unstable; urgency=medium
+
+ * Apply upstream patches: fix atime remount, fix smartcols reduction stages,
+ clear uuidd cache on fork
+
+ -- Chris Hofstaedtler <zeha@debian.org> Sun, 26 May 2024 15:52:22 +0200
+
util-linux (2.40.1-1) unstable; urgency=medium
* New upstream release.
diff --git a/debian/patches/series b/debian/patches/series
index 333acab..b6169df 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -9,3 +9,8 @@ upstream/audit-arch.h-add-defines-for-m68k-sh.patch
upstream/Fix-ul_path_read_buffer.patch
upstream/libmount-utils-add-pidfs-to-pseudo-fs-list.patch
upstream/fsck-warn-if-fsck.-type-not-found-and-device-is-specified.patch
+upstream-master/libuuid-drop-check-for-HAVE_TLS.patch
+upstream-master/libuuid-split-uuidd-cache-into-dedicated-struct.patch
+upstream-master/libuuid-clear-uuidd-cache-on-fork.patch
+upstream-master/libsmartcols-fix-reduction-stages-use.patch
+upstream-master/libmount-Fix-atime-remount-for-new-API.patch
diff --git a/debian/patches/upstream-master/libmount-Fix-atime-remount-for-new-API.patch b/debian/patches/upstream-master/libmount-Fix-atime-remount-for-new-API.patch
new file mode 100644
index 0000000..fb2cb79
--- /dev/null
+++ b/debian/patches/upstream-master/libmount-Fix-atime-remount-for-new-API.patch
@@ -0,0 +1,81 @@
+From: Karel Zak <kzak@redhat.com>
+Date: Tue, 14 May 2024 11:58:20 +0200
+Subject: libmount: Fix atime remount for new API
+
+All atime settings are mutually exclusive, and the attr_set mask for
+the mount_setattr() syscall cannot contain multiple MOUNT_ATTR_ atime
+related options.
+
+Unfortunately, during a remount, the list of options is composed of
+both old and new options. In this case, libmount sets more atime
+options to the mask. The correct behavior is to use the last atime
+related option from the list.
+
+Fixes: https://github.com/util-linux/util-linux/issues/3032
+Signed-off-by: Karel Zak <kzak@redhat.com>
+---
+ libmount/src/optlist.c | 33 +++++++++++++++++++++------------
+ 1 file changed, 21 insertions(+), 12 deletions(-)
+
+diff --git a/libmount/src/optlist.c b/libmount/src/optlist.c
+index 476acfd..e324896 100644
+--- a/libmount/src/optlist.c
++++ b/libmount/src/optlist.c
+@@ -837,6 +837,7 @@ int mnt_optlist_get_attrs(struct libmnt_optlist *ls, uint64_t *set, uint64_t *cl
+ struct libmnt_iter itr;
+ struct libmnt_opt *opt;
+ uint64_t remount_reset = 0;
++ uint64_t atime_set = 0;
+
+ if (!ls || !ls->linux_map || !set || !clr)
+ return -EINVAL;
+@@ -879,29 +880,37 @@ int mnt_optlist_get_attrs(struct libmnt_optlist *ls, uint64_t *set, uint64_t *cl
+ remount_reset &= ~x;
+
+ if (opt->ent->mask & MNT_INVERT) {
+- DBG(OPTLIST, ul_debugobj(ls, " clr: %s", opt->ent->name));
+- /*
+- * All atime settings are mutually exclusive so *clr must
+- * have MOUNT_ATTR__ATIME set.
+- *
+- * See the function fs/namespace.c:build_mount_kattr()
+- * in the linux kernel source.
+- */
++ DBG(OPTLIST, ul_debugobj(ls, " clr: %s 0x%08" PRIx64,
++ opt->ent->name, x));
++
+ if (x == MOUNT_ATTR_RELATIME || x == MOUNT_ATTR_NOATIME ||
+ x == MOUNT_ATTR_STRICTATIME)
+ *clr |= MOUNT_ATTR__ATIME;
+ else
+ *clr |= x;
+ } else {
+- DBG(OPTLIST, ul_debugobj(ls, " set: %s", opt->ent->name));
+- *set |= x;
+-
+ if (x == MOUNT_ATTR_RELATIME || x == MOUNT_ATTR_NOATIME ||
+- x == MOUNT_ATTR_STRICTATIME)
++ x == MOUNT_ATTR_STRICTATIME) {
++ /* All atime settings are mutually exclusive,
++ * the last option wins and MOUNT_ATTR__ATIME
++ * is required in clr mask.
++ */
++ DBG(OPTLIST, ul_debugobj(ls, " atime: %s 0x%08" PRIx64,
++ opt->ent->name, x));
+ *clr |= MOUNT_ATTR__ATIME;
++ atime_set = x;
++ } else {
++ DBG(OPTLIST, ul_debugobj(ls, " set: %s 0x%08" PRIx64,
++ opt->ent->name, x));
++ *set |= x;
++ }
+ }
+ }
+
++ if (atime_set) {
++ DBG(OPTLIST, ul_debugobj(ls, " set atime 0x%08" PRIx64, atime_set));
++ *set |= atime_set;
++ }
+ if (remount_reset)
+ *clr |= remount_reset;
+
diff --git a/debian/patches/upstream-master/libsmartcols-fix-reduction-stages-use.patch b/debian/patches/upstream-master/libsmartcols-fix-reduction-stages-use.patch
new file mode 100644
index 0000000..1bb162b
--- /dev/null
+++ b/debian/patches/upstream-master/libsmartcols-fix-reduction-stages-use.patch
@@ -0,0 +1,53 @@
+From: Karel Zak <kzak@redhat.com>
+Date: Wed, 15 May 2024 15:45:19 +0200
+Subject: libsmartcols: fix reduction stages use
+
+There is no proper check for the number of reduction stages, so in
+some cases, the code can loop indefinitely.
+
+The patch also fixes 'rc' variable shadowing.
+
+Fixes: https://github.com/util-linux/util-linux/issues/3046
+Signed-off-by: Karel Zak <kzak@redhat.com>
+---
+ libsmartcols/src/calculate.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/libsmartcols/src/calculate.c b/libsmartcols/src/calculate.c
+index 86e1b27..41daf74 100644
+--- a/libsmartcols/src/calculate.c
++++ b/libsmartcols/src/calculate.c
+@@ -306,6 +306,8 @@ static int reduce_column(struct libscols_table *tb,
+ size_t wanted, org_width, reduce = 1;
+ int is_trunc = 0;
+
++ if (stage > 6)
++ return -1;
+ if (tb->termwidth >= *width)
+ return 1;
+ /* ignore hidden columns */
+@@ -493,7 +495,7 @@ int __scols_calculate(struct libscols_table *tb, struct ul_buffer *buf)
+ /* reduce columns width */
+ while (width > tb->termwidth) {
+ size_t org_width = width;
+- int rc = 0, n = 0;
++ int xrc = 0, n = 0;
+
+ if (!sorted) {
+ DBG(TAB, ul_debugobj(tb, "sorting by deviation"));
+@@ -508,12 +510,12 @@ int __scols_calculate(struct libscols_table *tb, struct ul_buffer *buf)
+ scols_reset_iter(&itr, SCOLS_ITER_BACKWARD);
+
+ while (width > tb->termwidth
+- && rc == 0
++ && xrc == 0
+ && scols_table_next_column(tb, &itr, &cl) == 0) {
+- rc = reduce_column(tb, cl, &width, stage, n++);
++ xrc = reduce_column(tb, cl, &width, stage, n++);
+ }
+
+- if (rc != 0)
++ if (xrc != 0)
+ break;
+ if (org_width == width)
+ stage++;
diff --git a/debian/patches/upstream-master/libuuid-clear-uuidd-cache-on-fork.patch b/debian/patches/upstream-master/libuuid-clear-uuidd-cache-on-fork.patch
new file mode 100644
index 0000000..46f2cb4
--- /dev/null
+++ b/debian/patches/upstream-master/libuuid-clear-uuidd-cache-on-fork.patch
@@ -0,0 +1,81 @@
+From: =?utf-8?q?Thomas_Wei=C3=9Fschuh?= <thomas@t-8ch.de>
+Date: Tue, 7 May 2024 13:44:31 +0200
+Subject: libuuid: clear uuidd cache on fork()
+MIME-Version: 1.0
+Content-Type: text/plain; charset="utf-8"
+Content-Transfer-Encoding: 8bit
+
+After fork() the memory of the calling thread is preserved into the new
+process. This also includes TLS.
+Make sure to reset the cache after a fork to avoid reuse of cached
+values.
+
+Only the TLS of the thread calling fork() is relevant as that is the
+only thread that gets forked.
+New threads will received newly initialized TLS.
+
+Fixes https://github.com/util-linux/util-linux/issues/3009
+Signed-off-by: Thomas Weißschuh <thomas@t-8ch.de>
+---
+ libuuid/src/Makemodule.am | 2 +-
+ libuuid/src/gen_uuid.c | 17 +++++++++++++++--
+ 2 files changed, 16 insertions(+), 3 deletions(-)
+
+diff --git a/libuuid/src/Makemodule.am b/libuuid/src/Makemodule.am
+index e58fa26..417fd2b 100644
+--- a/libuuid/src/Makemodule.am
++++ b/libuuid/src/Makemodule.am
+@@ -31,7 +31,7 @@ libuuid_la_SOURCES = \
+ EXTRA_libuuid_la_DEPENDENCIES = \
+ libuuid/src/libuuid.sym
+
+-libuuid_la_LIBADD = $(LDADD) $(SOCKET_LIBS)
++libuuid_la_LIBADD = $(LDADD) $(SOCKET_LIBS) -lpthread
+
+ libuuid_la_CFLAGS = \
+ $(AM_CFLAGS) \
+diff --git a/libuuid/src/gen_uuid.c b/libuuid/src/gen_uuid.c
+index c40f9d6..3b76ddc 100644
+--- a/libuuid/src/gen_uuid.c
++++ b/libuuid/src/gen_uuid.c
+@@ -80,6 +80,8 @@
+ #if defined(__linux__) && defined(HAVE_SYS_SYSCALL_H)
+ #include <sys/syscall.h>
+ #endif
++#include <pthread.h>
++#include <signal.h>
+
+ #include "all-io.h"
+ #include "uuidP.h"
+@@ -591,9 +593,21 @@ THREAD_LOCAL struct {
+ .cache_size = CS_MIN,
+ };
+
++static void reset_uuidd_cache(void)
++{
++ memset(&uuidd_cache, 0, sizeof(uuidd_cache));
++ uuidd_cache.cache_size = CS_MIN;
++}
++
+ static int uuid_generate_time_generic(uuid_t out) {
++ static volatile sig_atomic_t atfork_registered;
+ time_t now;
+
++ if (!atfork_registered) {
++ pthread_atfork(NULL, NULL, reset_uuidd_cache);
++ atfork_registered = 1;
++ }
++
+ if (uuidd_cache.num > 0) { /* expire cache */
+ now = time(NULL);
+ if (now > uuidd_cache.last_time+1) {
+@@ -622,8 +636,7 @@ static int uuid_generate_time_generic(uuid_t out) {
+ return 0;
+ }
+ /* request to daemon failed, reset cache */
+- uuidd_cache.num = 0;
+- uuidd_cache.cache_size = CS_MIN;
++ reset_uuidd_cache();
+ }
+ if (uuidd_cache.num > 0) { /* serve uuid from cache */
+ uuidd_cache.uu.time_low++;
diff --git a/debian/patches/upstream-master/libuuid-drop-check-for-HAVE_TLS.patch b/debian/patches/upstream-master/libuuid-drop-check-for-HAVE_TLS.patch
new file mode 100644
index 0000000..1c969f0
--- /dev/null
+++ b/debian/patches/upstream-master/libuuid-drop-check-for-HAVE_TLS.patch
@@ -0,0 +1,49 @@
+From: =?utf-8?q?Thomas_Wei=C3=9Fschuh?= <thomas@t-8ch.de>
+Date: Tue, 7 May 2024 13:28:41 +0200
+Subject: libuuid: drop check for HAVE_TLS
+MIME-Version: 1.0
+Content-Type: text/plain; charset="utf-8"
+Content-Transfer-Encoding: 8bit
+
+In the function get_clock() TLS is used unconditionally anyways.
+
+Signed-off-by: Thomas Weißschuh <thomas@t-8ch.de>
+---
+ libuuid/src/gen_uuid.c | 9 ---------
+ 1 file changed, 9 deletions(-)
+
+diff --git a/libuuid/src/gen_uuid.c b/libuuid/src/gen_uuid.c
+index 59e8c23..0984e24 100644
+--- a/libuuid/src/gen_uuid.c
++++ b/libuuid/src/gen_uuid.c
+@@ -90,11 +90,7 @@
+ #include "md5.h"
+ #include "sha1.h"
+
+-#ifdef HAVE_TLS
+ #define THREAD_LOCAL static __thread
+-#else
+-#define THREAD_LOCAL static
+-#endif
+
+ #ifdef _WIN32
+ static void gettimeofday (struct timeval *tv, void *dummy)
+@@ -584,7 +580,6 @@ int __uuid_generate_time_cont(uuid_t out, int *num, uint32_t cont_offset)
+ * the UUID anyway, but returns -1. Otherwise, returns 0.
+ */
+ static int uuid_generate_time_generic(uuid_t out) {
+-#ifdef HAVE_TLS
+ /* thread local cache for uuidd based requests */
+ THREAD_LOCAL int num = 0;
+ THREAD_LOCAL int cache_size = CS_MIN;
+@@ -637,10 +632,6 @@ static int uuid_generate_time_generic(uuid_t out) {
+ last_used = cache_size;
+ return 0;
+ }
+-#else
+- if (get_uuid_via_daemon(UUIDD_OP_TIME_UUID, out, 0) == 0)
+- return 0;
+-#endif
+
+ return __uuid_generate_time(out, NULL);
+ }
diff --git a/debian/patches/upstream-master/libuuid-split-uuidd-cache-into-dedicated-struct.patch b/debian/patches/upstream-master/libuuid-split-uuidd-cache-into-dedicated-struct.patch
new file mode 100644
index 0000000..86fe71c
--- /dev/null
+++ b/debian/patches/upstream-master/libuuid-split-uuidd-cache-into-dedicated-struct.patch
@@ -0,0 +1,116 @@
+From: =?utf-8?q?Thomas_Wei=C3=9Fschuh?= <thomas@t-8ch.de>
+Date: Tue, 7 May 2024 13:33:40 +0200
+Subject: libuuid: split uuidd cache into dedicated struct
+MIME-Version: 1.0
+Content-Type: text/plain; charset="utf-8"
+Content-Transfer-Encoding: 8bit
+
+To clear the struct we need to be able to refer to it by name.
+
+Signed-off-by: Thomas Weißschuh <thomas@t-8ch.de>
+---
+ libuuid/src/gen_uuid.c | 74 +++++++++++++++++++++++++++-----------------------
+ 1 file changed, 40 insertions(+), 34 deletions(-)
+
+diff --git a/libuuid/src/gen_uuid.c b/libuuid/src/gen_uuid.c
+index 0984e24..c40f9d6 100644
+--- a/libuuid/src/gen_uuid.c
++++ b/libuuid/src/gen_uuid.c
+@@ -579,57 +579,63 @@ int __uuid_generate_time_cont(uuid_t out, int *num, uint32_t cont_offset)
+ * If neither of these is possible (e.g. because of insufficient permissions), it generates
+ * the UUID anyway, but returns -1. Otherwise, returns 0.
+ */
++
++/* thread local cache for uuidd based requests */
++THREAD_LOCAL struct {
++ int num;
++ int cache_size;
++ int last_used;
++ struct uuid uu;
++ time_t last_time;
++} uuidd_cache = {
++ .cache_size = CS_MIN,
++};
++
+ static int uuid_generate_time_generic(uuid_t out) {
+- /* thread local cache for uuidd based requests */
+- THREAD_LOCAL int num = 0;
+- THREAD_LOCAL int cache_size = CS_MIN;
+- THREAD_LOCAL int last_used = 0;
+- THREAD_LOCAL struct uuid uu;
+- THREAD_LOCAL time_t last_time = 0;
+- time_t now;
+-
+- if (num > 0) { /* expire cache */
++ time_t now;
++
++ if (uuidd_cache.num > 0) { /* expire cache */
+ now = time(NULL);
+- if (now > last_time+1) {
+- last_used = cache_size - num;
+- num = 0;
++ if (now > uuidd_cache.last_time+1) {
++ uuidd_cache.last_used = uuidd_cache.cache_size - uuidd_cache.num;
++ uuidd_cache.num = 0;
+ }
+ }
+- if (num <= 0) { /* fill cache */
++ if (uuidd_cache.num <= 0) { /* fill cache */
+ /*
+ * num + OP_BULK provides a local cache in each application.
+ * Start with a small cache size to cover short running applications
+ * and adjust the cache size over the runntime.
+ */
+- if ((last_used == cache_size) && (cache_size < CS_MAX))
+- cache_size *= CS_FACTOR;
+- else if ((last_used < (cache_size / CS_FACTOR)) && (cache_size > CS_MIN))
+- cache_size /= CS_FACTOR;
++ if ((uuidd_cache.last_used == uuidd_cache.cache_size) && (uuidd_cache.cache_size < CS_MAX))
++ uuidd_cache.cache_size *= CS_FACTOR;
++ else if ((uuidd_cache.last_used < (uuidd_cache.cache_size / CS_FACTOR)) && (uuidd_cache.cache_size > CS_MIN))
++ uuidd_cache.cache_size /= CS_FACTOR;
+
+- num = cache_size;
++ uuidd_cache.num = uuidd_cache.cache_size;
+
+ if (get_uuid_via_daemon(UUIDD_OP_BULK_TIME_UUID,
+- out, &num) == 0) {
+- last_time = time(NULL);
+- uuid_unpack(out, &uu);
+- num--;
++ out, &uuidd_cache.num) == 0) {
++ uuidd_cache.last_time = time(NULL);
++ uuid_unpack(out, &uuidd_cache.uu);
++ uuidd_cache.num--;
+ return 0;
+ }
+ /* request to daemon failed, reset cache */
+- num = 0;
+- cache_size = CS_MIN;
++ uuidd_cache.num = 0;
++ uuidd_cache.cache_size = CS_MIN;
+ }
+- if (num > 0) { /* serve uuid from cache */
+- uu.time_low++;
+- if (uu.time_low == 0) {
+- uu.time_mid++;
+- if (uu.time_mid == 0)
+- uu.time_hi_and_version++;
++ if (uuidd_cache.num > 0) { /* serve uuid from cache */
++ uuidd_cache.uu.time_low++;
++ if (uuidd_cache.uu.time_low == 0) {
++ uuidd_cache.uu.time_mid++;
++ if (uuidd_cache.uu.time_mid == 0)
++ uuidd_cache.uu.time_hi_and_version++;
+ }
+- num--;
+- uuid_pack(&uu, out);
+- if (num == 0)
+- last_used = cache_size;
++ uuidd_cache.num--;
++ uuid_pack(&uuidd_cache.uu, out);
++ if (uuidd_cache.num == 0)
++ uuidd_cache.last_used = uuidd_cache.cache_size;
+ return 0;
+ }
+