diff options
| author | Kim Alvefur <zash@zash.se> | 2024-05-24 12:28:51 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-05-24 13:28:51 +0300 |
| commit | e3ca4a767a68d127df548d82669aba3689bd84f4 (patch) | |
| tree | 35ddba3aa60d47a9400291b5db8d6eeabc231c2d | |
| parent | 93eef5015e0dfe8d24071dd036f9a7f02160abeb (diff) | |
| download | luasocket-e3ca4a767a68d127df548d82669aba3689bd84f4.tar.gz luasocket-e3ca4a767a68d127df548d82669aba3689bd84f4.tar.bz2 luasocket-e3ca4a767a68d127df548d82669aba3689bd84f4.zip | |
fix(unix): Pass correct path length for abstract sockets (#430)
| -rw-r--r-- | src/unixdgram.c | 59 | ||||
| -rw-r--r-- | src/unixstream.c | 24 |
2 files changed, 42 insertions, 41 deletions
diff --git a/src/unixdgram.c b/src/unixdgram.c index 69093d7..1d6e475 100644 --- a/src/unixdgram.c +++ b/src/unixdgram.c | |||
| @@ -16,13 +16,6 @@ | |||
| 16 | 16 | ||
| 17 | #define UNIXDGRAM_DATAGRAMSIZE 8192 | 17 | #define UNIXDGRAM_DATAGRAMSIZE 8192 |
| 18 | 18 | ||
| 19 | /* provide a SUN_LEN macro if sys/un.h doesn't (e.g. Android) */ | ||
| 20 | #ifndef SUN_LEN | ||
| 21 | #define SUN_LEN(ptr) \ | ||
| 22 | ((size_t) (((struct sockaddr_un *) 0)->sun_path) \ | ||
| 23 | + strlen ((ptr)->sun_path)) | ||
| 24 | #endif | ||
| 25 | |||
| 26 | /*=========================================================================*\ | 19 | /*=========================================================================*\ |
| 27 | * Internal function prototypes | 20 | * Internal function prototypes |
| 28 | \*=========================================================================*/ | 21 | \*=========================================================================*/ |
| @@ -42,8 +35,8 @@ static int meth_receivefrom(lua_State *L); | |||
| 42 | static int meth_sendto(lua_State *L); | 35 | static int meth_sendto(lua_State *L); |
| 43 | static int meth_getsockname(lua_State *L); | 36 | static int meth_getsockname(lua_State *L); |
| 44 | 37 | ||
| 45 | static const char *unixdgram_tryconnect(p_unix un, const char *path); | 38 | static const char *unixdgram_tryconnect(p_unix un, const char *path, size_t len); |
| 46 | static const char *unixdgram_trybind(p_unix un, const char *path); | 39 | static const char *unixdgram_trybind(p_unix un, const char *path, size_t len); |
| 47 | 40 | ||
| 48 | /* unixdgram object methods */ | 41 | /* unixdgram object methods */ |
| 49 | static luaL_Reg unixdgram_methods[] = { | 42 | static luaL_Reg unixdgram_methods[] = { |
| @@ -133,13 +126,12 @@ static int meth_send(lua_State *L) | |||
| 133 | static int meth_sendto(lua_State *L) | 126 | static int meth_sendto(lua_State *L) |
| 134 | { | 127 | { |
| 135 | p_unix un = (p_unix) auxiliar_checkclass(L, "unixdgram{unconnected}", 1); | 128 | p_unix un = (p_unix) auxiliar_checkclass(L, "unixdgram{unconnected}", 1); |
| 136 | size_t count, sent = 0; | 129 | size_t count, sent, len = 0; |
| 137 | const char *data = luaL_checklstring(L, 2, &count); | 130 | const char *data = luaL_checklstring(L, 2, &count); |
| 138 | const char *path = luaL_checkstring(L, 3); | 131 | const char *path = luaL_checklstring(L, 3, &len); |
| 139 | p_timeout tm = &un->tm; | 132 | p_timeout tm = &un->tm; |
| 140 | int err; | 133 | int err; |
| 141 | struct sockaddr_un remote; | 134 | struct sockaddr_un remote; |
| 142 | size_t len = strlen(path); | ||
| 143 | 135 | ||
| 144 | if (len >= sizeof(remote.sun_path)) { | 136 | if (len >= sizeof(remote.sun_path)) { |
| 145 | lua_pushnil(L); | 137 | lua_pushnil(L); |
| @@ -148,7 +140,7 @@ static int meth_sendto(lua_State *L) | |||
| 148 | } | 140 | } |
| 149 | 141 | ||
| 150 | memset(&remote, 0, sizeof(remote)); | 142 | memset(&remote, 0, sizeof(remote)); |
| 151 | strcpy(remote.sun_path, path); | 143 | memcpy(remote.sun_path, path, len); |
| 152 | remote.sun_family = AF_UNIX; | 144 | remote.sun_family = AF_UNIX; |
| 153 | timeout_markstart(tm); | 145 | timeout_markstart(tm); |
| 154 | #ifdef UNIX_HAS_SUN_LEN | 146 | #ifdef UNIX_HAS_SUN_LEN |
| @@ -264,18 +256,22 @@ static int meth_dirty(lua_State *L) { | |||
| 264 | /*-------------------------------------------------------------------------*\ | 256 | /*-------------------------------------------------------------------------*\ |
| 265 | * Binds an object to an address | 257 | * Binds an object to an address |
| 266 | \*-------------------------------------------------------------------------*/ | 258 | \*-------------------------------------------------------------------------*/ |
| 267 | static const char *unixdgram_trybind(p_unix un, const char *path) { | 259 | static const char *unixdgram_trybind(p_unix un, const char *path, size_t len) { |
| 268 | struct sockaddr_un local; | 260 | struct sockaddr_un local; |
| 269 | size_t len = strlen(path); | 261 | int err; |
| 270 | if (len >= sizeof(local.sun_path)) return "path too long"; | 262 | if (len >= sizeof(local.sun_path)) return "path too long"; |
| 271 | memset(&local, 0, sizeof(local)); | 263 | memset(&local, 0, sizeof(local)); |
| 272 | strcpy(local.sun_path, path); | 264 | memcpy(local.sun_path, path, len); |
| 273 | local.sun_family = AF_UNIX; | 265 | local.sun_family = AF_UNIX; |
| 274 | size_t addrlen = SUN_LEN(&local); | ||
| 275 | #ifdef UNIX_HAS_SUN_LEN | 266 | #ifdef UNIX_HAS_SUN_LEN |
| 276 | local.sun_len = addrlen + 1; | 267 | local.sun_len = sizeof(local.sun_family) + sizeof(local.sun_len) |
| 268 | + len + 1; | ||
| 269 | err = socket_bind(&un->sock, (SA *) &local, local.sun_len); | ||
| 270 | |||
| 271 | #else | ||
| 272 | err = socket_bind(&un->sock, (SA *) &local, | ||
| 273 | sizeof(local.sun_family) + len); | ||
| 277 | #endif | 274 | #endif |
| 278 | int err = socket_bind(&un->sock, (SA *) &local, addrlen); | ||
| 279 | if (err != IO_DONE) socket_destroy(&un->sock); | 275 | if (err != IO_DONE) socket_destroy(&un->sock); |
| 280 | return socket_strerror(err); | 276 | return socket_strerror(err); |
| 281 | } | 277 | } |
| @@ -283,8 +279,9 @@ static const char *unixdgram_trybind(p_unix un, const char *path) { | |||
| 283 | static int meth_bind(lua_State *L) | 279 | static int meth_bind(lua_State *L) |
| 284 | { | 280 | { |
| 285 | p_unix un = (p_unix) auxiliar_checkclass(L, "unixdgram{unconnected}", 1); | 281 | p_unix un = (p_unix) auxiliar_checkclass(L, "unixdgram{unconnected}", 1); |
| 286 | const char *path = luaL_checkstring(L, 2); | 282 | size_t len; |
| 287 | const char *err = unixdgram_trybind(un, path); | 283 | const char *path = luaL_checklstring(L, 2, &len); |
| 284 | const char *err = unixdgram_trybind(un, path, len); | ||
| 288 | if (err) { | 285 | if (err) { |
| 289 | lua_pushnil(L); | 286 | lua_pushnil(L); |
| 290 | lua_pushstring(L, err); | 287 | lua_pushstring(L, err); |
| @@ -313,20 +310,23 @@ static int meth_getsockname(lua_State *L) | |||
| 313 | /*-------------------------------------------------------------------------*\ | 310 | /*-------------------------------------------------------------------------*\ |
| 314 | * Turns a master unixdgram object into a client object. | 311 | * Turns a master unixdgram object into a client object. |
| 315 | \*-------------------------------------------------------------------------*/ | 312 | \*-------------------------------------------------------------------------*/ |
| 316 | static const char *unixdgram_tryconnect(p_unix un, const char *path) | 313 | static const char *unixdgram_tryconnect(p_unix un, const char *path, size_t len) |
| 317 | { | 314 | { |
| 318 | struct sockaddr_un remote; | 315 | struct sockaddr_un remote; |
| 319 | size_t len = strlen(path); | 316 | int err; |
| 320 | if (len >= sizeof(remote.sun_path)) return "path too long"; | 317 | if (len >= sizeof(remote.sun_path)) return "path too long"; |
| 321 | memset(&remote, 0, sizeof(remote)); | 318 | memset(&remote, 0, sizeof(remote)); |
| 322 | strcpy(remote.sun_path, path); | 319 | memcpy(remote.sun_path, path, len); |
| 323 | remote.sun_family = AF_UNIX; | 320 | remote.sun_family = AF_UNIX; |
| 324 | timeout_markstart(&un->tm); | 321 | timeout_markstart(&un->tm); |
| 325 | size_t addrlen = SUN_LEN(&remote); | ||
| 326 | #ifdef UNIX_HAS_SUN_LEN | 322 | #ifdef UNIX_HAS_SUN_LEN |
| 327 | remote.sun_len = addrlen + 1; | 323 | remote.sun_len = sizeof(remote.sun_family) + sizeof(remote.sun_len) |
| 324 | + len + 1; | ||
| 325 | err = socket_connect(&un->sock, (SA *) &remote, remote.sun_len, &un->tm); | ||
| 326 | #else | ||
| 327 | err = socket_connect(&un->sock, (SA *) &remote, | ||
| 328 | sizeof(remote.sun_family) + len, &un->tm); | ||
| 328 | #endif | 329 | #endif |
| 329 | int err = socket_connect(&un->sock, (SA *) &remote, addrlen, &un->tm); | ||
| 330 | if (err != IO_DONE) socket_destroy(&un->sock); | 330 | if (err != IO_DONE) socket_destroy(&un->sock); |
| 331 | return socket_strerror(err); | 331 | return socket_strerror(err); |
| 332 | } | 332 | } |
| @@ -334,8 +334,9 @@ static const char *unixdgram_tryconnect(p_unix un, const char *path) | |||
| 334 | static int meth_connect(lua_State *L) | 334 | static int meth_connect(lua_State *L) |
| 335 | { | 335 | { |
| 336 | p_unix un = (p_unix) auxiliar_checkgroup(L, "unixdgram{any}", 1); | 336 | p_unix un = (p_unix) auxiliar_checkgroup(L, "unixdgram{any}", 1); |
| 337 | const char *path = luaL_checkstring(L, 2); | 337 | size_t len; |
| 338 | const char *err = unixdgram_tryconnect(un, path); | 338 | const char *path = luaL_checklstring(L, 2, &len); |
| 339 | const char *err = unixdgram_tryconnect(un, path, len); | ||
| 339 | if (err) { | 340 | if (err) { |
| 340 | lua_pushnil(L); | 341 | lua_pushnil(L); |
| 341 | lua_pushstring(L, err); | 342 | lua_pushstring(L, err); |
diff --git a/src/unixstream.c b/src/unixstream.c index 02aced9..89a8776 100644 --- a/src/unixstream.c +++ b/src/unixstream.c | |||
| @@ -33,8 +33,8 @@ static int meth_getstats(lua_State *L); | |||
| 33 | static int meth_setstats(lua_State *L); | 33 | static int meth_setstats(lua_State *L); |
| 34 | static int meth_getsockname(lua_State *L); | 34 | static int meth_getsockname(lua_State *L); |
| 35 | 35 | ||
| 36 | static const char *unixstream_tryconnect(p_unix un, const char *path); | 36 | static const char *unixstream_tryconnect(p_unix un, const char *path, size_t len); |
| 37 | static const char *unixstream_trybind(p_unix un, const char *path); | 37 | static const char *unixstream_trybind(p_unix un, const char *path, size_t len); |
| 38 | 38 | ||
| 39 | /* unixstream object methods */ | 39 | /* unixstream object methods */ |
| 40 | static luaL_Reg unixstream_methods[] = { | 40 | static luaL_Reg unixstream_methods[] = { |
| @@ -181,13 +181,12 @@ static int meth_accept(lua_State *L) { | |||
| 181 | /*-------------------------------------------------------------------------*\ | 181 | /*-------------------------------------------------------------------------*\ |
| 182 | * Binds an object to an address | 182 | * Binds an object to an address |
| 183 | \*-------------------------------------------------------------------------*/ | 183 | \*-------------------------------------------------------------------------*/ |
| 184 | static const char *unixstream_trybind(p_unix un, const char *path) { | 184 | static const char *unixstream_trybind(p_unix un, const char *path, size_t len) { |
| 185 | struct sockaddr_un local; | 185 | struct sockaddr_un local; |
| 186 | size_t len = strlen(path); | ||
| 187 | int err; | 186 | int err; |
| 188 | if (len >= sizeof(local.sun_path)) return "path too long"; | 187 | if (len >= sizeof(local.sun_path)) return "path too long"; |
| 189 | memset(&local, 0, sizeof(local)); | 188 | memset(&local, 0, sizeof(local)); |
| 190 | strcpy(local.sun_path, path); | 189 | memcpy(local.sun_path, path, len); |
| 191 | local.sun_family = AF_UNIX; | 190 | local.sun_family = AF_UNIX; |
| 192 | #ifdef UNIX_HAS_SUN_LEN | 191 | #ifdef UNIX_HAS_SUN_LEN |
| 193 | local.sun_len = sizeof(local.sun_family) + sizeof(local.sun_len) | 192 | 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) { | |||
| 204 | 203 | ||
| 205 | static int meth_bind(lua_State *L) { | 204 | static int meth_bind(lua_State *L) { |
| 206 | p_unix un = (p_unix) auxiliar_checkclass(L, "unixstream{master}", 1); | 205 | p_unix un = (p_unix) auxiliar_checkclass(L, "unixstream{master}", 1); |
| 207 | const char *path = luaL_checkstring(L, 2); | 206 | size_t len; |
| 208 | const char *err = unixstream_trybind(un, path); | 207 | const char *path = luaL_checklstring(L, 2, &len); |
| 208 | const char *err = unixstream_trybind(un, path, len); | ||
| 209 | if (err) { | 209 | if (err) { |
| 210 | lua_pushnil(L); | 210 | lua_pushnil(L); |
| 211 | lua_pushstring(L, err); | 211 | lua_pushstring(L, err); |
| @@ -234,14 +234,13 @@ static int meth_getsockname(lua_State *L) | |||
| 234 | /*-------------------------------------------------------------------------*\ | 234 | /*-------------------------------------------------------------------------*\ |
| 235 | * Turns a master unixstream object into a client object. | 235 | * Turns a master unixstream object into a client object. |
| 236 | \*-------------------------------------------------------------------------*/ | 236 | \*-------------------------------------------------------------------------*/ |
| 237 | static const char *unixstream_tryconnect(p_unix un, const char *path) | 237 | static const char *unixstream_tryconnect(p_unix un, const char *path, size_t len) |
| 238 | { | 238 | { |
| 239 | struct sockaddr_un remote; | 239 | struct sockaddr_un remote; |
| 240 | int err; | 240 | int err; |
| 241 | size_t len = strlen(path); | ||
| 242 | if (len >= sizeof(remote.sun_path)) return "path too long"; | 241 | if (len >= sizeof(remote.sun_path)) return "path too long"; |
| 243 | memset(&remote, 0, sizeof(remote)); | 242 | memset(&remote, 0, sizeof(remote)); |
| 244 | strcpy(remote.sun_path, path); | 243 | memcpy(remote.sun_path, path, len); |
| 245 | remote.sun_family = AF_UNIX; | 244 | remote.sun_family = AF_UNIX; |
| 246 | timeout_markstart(&un->tm); | 245 | timeout_markstart(&un->tm); |
| 247 | #ifdef UNIX_HAS_SUN_LEN | 246 | #ifdef UNIX_HAS_SUN_LEN |
| @@ -259,8 +258,9 @@ static const char *unixstream_tryconnect(p_unix un, const char *path) | |||
| 259 | static int meth_connect(lua_State *L) | 258 | static int meth_connect(lua_State *L) |
| 260 | { | 259 | { |
| 261 | p_unix un = (p_unix) auxiliar_checkclass(L, "unixstream{master}", 1); | 260 | p_unix un = (p_unix) auxiliar_checkclass(L, "unixstream{master}", 1); |
| 262 | const char *path = luaL_checkstring(L, 2); | 261 | size_t len; |
| 263 | const char *err = unixstream_tryconnect(un, path); | 262 | const char *path = luaL_checklstring(L, 2, &len); |
| 263 | const char *err = unixstream_tryconnect(un, path, len); | ||
| 264 | if (err) { | 264 | if (err) { |
| 265 | lua_pushnil(L); | 265 | lua_pushnil(L); |
| 266 | lua_pushstring(L, err); | 266 | lua_pushstring(L, err); |
