]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
import: skip sockets and fifos when creating archives 41090/head
authorZbigniew Jędrzejewski-Szmek <zbyszek@amutable.com>
Fri, 13 Mar 2026 10:08:07 +0000 (11:08 +0100)
committerLuca Boccassi <luca.boccassi@gmail.com>
Fri, 13 Mar 2026 18:13:19 +0000 (18:13 +0000)
Fixes #40239.

$ SYSTEMD_LOG_LEVEL=debug SYSTEMD_LOG_LOCATION=1 build/test-tar -c /var/tmp/tar1.tar /var/tmp/with-fifo/
src/basic/dlfcn-util.c:66: Loaded shared library 'libarchive.so.13' via dlopen().
src/shared/tar-util.c:1422: Archiving '.'...
src/basic/dlfcn-util.c:66: Loaded shared library 'libacl.so.1' via dlopen().
src/shared/tar-util.c:1152: Skipping './fifo' (fifo).
src/shared/tar-util.c:1152: Skipping './unix' (sock).

src/shared/tar-util.c

index d2a991ba135e961938ee114a7c06a76e43671f4e..33395e96bcf21099b932d780fbcffb00f9b35b97 100644 (file)
@@ -1130,6 +1130,36 @@ struct make_archive_data {
         int have_unique_mount_id;
 };
 
+static int filter_item(
+                int inode_fd,
+                const struct statx *sx,
+                const char *path) {
+        mode_t m;
+        int r;
+
+        assert(inode_fd >= 0);
+        assert(sx);
+        assert(path);
+
+        if (FLAGS_SET(sx->stx_mask, STATX_TYPE))
+                m = sx->stx_mode;
+        else {
+                struct stat st;
+                r = RET_NERRNO(fstat(inode_fd, &st));
+                if (r < 0)
+                        return log_error_errno(r, "Failed to stat '%s': %m", path);
+                m = st.st_mode;
+        }
+
+        /* Filter out sockets, fifos, and weird misc fds such as eventfds() that have no inode type. */
+        if (IN_SET(m & S_IFMT, S_IFSOCK, S_IFIFO, 0)) {
+                log_debug("Skipping '%s' (%s).", path, inode_type_to_string(m) ?: "unknown");
+                return false;
+        }
+
+        return true;
+}
+
 static int hardlink_lookup(
                 struct make_archive_data *d,
                 int inode_fd,
@@ -1387,7 +1417,13 @@ static int archive_item(
         assert(inode_fd >= 0);
         assert(sx);
 
-        log_debug("Archiving %s\n", path);
+        r = filter_item(inode_fd, sx, path);
+        if (r < 0)
+                return r;
+        if (r == 0)
+                return RECURSE_DIR_CONTINUE;
+
+        log_debug("Archiving '%s'...", path);
 
         _cleanup_(archive_entry_freep) struct archive_entry *entry = NULL;
         entry = sym_archive_entry_new();