sm-commit AT lists.ibiblio.org
Subject: Source Mage code commit list
List archive
[[SM-Commit] ] GIT changes to master grimoire by Ismael Luceno (623d1566f00205dcc3c34de6b1dc579e10cdb5f1)
- From: Ismael Luceno <scm AT sourcemage.org>
- To: sm-commit AT lists.ibiblio.org, sm-commit AT lists.sourcemage.org
- Subject: [[SM-Commit] ] GIT changes to master grimoire by Ismael Luceno (623d1566f00205dcc3c34de6b1dc579e10cdb5f1)
- Date: Thu, 27 Nov 2025 18:52:41 +0000
GIT changes to master grimoire by Ismael Luceno <ismael AT sourcemage.org>:
disk/e2fsprogs/HISTORY | 4
disk/e2fsprogs/PRE_BUILD | 3
disk/e2fsprogs/patches/0001-fuse2fs-fix-logging-redirection.patch | 287
++++++++++
3 files changed, 294 insertions(+)
New commits:
commit 623d1566f00205dcc3c34de6b1dc579e10cdb5f1
Author: Ismael Luceno <ismael AT sourcemage.org>
Commit: Ismael Luceno <ismael AT sourcemage.org>
e2fsprogs: Fix build against musl
diff --git a/disk/e2fsprogs/HISTORY b/disk/e2fsprogs/HISTORY
index 67b5428..4dbe285 100644
--- a/disk/e2fsprogs/HISTORY
+++ b/disk/e2fsprogs/HISTORY
@@ -1,3 +1,7 @@
+2025-11-27 Ismael Luceno <ismael AT sourcemage.org>
+ * PRE_BUILD, patches/0001-fuse2fs-fix-logging-redirection.patch:
+ fixed build against musl
+
2025-07-09 Pavel Vinogradov <public AT sourcemage.org>
* DETAILS: version 1.47.3
diff --git a/disk/e2fsprogs/PRE_BUILD b/disk/e2fsprogs/PRE_BUILD
new file mode 100755
index 0000000..c230ad1
--- /dev/null
+++ b/disk/e2fsprogs/PRE_BUILD
@@ -0,0 +1,3 @@
+default_pre_build &&
+cd "$SOURCE_DIRECTORY" &&
+apply_patch_dir patches
diff --git
a/disk/e2fsprogs/patches/0001-fuse2fs-fix-logging-redirection.patch
b/disk/e2fsprogs/patches/0001-fuse2fs-fix-logging-redirection.patch
new file mode 100644
index 0000000..c46907d
--- /dev/null
+++ b/disk/e2fsprogs/patches/0001-fuse2fs-fix-logging-redirection.patch
@@ -0,0 +1,287 @@
+From f79abd8554e600eacc2a7c864a8332b670c9e262 Mon Sep 17 00:00:00 2001
+From: "Darrick J. Wong" <djwong AT kernel.org>
+Date: Tue, 22 Jul 2025 12:40:53 -0700
+Subject: fuse2fs: fix logging redirection
+
+Someone pointed out that you can't just go around reassigning stdout and
+stderr because section 7.23.1 paragraph 4 of a recent C2y draft says
+that stdin, stdout, and stderr “are expressions of type "pointer to
+FILE" that point to the FILE objects associated, respectively, with the
+standard error, input, and output streams.”
+
+The use of the word "expression" should have been the warning sign that
+a symbol that can be mostly used as a pointer is not simply a pointer.
+
+Seven pages later, footnote 318 of the C2y draft clarifies that stdin,
+stdout, and stderr “need not be modifiable lvalues to which the value
+returned by the fopen function could be assigned.”
+
+"need not be" is the magic phrasing that means that glibc, musl, and
+mingw (for example) have very different declarations of stdout:
+
+glibc:
+extern FILE *stdout; /* Standard output stream. */
+
+musl:
+extern FILE *const stdout;
+
+mingw:
+#define stdout (&_iob[STDOUT_FILENO])
+
+All three are following the specification, yet you can write C code that
+fails to compile what otherwise looks like a normal assignment on two of
+the libraries:
+
+static FILE *const fark; /* musl */
+
+FILE crap[3]; /* mingw */
+#define crows (&crap[0])
+
+static FILE *stupid; /* glibc */
+
+int main(int argc, char *argv[])
+{
+ fark = NULL;
+ crows = NULL;
+ stupid = NULL;
+}
+
+/tmp/a.c: In function ‘main’:
+/tmp/a.c:20:14: error: assignment of read-only variable ‘fark’
+ 20 | fark = NULL;
+ | ^
+/tmp/a.c:21:15: error: lvalue required as left operand of assignment
+ 21 | crows = NULL;
+ | ^
+
+What a useless specification! You don't even get the same error!
+Unfortunately, this leadership vacuum means that each implementation of
+a so-called standard C library is perfectly within its right to do this.
+IOWs, the authors decided that every C programmer must divert some of
+the brainpower they could spend on their program's core algorithms to be
+really smart about this quirk.
+
+A whole committee of very smart programmers collectively decided this
+was a good way to run things decades ago so that C library authors in
+the 1980s wouldn't have to change their code, and subsequent gatherings
+have reaffirmed this "practical" decision. Their suggestion to reassign
+stdout and stderr is to use freopen, but that walks the specified path,
+which is racy if you want both streams to point to the same file. You
+could pass /dev/fd/XX to solve the race, but then you lose portability.
+
+In other words, they "engineered" an incomplete solution with problems
+to achieve a short term goal that nobody should care about 40 years
+later.
+
+Fix fuse2fs by rearranging the code to change STD{OUT,ERR}_FILENO to
+point to the same open logfile via dup2 and then try to use freopen on
+/dev/fd/XX to capture any stdout/err usage by the libraries that fuse2fs
+depends on.
+
+Note that we must do the whole thing over again in op_init because
+libfuse will dup2 STD{OUT,ERR}_FILE to /dev/null as part of daemonizing
+the server.
+
+Cc: linux-ext4 AT vger.kernel.org # v1.47.3
+Fixes: 5cdebf3eebc22c ("fuse2fs: stop aliasing stderr with ff->err_fp")
+Link: https://github.com/tytso/e2fsprogs/issues/235
+Signed-off-by: Darrick J. Wong <djwong AT kernel.org>
+Link: https://lore.kernel.org/r/20250722194053.GO2672022@frogsfrogsfrogs
+Signed-off-by: Theodore Ts'o <tytso AT mit.edu>
+Upstream-Status: Backport
+
[https://git.kernel.org/pub/scm/fs/ext2/e2fsprogs.git/patch/?id=f79abd8554e600eacc2a7c864a8332b670c9e262]
+Signed-off-by: Ismael Luceno <ismael AT sourcemage.org>
+---
+ misc/fuse2fs.c | 141
+++++++++++++++++++++++++++++++++++++++++++++++++--------
+ 1 file changed, 123 insertions(+), 18 deletions(-)
+
+diff --git a/misc/fuse2fs.c b/misc/fuse2fs.c
+index cee9e657c..242bbfd22 100644
+--- a/misc/fuse2fs.c
++++ b/misc/fuse2fs.c
+@@ -229,6 +229,7 @@ struct fuse2fs {
+ uint8_t directio;
+ uint8_t acl;
+
++ int logfd;
+ int blocklog;
+ unsigned int blockmask;
+ unsigned long offset;
+@@ -792,6 +793,111 @@ static void op_destroy(void *p EXT2FS_ATTR((unused)))
+ pthread_mutex_unlock(&ff->bfl);
+ }
+
++/* Reopen @stream with @fileno */
++static int fuse2fs_freopen_stream(const char *path, int fileno, FILE
*stream)
++{
++ char _fdpath[256];
++ const char *fdpath;
++ FILE *fp;
++ int ret;
++
++ ret = snprintf(_fdpath, sizeof(_fdpath), "/dev/fd/%d", fileno);
++ if (ret >= sizeof(_fdpath))
++ fdpath = path;
++ else
++ fdpath = _fdpath;
++
++ /*
++ * C23 defines std{out,err} as an expression of type FILE* that need
++ * not be an lvalue. What this means is that we can't just assign to
++ * stdout: we have to use freopen, which takes a path.
++ *
++ * There's no guarantee that the OS provides a /dev/fd/X alias for
open
++ * file descriptors, so if that fails, fall back to the original log
++ * file path. We'd rather not do a path-based reopen because that
++ * exposes us to rename race attacks.
++ */
++ fp = freopen(fdpath, "a", stream);
++ if (!fp && errno == ENOENT && fdpath == _fdpath)
++ fp = freopen(path, "a", stream);
++ if (!fp) {
++ perror(fdpath);
++ return -1;
++ }
++
++ return 0;
++}
++
++/* Redirect stdout/stderr to a file, or return a mount-compatible error. */
++static int fuse2fs_capture_output(struct fuse2fs *ff, const char *path)
++{
++ int ret;
++ int fd;
++
++ /*
++ * First, open the log file path with system calls so that we can
++ * redirect the stdout/stderr file numbers (typically 1 and 2) to our
++ * logfile descriptor. We'd like to avoid allocating extra file
++ * objects in the kernel if we can because pos will be the same
between
++ * stdout and stderr.
++ */
++ if (ff->logfd < 0) {
++ fd = open(path, O_WRONLY | O_CREAT | O_APPEND, 0600);
++ if (fd < 0) {
++ perror(path);
++ return -1;
++ }
++
++ /*
++ * Save the newly opened fd in case we have to do this again
in
++ * op_init.
++ */
++ ff->logfd = fd;
++ }
++
++ ret = dup2(ff->logfd, STDOUT_FILENO);
++ if (ret < 0) {
++ perror(path);
++ return -1;
++ }
++
++ ret = dup2(ff->logfd, STDERR_FILENO);
++ if (ret < 0) {
++ perror(path);
++ return -1;
++ }
++
++ /*
++ * Now that we've changed STD{OUT,ERR}_FILENO to be the log file, use
++ * freopen to make sure that std{out,err} (the C library abstractions)
++ * point to the STDXXX_FILENO because any of our library dependencies
++ * might decide to printf to one of those streams and we want to
++ * capture all output in the log.
++ */
++ ret = fuse2fs_freopen_stream(path, STDOUT_FILENO, stdout);
++ if (ret)
++ return ret;
++ ret = fuse2fs_freopen_stream(path, STDERR_FILENO, stderr);
++ if (ret)
++ return ret;
++
++ return 0;
++}
++
++/* Set up debug and error logging files */
++static int fuse2fs_setup_logging(struct fuse2fs *ff)
++{
++ char *logfile = getenv("FUSE2FS_LOGFILE");
++ if (logfile)
++ return fuse2fs_capture_output(ff, logfile);
++
++ /* in kernel mode, try to log errors to the kernel log */
++ if (ff->kernel)
++ fuse2fs_capture_output(ff, "/dev/ttyprintk");
++
++ return 0;
++}
++
+ static void *op_init(struct fuse_conn_info *conn
+ #if FUSE_VERSION >= FUSE_MAKE_VERSION(3, 0)
+ , struct fuse_config *cfg EXT2FS_ATTR((unused))
+@@ -807,6 +913,17 @@ static void *op_init(struct fuse_conn_info *conn
+ translate_error(global_fs, 0, EXT2_ET_BAD_MAGIC);
+ return NULL;
+ }
++
++ /*
++ * Configure logging a second time, because libfuse might have
++ * redirected std{out,err} as part of daemonization. If this fails,
++ * give up and move on.
++ */
++ fuse2fs_setup_logging(ff);
++ if (ff->logfd >= 0)
++ close(ff->logfd);
++ ff->logfd = -1;
++
+ fs = ff->fs;
+ dbg_printf(ff, "%s: dev=%s\n", __func__, fs->device_name);
+ #ifdef FUSE_CAP_IOCTL_DIR
+@@ -4448,7 +4565,6 @@ int main(int argc, char *argv[])
+ struct fuse2fs fctx;
+ errcode_t err;
+ FILE *orig_stderr = stderr;
+- char *logfile;
+ char extra_args[BUFSIZ];
+ int ret;
+ int flags = EXT2_FLAG_64BITS | EXT2_FLAG_THREADS |
EXT2_FLAG_EXCLUSIVE |
+@@ -4456,6 +4572,7 @@ int main(int argc, char *argv[])
+
+ memset(&fctx, 0, sizeof(fctx));
+ fctx.magic = FUSE2FS_MAGIC;
++ fctx.logfd = -1;
+
+ ret = fuse_opt_parse(&args, &fctx, fuse2fs_opts, fuse2fs_opt_proc);
+ if (ret)
+@@ -4482,23 +4599,11 @@ int main(int argc, char *argv[])
+ #endif
+ add_error_table(&et_ext2_error_table);
+
+- /* Set up error logging */
+- logfile = getenv("FUSE2FS_LOGFILE");
+- if (logfile) {
+- FILE *fp = fopen(logfile, "a");
+- if (!fp) {
+- perror(logfile);
+- goto out;
+- }
+- stderr = fp;
+- stdout = fp;
+- } else if (fctx.kernel) {
+- /* in kernel mode, try to log errors to the kernel log */
+- FILE *fp = fopen("/dev/ttyprintk", "a");
+- if (fp) {
+- stderr = fp;
+- stdout = fp;
+- }
++ ret = fuse2fs_setup_logging(&fctx);
++ if (ret) {
++ /* operational error */
++ ret = 2;
++ goto out;
+ }
+
+ /* Will we allow users to allocate every last block? */
+--
+cgit 1.2.3-korg
+
- [[SM-Commit] ] GIT changes to master grimoire by Ismael Luceno (623d1566f00205dcc3c34de6b1dc579e10cdb5f1), Ismael Luceno, 11/27/2025
Archive powered by MHonArc 2.6.24.