From ebc3f31747cbd44cd7353ffa8bd7f05e4683520e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Forsman?= Date: Sat, 24 Jan 2026 22:47:53 +0100 Subject: [PATCH 1/4] libredirect: fixup TAB -> SPACE for indentation The whole file is indented with 4 SPACEs, except two recently added functions that wrongly use TABs. Fixes: e6a936c760e078f5f2e52673d6c4b36f1f6d945b ("libredirect: add 'bind' for AF_UNIX") Fixes: 599a2f2fbe701b9ca2f12e9a97b77fc878e4cd0f ("libredirect: add 'connect' for AF_UNIX") --- pkgs/by-name/li/libredirect/libredirect.c | 32 +++++++++++------------ 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/pkgs/by-name/li/libredirect/libredirect.c b/pkgs/by-name/li/libredirect/libredirect.c index 011b5e6965c5..f700547c307c 100644 --- a/pkgs/by-name/li/libredirect/libredirect.c +++ b/pkgs/by-name/li/libredirect/libredirect.c @@ -117,14 +117,14 @@ WRAPPER(int, bind)(int socket, const struct sockaddr *addr, socklen_t addr_len) char buf[PATH_MAX]; const struct sockaddr *real_addr = addr; if (addr->sa_family == AF_UNIX) { - struct sockaddr_un real_addr_un = *(struct sockaddr_un *)addr; - const char *sun_path = rewrite(real_addr_un.sun_path, buf); - if (sun_path != real_addr_un.sun_path) { - strncpy(real_addr_un.sun_path, buf, sizeof(real_addr_un.sun_path) - 1); - real_addr_un.sun_path[sizeof(real_addr_un.sun_path) - 1] = '\0'; - real_addr = (struct sockaddr *)&real_addr_un; - addr_len = offsetof(struct sockaddr_un, sun_path) + strlen(real_addr_un.sun_path) + 1; - } + struct sockaddr_un real_addr_un = *(struct sockaddr_un *)addr; + const char *sun_path = rewrite(real_addr_un.sun_path, buf); + if (sun_path != real_addr_un.sun_path) { + strncpy(real_addr_un.sun_path, buf, sizeof(real_addr_un.sun_path) - 1); + real_addr_un.sun_path[sizeof(real_addr_un.sun_path) - 1] = '\0'; + real_addr = (struct sockaddr *)&real_addr_un; + addr_len = offsetof(struct sockaddr_un, sun_path) + strlen(real_addr_un.sun_path) + 1; + } } return bind_real(socket, real_addr, addr_len); } @@ -136,14 +136,14 @@ WRAPPER(int, connect)(int socket, const struct sockaddr *addr, socklen_t addr_le char buf[PATH_MAX]; const struct sockaddr *real_addr = addr; if (addr->sa_family == AF_UNIX) { - struct sockaddr_un real_addr_un = *(struct sockaddr_un *)addr; - const char *sun_path = rewrite(real_addr_un.sun_path, buf); - if (sun_path != real_addr_un.sun_path) { - strncpy(real_addr_un.sun_path, buf, sizeof(real_addr_un.sun_path) - 1); - real_addr_un.sun_path[sizeof(real_addr_un.sun_path) - 1] = '\0'; - real_addr = (struct sockaddr *)&real_addr_un; - addr_len = offsetof(struct sockaddr_un, sun_path) + strlen(real_addr_un.sun_path) + 1; - } + struct sockaddr_un real_addr_un = *(struct sockaddr_un *)addr; + const char *sun_path = rewrite(real_addr_un.sun_path, buf); + if (sun_path != real_addr_un.sun_path) { + strncpy(real_addr_un.sun_path, buf, sizeof(real_addr_un.sun_path) - 1); + real_addr_un.sun_path[sizeof(real_addr_un.sun_path) - 1] = '\0'; + real_addr = (struct sockaddr *)&real_addr_un; + addr_len = offsetof(struct sockaddr_un, sun_path) + strlen(real_addr_un.sun_path) + 1; + } } return connect_real(socket, real_addr, addr_len); } From 34724e6988909925059c1658b22a0dbe2ed7f324 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Forsman?= Date: Sat, 24 Jan 2026 23:11:41 +0100 Subject: [PATCH 2/4] libredirect: abort if rewritten UNIX socket path is too long Use snprintf instead of strncpy to make it easier/more efficient to detect truncation. abort() (and nothing else) is already used for error handling in rewrite(), so use that here too, in bind() and connect(). --- pkgs/by-name/li/libredirect/libredirect.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/pkgs/by-name/li/libredirect/libredirect.c b/pkgs/by-name/li/libredirect/libredirect.c index f700547c307c..c1a6720692ec 100644 --- a/pkgs/by-name/li/libredirect/libredirect.c +++ b/pkgs/by-name/li/libredirect/libredirect.c @@ -120,8 +120,10 @@ WRAPPER(int, bind)(int socket, const struct sockaddr *addr, socklen_t addr_len) struct sockaddr_un real_addr_un = *(struct sockaddr_un *)addr; const char *sun_path = rewrite(real_addr_un.sun_path, buf); if (sun_path != real_addr_un.sun_path) { - strncpy(real_addr_un.sun_path, buf, sizeof(real_addr_un.sun_path) - 1); - real_addr_un.sun_path[sizeof(real_addr_un.sun_path) - 1] = '\0'; + int n = snprintf(real_addr_un.sun_path, sizeof(real_addr_un.sun_path), "%s", buf); + if (n < 0 || n >= sizeof(real_addr_un.sun_path)) { + abort(); + } real_addr = (struct sockaddr *)&real_addr_un; addr_len = offsetof(struct sockaddr_un, sun_path) + strlen(real_addr_un.sun_path) + 1; } @@ -139,8 +141,10 @@ WRAPPER(int, connect)(int socket, const struct sockaddr *addr, socklen_t addr_le struct sockaddr_un real_addr_un = *(struct sockaddr_un *)addr; const char *sun_path = rewrite(real_addr_un.sun_path, buf); if (sun_path != real_addr_un.sun_path) { - strncpy(real_addr_un.sun_path, buf, sizeof(real_addr_un.sun_path) - 1); - real_addr_un.sun_path[sizeof(real_addr_un.sun_path) - 1] = '\0'; + int n = snprintf(real_addr_un.sun_path, sizeof(real_addr_un.sun_path), "%s", buf); + if (n < 0 || n >= sizeof(real_addr_un.sun_path)) { + abort(); + } real_addr = (struct sockaddr *)&real_addr_un; addr_len = offsetof(struct sockaddr_un, sun_path) + strlen(real_addr_un.sun_path) + 1; } From f8d95d174a505957b41fcd4a31da1364ad702cf3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Forsman?= Date: Sat, 24 Jan 2026 17:32:11 +0100 Subject: [PATCH 3/4] libredirect: fix type of listxattr, llistxattr func pointers Copy paste mistake. --- pkgs/by-name/li/libredirect/libredirect.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/by-name/li/libredirect/libredirect.c b/pkgs/by-name/li/libredirect/libredirect.c index c1a6720692ec..29169facf8ed 100644 --- a/pkgs/by-name/li/libredirect/libredirect.c +++ b/pkgs/by-name/li/libredirect/libredirect.c @@ -390,7 +390,7 @@ WRAPPER_DEF(opendir) #if !defined(__APPLE__) WRAPPER(ssize_t, listxattr)(const char * path, char * list, size_t size) { - int (*listxattr_real) (const char *, char *, size_t) = LOOKUP_REAL(listxattr); + ssize_t (*listxattr_real) (const char *, char *, size_t) = LOOKUP_REAL(listxattr); char buf[PATH_MAX]; return listxattr_real(rewrite(path, buf), list, size); } @@ -400,7 +400,7 @@ WRAPPER_DEF(listxattr); #if !defined(__APPLE__) WRAPPER(ssize_t, llistxattr)(const char * path, char * list, size_t size) { - int (*llistxattr_real) (const char *, char *, size_t) = LOOKUP_REAL(llistxattr); + ssize_t (*llistxattr_real) (const char *, char *, size_t) = LOOKUP_REAL(llistxattr); char buf[PATH_MAX]; return llistxattr_real(rewrite(path, buf), list, size); } From 6656986570b3a421aed445fadae00db26c49ba34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Forsman?= Date: Fri, 23 Jan 2026 21:37:18 +0100 Subject: [PATCH 4/4] libredirect: add remaining sys/xattr.h functions that take a path Specifically: getxattr, lgetxattr, setxattr, lsetxattr, removexattr, lremovexattr. The filesystem in the Nix build sandbox doesn't support extended attributes, so I'm unable to add tests. --- pkgs/by-name/li/libredirect/libredirect.c | 60 +++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/pkgs/by-name/li/libredirect/libredirect.c b/pkgs/by-name/li/libredirect/libredirect.c index 29169facf8ed..d0b9ae8b9626 100644 --- a/pkgs/by-name/li/libredirect/libredirect.c +++ b/pkgs/by-name/li/libredirect/libredirect.c @@ -387,6 +387,26 @@ WRAPPER(DIR *, opendir)(const char * path) } WRAPPER_DEF(opendir) +#if !defined(__APPLE__) +WRAPPER(ssize_t, getxattr)(const char * path, const char * name, void * value, size_t size) +{ + ssize_t (*getxattr_real) (const char *, const char *, void *, size_t) = LOOKUP_REAL(getxattr); + char buf[PATH_MAX]; + return getxattr_real(rewrite(path, buf), name, value, size); +} +WRAPPER_DEF(getxattr); +#endif + +#if !defined(__APPLE__) +WRAPPER(ssize_t, lgetxattr)(const char * path, const char * name, void * value, size_t size) +{ + ssize_t (*lgetxattr_real) (const char *, const char *, void *, size_t) = LOOKUP_REAL(lgetxattr); + char buf[PATH_MAX]; + return lgetxattr_real(rewrite(path, buf), name, value, size); +} +WRAPPER_DEF(lgetxattr); +#endif + #if !defined(__APPLE__) WRAPPER(ssize_t, listxattr)(const char * path, char * list, size_t size) { @@ -407,6 +427,46 @@ WRAPPER(ssize_t, llistxattr)(const char * path, char * list, size_t size) WRAPPER_DEF(llistxattr); #endif +#if !defined(__APPLE__) +WRAPPER(int, setxattr)(const char * path, const char * name, const void * value, size_t size, int flags) +{ + int (*setxattr_real) (const char *, const char *, const void *, size_t, int) = LOOKUP_REAL(setxattr); + char buf[PATH_MAX]; + return setxattr_real(rewrite(path, buf), name, value, size, flags); +} +WRAPPER_DEF(setxattr); +#endif + +#if !defined(__APPLE__) +WRAPPER(int, lsetxattr)(const char * path, const char * name, const void * value, size_t size, int flags) +{ + int (*lsetxattr_real) (const char *, const char *, const void *, size_t, int) = LOOKUP_REAL(lsetxattr); + char buf[PATH_MAX]; + return lsetxattr_real(rewrite(path, buf), name, value, size, flags); +} +WRAPPER_DEF(setxattr); +#endif + +#if !defined(__APPLE__) +WRAPPER(int, removexattr)(const char * path, const char * name) +{ + int (*removexattr_real) (const char *, const char *) = LOOKUP_REAL(removexattr); + char buf[PATH_MAX]; + return removexattr_real(rewrite(path, buf), name); +} +WRAPPER_DEF(removexattr); +#endif + +#if !defined(__APPLE__) +WRAPPER(int, lremovexattr)(const char * path, const char * name) +{ + int (*lremovexattr_real) (const char *, const char *) = LOOKUP_REAL(lremovexattr); + char buf[PATH_MAX]; + return lremovexattr_real(rewrite(path, buf), name); +} +WRAPPER_DEF(lremovexattr); +#endif + #define SYSTEM_CMD_MAX 512 static char * replace_substring(char * source, char * buf, char * replace_string, char * start_ptr, char * suffix_ptr) {