From e3ca4a767a68d127df548d82669aba3689bd84f4 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 24 May 2024 12:28:51 +0200 Subject: [PATCH] fix(unix): Pass correct path length for abstract sockets (#430) --- src/unixdgram.c | 59 ++++++++++++++++++++++++------------------------ src/unixstream.c | 24 ++++++++++---------- 2 files changed, 42 insertions(+), 41 deletions(-) diff --git a/src/unixdgram.c b/src/unixdgram.c index 69093d73..1d6e4757 100644 --- a/src/unixdgram.c +++ b/src/unixdgram.c @@ -16,13 +16,6 @@ #define UNIXDGRAM_DATAGRAMSIZE 8192 -/* provide a SUN_LEN macro if sys/un.h doesn't (e.g. Android) */ -#ifndef SUN_LEN -#define SUN_LEN(ptr) \ - ((size_t) (((struct sockaddr_un *) 0)->sun_path) \ - + strlen ((ptr)->sun_path)) -#endif - /*=========================================================================*\ * Internal function prototypes \*=========================================================================*/ @@ -42,8 +35,8 @@ static int meth_receivefrom(lua_State *L); static int meth_sendto(lua_State *L); static int meth_getsockname(lua_State *L); -static const char *unixdgram_tryconnect(p_unix un, const char *path); -static const char *unixdgram_trybind(p_unix un, const char *path); +static const char *unixdgram_tryconnect(p_unix un, const char *path, size_t len); +static const char *unixdgram_trybind(p_unix un, const char *path, size_t len); /* unixdgram object methods */ static luaL_Reg unixdgram_methods[] = { @@ -133,13 +126,12 @@ static int meth_send(lua_State *L) static int meth_sendto(lua_State *L) { p_unix un = (p_unix) auxiliar_checkclass(L, "unixdgram{unconnected}", 1); - size_t count, sent = 0; + size_t count, sent, len = 0; const char *data = luaL_checklstring(L, 2, &count); - const char *path = luaL_checkstring(L, 3); + const char *path = luaL_checklstring(L, 3, &len); p_timeout tm = &un->tm; int err; struct sockaddr_un remote; - size_t len = strlen(path); if (len >= sizeof(remote.sun_path)) { lua_pushnil(L); @@ -148,7 +140,7 @@ static int meth_sendto(lua_State *L) } memset(&remote, 0, sizeof(remote)); - strcpy(remote.sun_path, path); + memcpy(remote.sun_path, path, len); remote.sun_family = AF_UNIX; timeout_markstart(tm); #ifdef UNIX_HAS_SUN_LEN @@ -264,18 +256,22 @@ static int meth_dirty(lua_State *L) { /*-------------------------------------------------------------------------*\ * Binds an object to an address \*-------------------------------------------------------------------------*/ -static const char *unixdgram_trybind(p_unix un, const char *path) { +static const char *unixdgram_trybind(p_unix un, const char *path, size_t len) { struct sockaddr_un local; - size_t len = strlen(path); + int err; if (len >= sizeof(local.sun_path)) return "path too long"; memset(&local, 0, sizeof(local)); - strcpy(local.sun_path, path); + memcpy(local.sun_path, path, len); local.sun_family = AF_UNIX; - size_t addrlen = SUN_LEN(&local); #ifdef UNIX_HAS_SUN_LEN - local.sun_len = addrlen + 1; + local.sun_len = sizeof(local.sun_family) + sizeof(local.sun_len) + + len + 1; + err = socket_bind(&un->sock, (SA *) &local, local.sun_len); + +#else + err = socket_bind(&un->sock, (SA *) &local, + sizeof(local.sun_family) + len); #endif - int err = socket_bind(&un->sock, (SA *) &local, addrlen); if (err != IO_DONE) socket_destroy(&un->sock); return socket_strerror(err); } @@ -283,8 +279,9 @@ static const char *unixdgram_trybind(p_unix un, const char *path) { static int meth_bind(lua_State *L) { p_unix un = (p_unix) auxiliar_checkclass(L, "unixdgram{unconnected}", 1); - const char *path = luaL_checkstring(L, 2); - const char *err = unixdgram_trybind(un, path); + size_t len; + const char *path = luaL_checklstring(L, 2, &len); + const char *err = unixdgram_trybind(un, path, len); if (err) { lua_pushnil(L); lua_pushstring(L, err); @@ -313,20 +310,23 @@ static int meth_getsockname(lua_State *L) /*-------------------------------------------------------------------------*\ * Turns a master unixdgram object into a client object. \*-------------------------------------------------------------------------*/ -static const char *unixdgram_tryconnect(p_unix un, const char *path) +static const char *unixdgram_tryconnect(p_unix un, const char *path, size_t len) { struct sockaddr_un remote; - size_t len = strlen(path); + int err; if (len >= sizeof(remote.sun_path)) return "path too long"; memset(&remote, 0, sizeof(remote)); - strcpy(remote.sun_path, path); + memcpy(remote.sun_path, path, len); remote.sun_family = AF_UNIX; timeout_markstart(&un->tm); - size_t addrlen = SUN_LEN(&remote); #ifdef UNIX_HAS_SUN_LEN - remote.sun_len = addrlen + 1; + remote.sun_len = sizeof(remote.sun_family) + sizeof(remote.sun_len) + + len + 1; + err = socket_connect(&un->sock, (SA *) &remote, remote.sun_len, &un->tm); +#else + err = socket_connect(&un->sock, (SA *) &remote, + sizeof(remote.sun_family) + len, &un->tm); #endif - int err = socket_connect(&un->sock, (SA *) &remote, addrlen, &un->tm); if (err != IO_DONE) socket_destroy(&un->sock); return socket_strerror(err); } @@ -334,8 +334,9 @@ static const char *unixdgram_tryconnect(p_unix un, const char *path) static int meth_connect(lua_State *L) { p_unix un = (p_unix) auxiliar_checkgroup(L, "unixdgram{any}", 1); - const char *path = luaL_checkstring(L, 2); - const char *err = unixdgram_tryconnect(un, path); + size_t len; + const char *path = luaL_checklstring(L, 2, &len); + const char *err = unixdgram_tryconnect(un, path, len); if (err) { lua_pushnil(L); lua_pushstring(L, err); diff --git a/src/unixstream.c b/src/unixstream.c index 02aced9c..89a8776a 100644 --- a/src/unixstream.c +++ b/src/unixstream.c @@ -33,8 +33,8 @@ static int meth_getstats(lua_State *L); static int meth_setstats(lua_State *L); static int meth_getsockname(lua_State *L); -static const char *unixstream_tryconnect(p_unix un, const char *path); -static const char *unixstream_trybind(p_unix un, const char *path); +static const char *unixstream_tryconnect(p_unix un, const char *path, size_t len); +static const char *unixstream_trybind(p_unix un, const char *path, size_t len); /* unixstream object methods */ static luaL_Reg unixstream_methods[] = { @@ -181,13 +181,12 @@ static int meth_accept(lua_State *L) { /*-------------------------------------------------------------------------*\ * Binds an object to an address \*-------------------------------------------------------------------------*/ -static const char *unixstream_trybind(p_unix un, const char *path) { +static const char *unixstream_trybind(p_unix un, const char *path, size_t len) { struct sockaddr_un local; - size_t len = strlen(path); int err; if (len >= sizeof(local.sun_path)) return "path too long"; memset(&local, 0, sizeof(local)); - strcpy(local.sun_path, path); + memcpy(local.sun_path, path, len); local.sun_family = AF_UNIX; #ifdef UNIX_HAS_SUN_LEN local.sun_len = sizeof(local.sun_family) + sizeof(local.sun_len) @@ -204,8 +203,9 @@ static const char *unixstream_trybind(p_unix un, const char *path) { static int meth_bind(lua_State *L) { p_unix un = (p_unix) auxiliar_checkclass(L, "unixstream{master}", 1); - const char *path = luaL_checkstring(L, 2); - const char *err = unixstream_trybind(un, path); + size_t len; + const char *path = luaL_checklstring(L, 2, &len); + const char *err = unixstream_trybind(un, path, len); if (err) { lua_pushnil(L); lua_pushstring(L, err); @@ -234,14 +234,13 @@ static int meth_getsockname(lua_State *L) /*-------------------------------------------------------------------------*\ * Turns a master unixstream object into a client object. \*-------------------------------------------------------------------------*/ -static const char *unixstream_tryconnect(p_unix un, const char *path) +static const char *unixstream_tryconnect(p_unix un, const char *path, size_t len) { struct sockaddr_un remote; int err; - size_t len = strlen(path); if (len >= sizeof(remote.sun_path)) return "path too long"; memset(&remote, 0, sizeof(remote)); - strcpy(remote.sun_path, path); + memcpy(remote.sun_path, path, len); remote.sun_family = AF_UNIX; timeout_markstart(&un->tm); #ifdef UNIX_HAS_SUN_LEN @@ -259,8 +258,9 @@ static const char *unixstream_tryconnect(p_unix un, const char *path) static int meth_connect(lua_State *L) { p_unix un = (p_unix) auxiliar_checkclass(L, "unixstream{master}", 1); - const char *path = luaL_checkstring(L, 2); - const char *err = unixstream_tryconnect(un, path); + size_t len; + const char *path = luaL_checklstring(L, 2, &len); + const char *err = unixstream_tryconnect(un, path, len); if (err) { lua_pushnil(L); lua_pushstring(L, err);