summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Schwenke <martin@meltin.net>2020-05-13 13:45:02 +1000
committerStefan Metzmacher <metze@samba.org>2020-06-22 16:43:47 +0200
commitdd428959713998d3f973bcf2762d489ef27d9f13 (patch)
tree5447e804d96eabf67c297bc48c30afc0415bf3f4
parentfc1e98f8ca51ca4de7551e61b6b9c6c99d183b10 (diff)
downloadsocket_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.c31
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;
}