(/home/sate/Testcases/c/cve/dovecot-1.2.0/src/lib/safe-mkdir.c) |
| |
| 10 | | | int safe_mkdir(const char *dir, mode_t mode, uid_t uid, gid_t gid) |
| 11 | | | { |
| 12 | | | struct stat st; |
| 13 | | | int fd, ret = 2, changed_ret = 0; |
| 14 | | | |
| 15 | | | if (lstat(dir, &st) < 0) { |
Event 1:
dir is passed to lstat64() as the first argument.
hide
Event 2:
lstat64() accesses the file named dir. - The same name is used to access a file later, but it is not safe to assume that it will be the same underlying file.
See related event 1.
hide
Event 3:
Skipping " if". lstat(dir, &st) < 0 evaluates to false.
hide
|
|
| 16 | | | if (errno != ENOENT)
x /usr/include/asm-generic/errno-base.h |
| |
5 | #define ENOENT 2 /* No such file or directory */ |
| |
|
| 17 | | | i_fatal("lstat() failed for %s: %m", dir); |
| 18 | | | |
| 19 | | | if (mkdir(dir, mode) < 0) { |
| 20 | | | if (errno != EEXIST) |
| 21 | | | i_fatal("Can't create directory %s: %m", dir); |
| 22 | | | } else { |
| 23 | | | |
| 24 | | | ret = changed_ret = 1; |
| 25 | | | } |
| 26 | | | } |
| 27 | | | |
| 28 | | | |
| 29 | | | |
| 30 | | | fd = open(dir, O_RDONLY); |
| 31 | | | if (fd == -1) |
Event 5:
Skipping " if". fd == -1 evaluates to false.
hide
|
|
| 32 | | | i_fatal("open() failed for %s: %m", dir); |
| 33 | | | |
| 34 | | | if (fstat(fd, &st) < 0) |
Event 6:
Skipping " if". fstat(fd, &st) < 0 evaluates to false.
hide
|
|
| 35 | | | i_fatal("fstat() failed for %s: %m", dir); |
| 36 | | | |
| 37 | | | if (!S_ISDIR(st.st_mode) || S_ISLNK(st.st_mode))
x /usr/include/sys/stat.h |
| |
131 | #define S_ISDIR(mode) __S_ISTYPE((mode), __S_IFDIR) |
| |
x /usr/include/sys/stat.h |
| |
129 | #define __S_ISTYPE(mode, mask) (((mode) & __S_IFMT) == (mask)) |
| |
x /usr/include/bits/stat.h |
| |
182 | #define __S_IFMT 0170000 /* These bits determine file type. */ |
| |
x /usr/include/bits/stat.h |
| |
185 | #define __S_IFDIR 0040000 /* Directory. */ |
| |
x /usr/include/sys/stat.h |
| |
139 | # define S_ISLNK(mode) __S_ISTYPE((mode), __S_IFLNK) |
| |
x /usr/include/sys/stat.h |
| |
129 | #define __S_ISTYPE(mode, mask) (((mode) & __S_IFMT) == (mask)) |
| |
x /usr/include/bits/stat.h |
| |
182 | #define __S_IFMT 0170000 /* These bits determine file type. */ |
| |
x /usr/include/bits/stat.h |
| |
190 | #define __S_IFLNK 0120000 /* Symbolic link. */ |
| |
|
Event 7:
Skipping " if". - (st.st_mode & 61440) == 16384 evaluates to true.
- (st.st_mode & 61440) == 40960 evaluates to false.
hide
|
|
| 38 | | | i_fatal("Not a directory %s", dir); |
| 39 | | | |
| 40 | | | |
| 41 | | | |
| 42 | | | if (st.st_uid != uid || st.st_gid != gid) { |
Event 8:
Taking true branch. st.st_uid != uid evaluates to true.
hide
|
|
| 43 | | | if (fchown(fd, uid, gid) < 0) |
Event 9:
Skipping " if". fchown(fd, uid, gid) < 0 evaluates to false.
hide
|
|
| 44 | | | i_fatal("fchown() failed for %s: %m", dir); |
| 45 | | | ret = changed_ret; |
| 46 | | | } |
| 47 | | | |
| 48 | | | if ((st.st_mode & 07777) != mode) { |
Event 10:
Skipping " if". (st.st_mode & 4095) != mode evaluates to false.
hide
|
|
| 49 | | | if (fchmod(fd, mode) < 0) |
| 50 | | | i_fatal("chmod() failed for %s: %m", dir); |
| 51 | | | ret = changed_ret; |
| 52 | | | } |
| 53 | | | |
| 54 | | | if (close(fd) < 0) |
Event 11:
Skipping " if". close(fd) < 0 evaluates to false.
hide
|
|
| 55 | | | i_fatal("close() failed for %s: %m", dir); |
| 56 | | | |
| 57 | | | |
| 58 | | | if (lstat(dir, &st) < 0) |
Event 12:
dir is passed to lstat64() as the first argument.
hide
File System Race Condition
The file named dir is accessed again. Another process may have changed the file since the access at safe-mkdir.c:15. For example, an attacker could replace the original file with a link to a file containing important or confidential data. The issue can occur if the highlighted code executes. See related events 2 and 12. Show: All events | Only primary events |
|
| |