From 2a01345b9034b947bb179bce29a13028ea9ca64d Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Thu, 5 Dec 2019 02:21:56 +0000 Subject: [PATCH] stest/udp-preload: Be more relaxed about paths 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 --- stest/udp-preload.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/stest/udp-preload.c b/stest/udp-preload.c index 1f3e7e3..b5897bb 100644 --- a/stest/udp-preload.c +++ b/stest/udp-preload.c @@ -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)); -- 2.30.2