logrotate/do_mkdir-fix-time-of-check-time-of-use-race-conditio.patch
2019-09-30 11:02:46 -04:00

88 lines
2.6 KiB
Diff

From 22892fb94b7da0018802363637928d21b7f00687 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Mon, 30 Apr 2018 18:46:13 +0200
Subject: [PATCH 14/39] do_mkdir: fix time-of-check/time-of-use race condition
reason: fix time-of-check/time-of-use race condition
https://github.com/logrotate/logrotate/pull/196
... detected by Coverity Analysis
Error: TOCTOU:
config.c:362: fs_check_call: Calling function "stat" to perform check on "path".
config.c:363: toctou: Calling function "mkdir" that uses "path" after a check function. This can cause a time-of-check, time-of-use race condition.
Closes #196
---
config.c | 49 ++++++++++++++++++++++++++-----------------------
1 file changed, 26 insertions(+), 23 deletions(-)
diff --git a/config.c b/config.c
index 9cc66ac..4162cca 100644
--- a/config.c
+++ b/config.c
@@ -357,33 +357,36 @@ static char *readAddress(const char *configFile, int lineNum, const char *key,
}
static int do_mkdir(const char *path, mode_t mode, uid_t uid, gid_t gid) {
- struct stat sb;
-
- if (stat(path, &sb) != 0) {
- if (mkdir(path, mode) != 0 && errno != EEXIST) {
- message(MESS_ERROR, "error creating %s: %s\n",
- path, strerror(errno));
- return -1;
- }
- if (chown(path, uid, gid) != 0) {
- message(MESS_ERROR, "error setting owner of %s to uid %d and gid %d: %s\n",
- path, uid, gid, strerror(errno));
- return -1;
- }
- if (chmod(path, mode) != 0) {
- message(MESS_ERROR, "error setting permissions of %s to 0%o: %s\n",
- path, mode, strerror(errno));
- return -1;
- }
+ if (mkdir(path, mode) == 0) {
+ /* newly created directory, set the owner and permissions */
+ if (chown(path, uid, gid) != 0) {
+ message(MESS_ERROR, "error setting owner of %s to uid %d and gid %d: %s\n",
+ path, uid, gid, strerror(errno));
+ return -1;
}
- else if (!S_ISDIR(sb.st_mode)) {
- message(MESS_ERROR, "path %s already exists, but it is not a directory\n",
- path);
- errno = ENOTDIR;
- return -1;
+
+ if (chmod(path, mode) != 0) {
+ message(MESS_ERROR, "error setting permissions of %s to 0%o: %s\n",
+ path, mode, strerror(errno));
+ return -1;
}
return 0;
+ }
+
+ if (errno == EEXIST) {
+ /* path already exists, check whether it is a directory or not */
+ struct stat sb;
+ if ((stat(path, &sb) == 0) && S_ISDIR(sb.st_mode))
+ return 0;
+
+ message(MESS_ERROR, "path %s already exists, but it is not a directory\n", path);
+ errno = ENOTDIR;
+ return -1;
+ }
+
+ message(MESS_ERROR, "error creating %s: %s\n", path, strerror(errno));
+ return -1;
}
static int mkpath(const char *path, mode_t mode, uid_t uid, gid_t gid) {
--
1.8.3.1