diff options
Diffstat (limited to '')
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; + } + |