diff options
author | Stefan Sperling <ssperling@sysmocom.de> | 2018-08-28 14:34:17 +0200 |
---|---|---|
committer | Harald Welte <laforge@gnumonks.org> | 2018-08-29 07:39:55 +0000 |
commit | 896ff6db161465d506bb9bb5bee2cdeef220dd2e (patch) | |
tree | 97a3b034dcd319b1b6312ff99a187f9a540640c5 | |
parent | 3953f41bbd7f1075f8585f6c306d35d095873474 (diff) |
Properly deal with sockaddr_un socket path length limitations.
In osmo_sock_unix_init(), add support for non-NUL-terminated unix
socket paths and return an error if the supplied socket path exceeds
the maximum socket path length supported by the operating system.
Change-Id: I19d935e5e3dd7928e6e153c6f5ad7044de726016
Related: OS#2673
-rw-r--r-- | src/socket.c | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/src/socket.c b/src/socket.c index 7e7f6d96..6f56efb5 100644 --- a/src/socket.c +++ b/src/socket.c @@ -605,22 +605,29 @@ int osmo_sock_unix_init(uint16_t type, uint8_t proto, struct sockaddr_un local; int sfd, rc, on = 1; unsigned int namelen; + const size_t socket_path_len = strlen(socket_path); if ((flags & (OSMO_SOCK_F_BIND | OSMO_SOCK_F_CONNECT)) == (OSMO_SOCK_F_BIND | OSMO_SOCK_F_CONNECT)) return -EINVAL; local.sun_family = AF_UNIX; - osmo_strlcpy(local.sun_path, socket_path, sizeof(local.sun_path)); + if (socket_path_len == sizeof(local.sun_path)) { + /* Handle corner-case where sun_path is not NUL-terminated. See the unix(7) man page. */ + memcpy(local.sun_path, socket_path, sizeof(local.sun_path)); + } else if (osmo_strlcpy(local.sun_path, socket_path, sizeof(local.sun_path)) >= sizeof(local.sun_path)) { + LOGP(DLGLOBAL, LOGL_ERROR, "Socket path exceeds maximum length of %zd bytes: %s\n", + sizeof(local.sun_path), socket_path); + return -ENOSPC; + } #if defined(BSD44SOCKETS) || defined(__UNIXWARE__) - local.sun_len = strlen(local.sun_path); + local.sun_len = socket_path_len; #endif #if defined(BSD44SOCKETS) || defined(SUN_LEN) namelen = SUN_LEN(&local); #else - namelen = strlen(local.sun_path) + - offsetof(struct sockaddr_un, sun_path); + namelen = socket_path_len + offsetof(struct sockaddr_un, sun_path); #endif sfd = socket(AF_UNIX, type, proto); |