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