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); |