(/home/sate/Testcases/c/cve/dovecot-1.2.0/src/plugins/lazy-expunge/lazy-expunge-plugin.c) |
| |
| 309 | | | static int dir_move_or_merge(struct mailbox_list *list, |
| 310 | | | const char *srcdir, const char *destdir) |
| 311 | | | { |
| 312 | | | DIR *dir; |
| 313 | | | struct dirent *dp; |
| 314 | | | string_t *src_path, *dest_path; |
| 315 | | | unsigned int src_dirlen, dest_dirlen; |
| 316 | | | int ret = 0; |
| 317 | | | |
| 318 | | | if (rename(srcdir, destdir) == 0 || errno == ENOENT)
x /usr/include/asm-generic/errno-base.h |
| |
5 | #define ENOENT 2 /* No such file or directory */ |
| |
|
Event 1:
Skipping " if". - rename(srcdir, destdir) == 0 evaluates to false.
- errno == 2 evaluates to false.
hide
|
|
| 319 | | | return 0; |
| 320 | | | |
| 321 | | | if (!EDESTDIREXISTS(errno)) {
x /home/sate/Testcases/c/cve/dovecot-1.2.0/src/lib/compat.h |
| |
253 | #define EDESTDIREXISTS(errno) \ |
254 | ((errno) == EEXIST || (errno) == ENOTEMPTY || (errno) == EBUSY) |
| |
x /usr/include/asm-generic/errno.h |
| |
10 | #define ENOTEMPTY 39 /* Directory not empty */ |
| |
x /usr/include/asm-generic/errno-base.h |
| |
19 | #define EBUSY 16 /* Device or resource busy */ |
| |
|
Event 2:
Skipping " if". errno == 17 evaluates to true.
hide
|
|
| 322 | | | mailbox_list_set_critical(list, |
| 323 | | | "rename(%s, %s) failed: %m", srcdir, destdir); |
| 324 | | | } |
| 325 | | | |
| 326 | | | |
| 327 | | | dir = opendir(srcdir); |
Event 3:
srcdir is passed to opendir().
hide
Event 4:
opendir() accesses the file named srcdir. - 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 3.
hide
|
|
| 328 | | | if (dir == NULL) { |
Event 5:
Skipping " if". dir == (void *)0 evaluates to false.
hide
|
|
| 329 | | | mailbox_list_set_critical(list, |
| 330 | | | "opendir(%s) failed: %m", srcdir); |
| 331 | | | return -1; |
| 332 | | | } |
| 333 | | | |
| 334 | | | src_path = t_str_new(512); |
| 335 | | | dest_path = t_str_new(512); |
| 336 | | | |
| 337 | | | str_append(src_path, srcdir); |
| 338 | | | str_append(dest_path, destdir); |
| 339 | | | str_append_c(src_path, '/'); |
| 340 | | | str_append_c(dest_path, '/'); |
| 341 | | | src_dirlen = str_len(src_path); |
| 342 | | | dest_dirlen = str_len(dest_path); |
| 343 | | | |
| 344 | | | while ((dp = readdir(dir)) != NULL) { |
| 345 | | | if (dp->d_name[0] == '.' && |
| 346 | | | (dp->d_name[1] == '\0' || |
| 347 | | | (dp->d_name[1] == '.' && dp->d_name[2] == '\0'))) |
| 348 | | | continue; |
| 349 | | | |
| 350 | | | str_truncate(src_path, src_dirlen); |
| 351 | | | str_append(src_path, dp->d_name); |
| 352 | | | str_truncate(dest_path, dest_dirlen); |
| 353 | | | str_append(dest_path, dp->d_name); |
| 354 | | | |
| 355 | | | if (rename(str_c(src_path), str_c(dest_path)) < 0 && |
| 356 | | | errno != ENOENT) {
x /usr/include/asm-generic/errno-base.h |
| |
5 | #define ENOENT 2 /* No such file or directory */ |
| |
|
| 357 | | | mailbox_list_set_critical(list, |
| 358 | | | "rename(%s, %s) failed: %m", |
| 359 | | | str_c(src_path), str_c(dest_path)); |
| 360 | | | ret = -1; |
| 361 | | | } |
| 362 | | | } |
| 363 | | | if (closedir(dir) < 0) { |
Event 8:
Skipping " if". closedir(dir) < 0 evaluates to false.
hide
|
|
| 364 | | | mailbox_list_set_critical(list, |
| 365 | | | "closedir(%s) failed: %m", srcdir); |
| 366 | | | ret = -1; |
| 367 | | | } |
| 368 | | | if (ret == 0) { |
Event 9:
Taking true branch. ret == 0 evaluates to true.
hide
|
|
| 369 | | | if (rmdir(srcdir) < 0) { |
Event 10:
srcdir is passed to rmdir().
hide
File System Race Condition
The file named srcdir is accessed again. Another process may have changed the file since the access at lazy-expunge-plugin.c:327. 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 4 and 10. Show: All events | Only primary events |
|
| |