(/home/sate/Testcases/c/cve/dovecot-1.2.0/src/lib-storage/index/maildir/maildir-storage.c) |
| |
| 685 | | | maildir_delete_nonrecursive(struct mailbox_list *list, const char *path, |
| 686 | | | const char *name) |
| 687 | | | { |
| 688 | | | DIR *dir; |
| 689 | | | struct dirent *d; |
| 690 | | | string_t *full_path; |
| 691 | | | unsigned int dir_len; |
| 692 | | | bool unlinked_something = FALSE; |
| 693 | | | |
| 694 | | | dir = opendir(path); |
Event 1:
path is passed to opendir().
hide
Event 2:
opendir() accesses the file named path. - 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
|
|
| 695 | | | if (dir == NULL) { |
Event 3:
Skipping " if". dir == (void *)0 evaluates to false.
hide
|
|
| 696 | | | if (errno == ENOENT) {
x /usr/include/asm-generic/errno-base.h |
| |
5 | #define ENOENT 2 /* No such file or directory */ |
| |
|
| 697 | | | mailbox_list_set_error(list, MAIL_ERROR_NOTFOUND, |
| 698 | | | T_MAIL_ERR_MAILBOX_NOT_FOUND(name));
x /home/sate/Testcases/c/cve/dovecot-1.2.0/src/lib-storage/mail-error.h |
| |
19 | #define T_MAIL_ERR_MAILBOX_NOT_FOUND(name) \ |
20 | t_strdup_printf(MAIL_ERRSTR_MAILBOX_NOT_FOUND, name) |
| |
|
| 699 | | | } else { |
| 700 | | | mailbox_list_set_critical(list, |
| 701 | | | "opendir(%s) failed: %m", path); |
| 702 | | | } |
| 703 | | | return -1; |
| 704 | | | } |
| 705 | | | |
| 706 | | | full_path = t_str_new(256); |
| 707 | | | str_append(full_path, path); |
| 708 | | | str_append_c(full_path, '/'); |
| 709 | | | dir_len = str_len(full_path); |
| 710 | | | |
| 711 | | | errno = 0; |
| 712 | | | while ((d = readdir(dir)) != NULL) { |
| 713 | | | if (d->d_name[0] == '.') { |
| 714 | | | |
| 715 | | | if (d->d_name[1] == '\0') |
| 716 | | | continue; |
| 717 | | | if (d->d_name[1] == '.' && d->d_name[2] == '\0') |
| 718 | | | continue; |
| 719 | | | } |
| 720 | | | |
| 721 | | | str_truncate(full_path, dir_len); |
| 722 | | | str_append(full_path, d->d_name); |
| 723 | | | |
| 724 | | | if (maildir_is_internal_name(d->d_name)) { |
| 725 | | | if (unlink_directory(str_c(full_path), TRUE) < 0) { |
| 726 | | | mailbox_list_set_critical(list, |
| 727 | | | "unlink_directory(%s) failed: %m", |
| 728 | | | str_c(full_path)); |
| 729 | | | } else { |
| 730 | | | unlinked_something = TRUE; |
| 731 | | | } |
| 732 | | | continue; |
| 733 | | | } |
| 734 | | | |
| 735 | | | |
| 736 | | | |
| 737 | | | |
| 738 | | | if (unlink(str_c(full_path)) == 0) |
| 739 | | | unlinked_something = TRUE; |
| 740 | | | else if (errno != ENOENT && errno != EISDIR && errno != EPERM) {
x /usr/include/asm-generic/errno-base.h |
| |
5 | #define ENOENT 2 /* No such file or directory */ |
| |
x /usr/include/asm-generic/errno-base.h |
| |
24 | #define EISDIR 21 /* Is a directory */ |
| |
x /usr/include/asm-generic/errno-base.h |
| |
4 | #define EPERM 1 /* Operation not permitted */ |
| |
|
| 741 | | | mailbox_list_set_critical(list, |
| 742 | | | "unlink_directory(%s) failed: %m", |
| 743 | | | str_c(full_path)); |
| 744 | | | } |
| 745 | | | } |
| 746 | | | |
| 747 | | | if (closedir(dir) < 0) { |
Event 6:
Skipping " if". closedir(dir) < 0 evaluates to false.
hide
|
|
| 748 | | | mailbox_list_set_critical(list, "closedir(%s) failed: %m", |
| 749 | | | path); |
| 750 | | | } |
| 751 | | | |
| 752 | | | if (rmdir(path) == 0) |
Event 7:
path is passed to rmdir().
hide
File System Race Condition
The file named path is accessed again. Another process may have changed the file since the access at maildir-storage.c:694. 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 7. Show: All events | Only primary events |
|
| |