From ebda598a4af7ead204e1f611ec066bb678a275d5 Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Mon, 17 Sep 2018 00:55:04 +0100 Subject: Avoid fixed-size buffers for file paths in DB open --- doc/doc-txt/ChangeLog | 4 ++++ src/src/exim_dbutil.c | 19 ++++++++++++++----- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog index 8d5f92b7f..f93622bf9 100644 --- a/doc/doc-txt/ChangeLog +++ b/doc/doc-txt/ChangeLog @@ -116,6 +116,10 @@ JH/24 Bug 2310: Raise a msg:fail:internal event for each undelivered recipient, and a msg:complete for the whole, when a message is manually reoved using -Mrm. Developement by Matthias Kurz, hacked on by JH. +JH/25 Avoid fixed-size buffers for pathnames in DB access. This required using + a "Gnu special" function, asprintf() in the DB utility binary builds; I + hope that is portable enough. + Exim version 4.91 ----------------- diff --git a/src/src/exim_dbutil.c b/src/src/exim_dbutil.c index 491a45315..17da205b4 100644 --- a/src/src/exim_dbutil.c +++ b/src/src/exim_dbutil.c @@ -253,14 +253,19 @@ dbfn_open(uschar *name, int flags, open_db *dbblock, BOOL lof) int rc; struct flock lock_data; BOOL read_only = flags == O_RDONLY; -uschar dirname[256], filename[256]; +uschar * dirname, * filename; /* The first thing to do is to open a separate file on which to lock. This ensures that Exim has exclusive use of the database before it even tries to open it. If there is a database, there should be a lock file in existence. */ -snprintf(CS dirname, sizeof(dirname), "%s/db", spool_directory); -snprintf(CS filename, sizeof(filename), "%.54s/%.200s.lockfile", dirname, name); +#ifdef COMPILE_UTILITY +asprintf(CSS &dirname, "%s/db", spool_directory); +asprintf(CSS &filename, "%s/%s.lockfile", dirname, name); +#else +dirname = string_sprintf("%s/db", spool_directory); +filename = string_sprintf("%s/%s.lockfile", dirname, name); +#endif dbblock->lockfd = Uopen(filename, flags, 0); if (dbblock->lockfd < 0) @@ -273,7 +278,7 @@ if (dbblock->lockfd < 0) /* Now we must get a lock on the opened lock file; do this with a blocking lock that times out. */ -lock_data.l_type = read_only? F_RDLCK : F_WRLCK; +lock_data.l_type = read_only ? F_RDLCK : F_WRLCK; lock_data.l_whence = lock_data.l_start = lock_data.l_len = 0; sigalrm_seen = FALSE; @@ -296,7 +301,11 @@ if (rc < 0) /* At this point we have an opened and locked separate lock file, that is, exclusive access to the database, so we can go ahead and open it. */ -snprintf(CS filename, sizeof(filename), "%s/%s", dirname, name); +#ifdef COMPILE_UTILITY +asprintf(CSS &filename, "%s/%s", dirname, name); +#else +filename = string_sprintf("%s/%s", dirname, name); +#endif EXIM_DBOPEN(filename, dirname, flags, 0, &(dbblock->dbptr)); if (!dbblock->dbptr) -- cgit v1.2.3