(/home/sate/Testcases/c/cve/dovecot-1.2.0/src/plugins/lazy-expunge/lazy-expunge-plugin.c) |
| |
| 379 | | | mailbox_move(struct mailbox_list *src_list, const char *src_name, |
| 380 | | | struct mailbox_list *dest_list, const char **_dest_name) |
| 381 | | | { |
| 382 | | | const char *dest_name = *_dest_name; |
| 383 | | | const char *srcdir, *src2dir, *src3dir, *destdir, *p, *destparent; |
| 384 | | | const char *origin; |
| 385 | | | struct stat st; |
| 386 | | | mode_t mode; |
| 387 | | | gid_t gid; |
| 388 | | | |
| 389 | | | srcdir = mailbox_list_get_path(src_list, src_name, |
Event 2:
srcdir is set to mailbox_list_get_path(...), which evaluates to list->v.get_path(...) from mailbox-list.c:446. See related event 1.
hide
|
|
| 390 | [+] | | MAILBOX_LIST_PATH_TYPE_MAILBOX); |
 |
| 391 | | | destdir = mailbox_list_get_path(dest_list, dest_name, |
| 392 | | | MAILBOX_LIST_PATH_TYPE_MAILBOX); |
| 393 | | | while (rename(srcdir, destdir) < 0) { |
Event 4:
During loop iterations, the file named srcdir is accessed, where srcdir is list->v.get_path(...) from mailbox-list.c:446. - 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 2.
hide
Event 5:
srcdir, which evaluates to list->v.get_path(...) from mailbox-list.c:446, is passed to rename() as the first argument. See related event 2.
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:393. 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 5. Show: All events | Only primary events |
|
| 394 | | | if (errno == ENOENT) {
x /usr/include/asm-generic/errno-base.h |
| |
5 | #define ENOENT 2 /* No such file or directory */ |
| |
|
| 395 | | | |
| 396 | | | |
| 397 | | | p = strrchr(destdir, '/'); |
| 398 | | | if (p == NULL) |
| 399 | | | return 0; |
| 400 | | | destparent = t_strdup_until(destdir, p); |
| 401 | | | if (stat(destparent, &st) == 0) |
| 402 | | | return 0; |
| 403 | | | |
| 404 | | | mailbox_list_get_dir_permissions(dest_list, NULL, |
| 405 | | | &mode, &gid, &origin); |
| 406 | | | if (mkdir_parents_chgrp(destparent, mode, |
| 407 | | | gid, origin) < 0) { |
| 408 | | | if (errno == EEXIST) { |
| 409 | | | |
| 410 | | | continue; |
| 411 | | | } |
| 412 | | | mailbox_list_set_critical(src_list, |
| 413 | | | "mkdir(%s) failed: %m", destparent); |
| 414 | | | return -1; |
| 415 | | | } |
| 416 | | | |
| 417 | | | continue; |
| 418 | | | } |
| 419 | | | |
| 420 | | | 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 */ |
| |
|
| 421 | | | mailbox_list_set_critical(src_list, |
| 422 | | | "rename(%s, %s) failed: %m", srcdir, destdir); |
| 423 | | | return -1; |
| 424 | | | } |
| 425 | | | |
| 426 | | | |
| 427 | | | |
| 428 | | | dest_name = t_strdup_printf("%s-%04u", *_dest_name, |
| 429 | | | (uint32_t)random()); |
| 430 | | | destdir = mailbox_list_get_path(dest_list, dest_name, |
| 431 | | | MAILBOX_LIST_PATH_TYPE_MAILBOX); |
| |