From f376ad9c6fb65bef0106c2631299c989b3df9f57 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Galarneau?= Date: Tue, 8 Oct 2019 14:18:31 -0400 Subject: [PATCH] Fix: sessiond: TOCTOU error on save of session configuration MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit The session_save() function checks for the existance and access rights on the target session configuration filename before opening it. This results in a TOCTOU (Time of check, time of use) problem. Defer the check and error reporting to the run_as_open() call. 1191754 Time of check time of use An attacker could change the filename's file association or other attributes between the check and use. In save_session: A check occurs on a file's attributes before the file is used in a privileged operation, but things may have changed (CWE-367) Reported-by: Coverity Scan Signed-off-by: Jérémie Galarneau --- src/bin/lttng-sessiond/save.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/bin/lttng-sessiond/save.c b/src/bin/lttng-sessiond/save.c index 3c4c3b2bc..cdeb4004d 100644 --- a/src/bin/lttng-sessiond/save.c +++ b/src/bin/lttng-sessiond/save.c @@ -2290,6 +2290,7 @@ int save_session(struct ltt_session *session, struct config_writer *writer = NULL; size_t session_name_len; const char *provided_path; + int file_open_flags = O_CREAT | O_WRONLY | O_TRUNC; assert(session); assert(attr); @@ -2363,18 +2364,26 @@ int save_session(struct ltt_session *session, len += sizeof(DEFAULT_SESSION_CONFIG_FILE_EXTENSION); config_file_path[len] = '\0'; - if (!access(config_file_path, F_OK) && !attr->overwrite) { - /* File exists, notify the user since the overwrite flag is off. */ - ret = LTTNG_ERR_SAVE_FILE_EXIST; - goto end; + if (!attr->overwrite) { + file_open_flags |= O_EXCL; } - fd = run_as_open(config_file_path, O_CREAT | O_WRONLY | O_TRUNC, + fd = run_as_open(config_file_path, file_open_flags, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP, LTTNG_SOCK_GET_UID_CRED(creds), LTTNG_SOCK_GET_GID_CRED(creds)); if (fd < 0) { PERROR("Could not create configuration file"); - ret = LTTNG_ERR_SAVE_IO_FAIL; + switch (errno) { + case EEXIST: + ret = LTTNG_ERR_SAVE_FILE_EXIST; + break; + case EACCES: + ret = LTTNG_ERR_EPERM; + break; + default: + ret = LTTNG_ERR_SAVE_IO_FAIL; + break; + } goto end; } -- 2.34.1