@@ -24,6 +24,8 @@
#include <math.h>
#include <stdarg.h>
#include <syslog.h>
+#include <fcntl.h>
+#include <errno.h>
#include "tmon.h"
@@ -132,35 +134,53 @@ static void prepare_logging(void)
{
int i;
struct stat logstat;
+ int dir_fd = -1;
+ int log_fd = -1;
+ tmon_log = NULL;
if (!logging)
return;
- /* open local data log file */
- tmon_log = fopen(TMON_LOG_FILE, "w+");
- if (!tmon_log) {
- syslog(LOG_ERR, "failed to open log file %s\n", TMON_LOG_FILE);
+
+ /* get a file descriptor for the log directory */
+ dir_fd = open(TMON_LOG_DIR, O_RDONLY | O_DIRECTORY | O_CLOEXEC);
+ if (dir_fd < 0) {
+ syslog(LOG_ERR, "Failed to open log directory %s: %s\n",
+ TMON_LOG_DIR, strerror(errno));
return;
}
- if (lstat(TMON_LOG_FILE, &logstat) < 0) {
- syslog(LOG_ERR, "Unable to stat log file %s\n", TMON_LOG_FILE);
- fclose(tmon_log);
- tmon_log = NULL;
+ /* open local data log file securely using openat() */
+ log_fd = openat(dir_fd, TMON_LOG_FILENAME,
+ O_RDWR | O_CREAT | O_TRUNC | O_NOFOLLOW | O_CLOEXEC,
+ 0600);
+ close(dir_fd);
+
+ if (log_fd < 0) {
+ syslog(LOG_ERR, "Failed to open log file %s/%s: %s\n",
+ TMON_LOG_DIR, TMON_LOG_FILENAME, strerror(errno));
return;
}
- /* The log file must be a regular file owned by us */
- if (S_ISLNK(logstat.st_mode)) {
- syslog(LOG_ERR, "Log file is a symlink. Will not log\n");
- fclose(tmon_log);
- tmon_log = NULL;
+ if (fstat(log_fd, &logstat) < 0) {
+ syslog(LOG_ERR, "Unable to stat log file %s/%s\n",
+ TMON_LOG_DIR, TMON_LOG_FILENAME);
+ close(log_fd);
return;
}
+ /* The log file must be owned by us */
if (logstat.st_uid != getuid()) {
syslog(LOG_ERR, "We don't own the log file. Not logging\n");
- fclose(tmon_log);
- tmon_log = NULL;
+ close(log_fd);
+ return;
+ }
+
+ /* All checks passed. Convert the file descriptor to a FILE stream. */
+ tmon_log = fdopen(log_fd, "w+");
+ if (!tmon_log) {
+ syslog(LOG_ERR, "Failed to fdopen log file descriptor for %s/%s: %s\n",
+ TMON_LOG_DIR, TMON_LOG_FILENAME, strerror(errno));
+ close(log_fd);
return;
}
@@ -25,7 +25,8 @@
*/
#define DATA_LEFT_ALIGN 10
#define NR_LINES_TZDATA 1
-#define TMON_LOG_FILE "/var/tmp/tmon.log"
+#define TMON_LOG_DIR "/var/tmp"
+#define TMON_LOG_FILENAME "tmon.log"
#include <sys/time.h>
#include <pthread.h>