From dd428959713998d3f973bcf2762d489ef27d9f13 Mon Sep 17 00:00:00 2001 From: Martin Schwenke Date: Wed, 13 May 2020 13:45:02 +1000 Subject: swrap: Abort if socket wrapper directory is too long to be usable If the socket wrapper directory path is too long to allow reliable construction of the required Unix domain socket paths then convert_in_un_alloc() can return ENFILE if paths are truncated in unfortunate ways. This can be very hard to debug since, for example, bind(2) should never return ENFILE. Instead, abort if the path returned by realpath(3) is unusable. The code structure is slightly weird but this accommodates an additional change. Signed-off-by: Martin Schwenke Reviewed-by: Andreas Schneider Reviewed-by: Stefan Metzmacher --- src/socket_wrapper.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'src') diff --git a/src/socket_wrapper.c b/src/socket_wrapper.c index 189c410..38df265 100644 --- a/src/socket_wrapper.c +++ b/src/socket_wrapper.c @@ -1409,10 +1409,30 @@ static int swrap_un_path_EINVAL(struct sockaddr_un *un, return 0; } +static bool swrap_dir_usable(const char *swrap_dir) +{ + struct sockaddr_un un; + int ret; + + ret = swrap_un_path(&un, swrap_dir, SOCKET_TYPE_CHAR_TCP, 0, 0); + if (ret == 0) { + return true; + } + + ret = swrap_un_path_EINVAL(&un, swrap_dir); + if (ret == 0) { + return true; + } + + return false; +} + static char *socket_wrapper_dir(void) { char *swrap_dir = NULL; char *s = getenv("SOCKET_WRAPPER_DIR"); + char *t; + bool ok; if (s == NULL) { SWRAP_LOG(SWRAP_LOG_WARN, "SOCKET_WRAPPER_DIR not set"); @@ -1427,6 +1447,17 @@ static char *socket_wrapper_dir(void) abort(); } + ok = swrap_dir_usable(swrap_dir); + if (ok) { + goto done; + } + + free(swrap_dir); + + SWRAP_LOG(SWRAP_LOG_ERROR, "SOCKET_WRAPPER_DIR is too long"); + abort(); + +done: SWRAP_LOG(SWRAP_LOG_TRACE, "socket_wrapper_dir: %s", swrap_dir); return swrap_dir; } -- cgit