chiark / gitweb /
stest/udp-preload: Be more relaxed about paths
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Thu, 5 Dec 2019 02:21:56 +0000 (02:21 +0000)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 7 Dec 2019 15:49:34 +0000 (15:49 +0000)
We would give ENAMETOOLONG if the specified path plus a maximal IPv6
address string wouldn't fit.  But in practice we don't use IPv6
addresses which stringify to anything that long, and this imposes an
annoyingly short restriction on the length of the emulation socket
directory path (a restriction which is going to be not met in my own
working tree when I add more sophisticated tests).

Instead, pass the suffix string to sun_prep and do the length check on
the actual length.  This means that addresses with short strings can
work, even if in principle addresses with long strings might fail.

Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
stest/udp-preload.c

index 1f3e7e3921a26a1717b56e770352078c87cbd68d..b5897bb877644a68de887e29b7712b586207caf1 100644 (file)
@@ -164,20 +164,20 @@ static int str2addrport(char *str,
     return 0;
 }
 
-static char *sun_prep(struct sockaddr_un *sun) {
+static int sun_prep(struct sockaddr_un *sun, const char *leaf) {
     const char *dir=getenv("UDP_PRELOAD_DIR");
     if (!dir) { errno=ECHILD; return 0; }
 
     memset(sun,0,sizeof(*sun));
     sun->sun_family=AF_UNIX;
     size_t dl = strlen(dir);
-    if (dl + 1 + ADDRPORTSTRLEN + 1 > sizeof(sun->sun_path)) {
-       errno=ENAMETOOLONG; return 0;
+    if (dl + 1 + strlen(leaf) + 1 > sizeof(sun->sun_path)) {
+       errno=ENAMETOOLONG; return -1;
     }
     strcpy(sun->sun_path,dir);
-    char *p=sun->sun_path+dl;
-    *p++='/';
-    return p;
+    sun->sun_path[dl]='/';
+    strcpy(sun->sun_path+dl+1,leaf);
+    return 0;
 }
 
 WRAP(socket) {
@@ -215,9 +215,9 @@ WRAP(bind) {
     fdinfo *ent=lookup(fd);
     if (!ent) return old_bind(fd,addr,addrlen);
     struct sockaddr_un sun;
-    char *p=sun_prep(&sun);
-    if (!p) return -1;
-    if (addrport2str(p,addr,addrlen)) return -1;
+    char tbuf[ADDRPORTSTRLEN+1];
+    if (addrport2str(tbuf,addr,addrlen)) return -1;
+    if (sun_prep(&sun,tbuf)) return -1;
 //fprintf(stderr,"binding %s\n",sun.sun_path);
     if (unlink(sun.sun_path) && errno!=ENOENT) return -1;
     return old_bind(fd,(const void*)&sun,sizeof(sun));
@@ -262,9 +262,7 @@ ssize_t TWRAP(sendto) {
     if (!leaf) leaf="udp";
     if (strlen(leaf) > ADDRPORTSTRLEN) { errno=ENAMETOOLONG; return -1; }
     struct sockaddr_un sun;
-    char *p=sun_prep(&sun);
-    if (!p) return -1;
-    strcpy(p,leaf);
+    if (sun_prep(&sun,leaf)) return -1;
 
     char tbuf[ADDRPORTSTRLEN+1];
     memset(tbuf,0,sizeof(tbuf));