Text   |  XML   |  ReML   |   Visible Warnings:

File System Race Condition  at maildir-storage.c:829

No properties have been set. | edit properties
Jump to warning location ↓ warning details...
Show Events | Options

maildir_list_delete_mailbox

(/home/sate/Testcases/c/cve/dovecot-1.2.0/src/lib-storage/index/maildir/maildir-storage.c)expand/collapse
Show more  
 769  maildir_list_delete_mailbox(struct mailbox_list *list, const char *name)
 770  {
 771          struct maildir_storage *storage = MAILDIR_LIST_CONTEXT(list);
 772          struct stat st;
 773          const char *src, *dest, *base;
 774          int count;
 775   
 776          /* Make sure the indexes are closed before trying to delete the 
 777             directory that contains them. It can still fail with some NFS 
 778             implementations if indexes are opened by another session, but 
 779             that can't really be helped. */
 780          index_storage_destroy_unrefed();
 781   
 782          /* delete the index and control directories */
 783          if (storage->list_module_ctx.super.delete_mailbox(list, name) < 0)
 784                  return -1;
 785   
 786          /* check if the mailbox actually exists */
 787[+]         src = mailbox_list_get_path(list, name, MAILBOX_LIST_PATH_TYPE_MAILBOX);
 788          if (lstat(src, &st) != 0 && errno == ENOENT) {
 789                  mailbox_list_set_error(list, MAIL_ERROR_NOTFOUND,
 790                          T_MAIL_ERR_MAILBOX_NOT_FOUND(name));
 791                  return -1;
 792          }
 793   
 794          if (!S_ISDIR(st.st_mode)) {
 795                  /* a symlink most likely */
 796                  if (unlink(src) < 0 && errno != ENOENT) {
 797                          mailbox_list_set_critical(list,
 798                                  "unlink(%s) failed: %m", src);
 799                          return -1;
 800                  }
 801                  return 0;
 802          }
 803   
 804          if (strcmp(name, "INBOX") == 0) {
 805                  /* we shouldn't get this far if this is the actual INBOX.
 806                     more likely we're just deleting a namespace/INBOX.
 807                     be anyway sure that we don't accidentally delete the entire
 808                     maildir (INBOX explicitly configured to maildir root). */
 809                  base = mailbox_list_get_path(list, NULL,
 810                                               MAILBOX_LIST_PATH_TYPE_MAILBOX);
 811                  if (strcmp(base, src) == 0) {
 812                          mailbox_list_set_error(list, MAIL_ERROR_NOTPOSSIBLE,
 813                                                 "INBOX can't be deleted.");
 814                          return -1;
 815                  }
 816          }
 817   
 818[+]         dest = maildir_get_unlink_dest(list, name);
 819          if (dest == NULL) {
 820                  /* delete the directory directly without any renaming */
 821                  return maildir_delete_nonrecursive(list, src, name);
 822          }
 823   
 824          /* rename the .maildir into ..DOVECOT-TRASH which atomically
 825             marks it as being deleted. If we die before deleting the
 826             ..DOVECOT-TRASH directory, it gets deleted the next time
 827             mailbox listing sees it. */
 828          count = 0;
 829          while (rename(src, dest) < 0) {
 830                  if (errno == ENOENT) {
 831                          /* it was just deleted under us by 
 832                             another process */
 833                          mailbox_list_set_error(list, MAIL_ERROR_NOTFOUND,
 834                                  T_MAIL_ERR_MAILBOX_NOT_FOUND(name));
 835                          return -1;
 836                  }
 837                  if (!EDESTDIREXISTS(errno)) {
 838                          mailbox_list_set_critical(list,
 839                                  "rename(%s, %s) failed: %m", src, dest);
 840                          return -1;
 841                  }
 842   
 843                  /* already existed, delete it and try again */
 844                  if (unlink_directory(dest, TRUE) < 0 &&
 845                      (errno != ENOTEMPTY || count >= 5)) {
 846                          mailbox_list_set_critical(list,
 847                                  "unlink_directory(%s) failed: %m", dest);
 848                          return -1;
 849                  }
 850                  count++;
Show more  




Change Warning 7384.25725 : File System Race Condition

Priority:
State:
Finding:
Owner:
Note: