diff options
author | Martin Schwenke <martin@meltin.net> | 2020-05-13 13:45:02 +1000 |
---|---|---|
committer | Stefan Metzmacher <metze@samba.org> | 2020-06-22 16:43:47 +0200 |
commit | dd428959713998d3f973bcf2762d489ef27d9f13 (patch) | |
tree | 5447e804d96eabf67c297bc48c30afc0415bf3f4 | |
parent | fc1e98f8ca51ca4de7551e61b6b9c6c99d183b10 (diff) | |
download | socket_wrapper-dd428959713998d3f973bcf2762d489ef27d9f13.tar.gz socket_wrapper-dd428959713998d3f973bcf2762d489ef27d9f13.tar.xz socket_wrapper-dd428959713998d3f973bcf2762d489ef27d9f13.zip |
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 <martin@meltin.net>
Reviewed-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
-rw-r--r-- | src/socket_wrapper.c | 31 |
1 files changed, 31 insertions, 0 deletions
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; } |