From: Jeremy Harris Date: Mon, 8 Aug 2022 18:46:03 +0000 (+0100) Subject: Symlink following for TLS creds files X-Git-Tag: exim-4.97-RC0~258 X-Git-Url: https://git.exim.org/exim.git/commitdiff_plain/ef57b25bfa7623c3f8a8e65f927165c4ddc7c43b Symlink following for TLS creds files --- diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog index 874d725f3..b813033c1 100644 --- a/doc/doc-txt/ChangeLog +++ b/doc/doc-txt/ChangeLog @@ -18,6 +18,11 @@ JH/04 Bug 2903: avoid exit on an attempt to rewrite a malformed address. Make the rewrite never match and keep the logging. Trust the admin to be using verify=header-syntax (to actually reject the message). +JH/05 Follow symlinks for placing a watch on TLS creds files. This means + (under Linux) we watch the dir containing the final file; previously + it would be the dir with the first symlink. We still do not monitor + the entire path. + Exim version 4.96 ----------------- diff --git a/src/src/tls.c b/src/src/tls.c index 3ed37bbb0..76e72b5f5 100644 --- a/src/src/tls.c +++ b/src/src/tls.c @@ -143,15 +143,29 @@ static BOOL tls_set_one_watch(const uschar * filename) # ifdef EXIM_HAVE_INOTIFY { +uschar buf[PATH_MAX]; +ssize_t len; uschar * s; if (Ustrcmp(filename, "system,cache") == 0) return TRUE; - if (!(s = Ustrrchr(filename, '/'))) return FALSE; + +for (unsigned loop = 20; + (len = readlink(CCS filename, CS buf, sizeof(buf))) >= 0; ) + { /* a symlink */ + if (--loop == 0) { errno = ELOOP; return FALSE; } + filename = buf[0] == '/' + ? string_copyn(buf, (unsigned)len) /* mem released by tls_set_watch */ + : string_sprintf("%.*s/%.*s", (int)(s - filename), (int)len); + s = Ustrrchr(filename, '/'); + } +if (errno != EINVAL) + return FALSE; /* other error */ + +/* not a symlink */ s = string_copyn(filename, s - filename); /* mem released by tls_set_watch */ -DEBUG(D_tls) debug_printf("watch dir '%s'\n", s); -/*XXX unclear what effect symlinked files will have for inotify */ +DEBUG(D_tls) debug_printf("watch dir '%s'\n", s); if (inotify_add_watch(tls_watch_fd, CCS s, IN_ONESHOT | IN_CLOSE_WRITE | IN_DELETE | IN_DELETE_SELF