Text   |  XML   |  ReML   |   Visible Warnings:

Buffer Overrun  at mail-process.c:794

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

create_mail_process

(/home/sate/Testcases/c/cve/dovecot-1.2.0/src/master/mail-process.c)expand/collapse
Show more  
 551  create_mail_process(enum process_type process_type, struct settings *set,
 552                      const struct  *request,
 553                      const char *user, const char *const *args,
 554                      const unsigned char *data, bool dump_capability,
 555                      pid_t *pid_r)
 556  {
 557          const struct var_expand_table *var_expand_table;
 558          const char *p, *addr, *mail, *chroot_dir, *home_dir, *full_home_dir;
 559          const char *system_groups_user, *master_user;
 560          struct mail_process_group *process_group;
 561          char title[1024];
 562          struct log_io *log;
 563          string_t *str;
 564          pid_t pid;
 565          uid_t uid;
 566          gid_t gid;
 567          ARRAY_DEFINE(extra_args, const char *);
 568          unsigned int i, len, count, left, process_count, throttle;
 569          int ret, log_fd, nice_value, chdir_errno;
 570          bool home_given, nfs_check;
 571   
 572          i_assert(process_type == PROCESS_TYPE_IMAP ||
 573                   process_type == PROCESS_TYPE_POP3);
 574   
 575          if (mail_process_count == set->max_mail_processes) {
 576                  i_error("Maximum number of mail processes exceeded "
 577                          "(see max_mail_processes setting)");
 578                  return ;
 579          }
 580   
 581          t_array_init(&extra_args, 16);
 582          mail = home_dir = chroot_dir = system_groups_user = "";
 583          master_user = NULL;
 584          uid = (uid_t)-1; gid = (gid_t)-1; nice_value = 0;
 585          home_given = FALSE;
 586          for (; *args != NULL; args++) {
 587                  if (strncmp(*args, "home=", 5) == 0) {
 588                          home_dir = *args + 5;
 589                          home_given = TRUE;
 590                  } else if (strncmp(*args, "mail=", 5) == 0)
 591                          mail = *args + 5;
 592                  else if (strncmp(*args, "chroot=", 7) == 0)
 593                          chroot_dir = *args + 7;
 594                  else if (strncmp(*args, "nice=", 5) == 0)
 595                          nice_value = atoi(*args + 5);
 596                  else if (strncmp(*args, "system_groups_user=", 19) == 0)
 597
609
Show [ Lines 597 to 609 omitted. ]
 610                          master_user = arg + 12;
 611                          array_append(&extra_args, &arg, 1);
 612                  } else {
 613                          const char *arg = *args;
 614                          array_append(&extra_args, &arg, 1);
 615                  }
 616          }
 617   
 618          /* check process limit for this user, but not if this is a master 
 619             user . */
 620          process_group = dump_capability ? NULL :
 621                  mail_process_group_lookup(process_type, user,
 622                                            &request->remote_ip);
 623          process_count = process_group == NULL ? 0 :
 624                  array_count(&process_group->processes);
 625          if (process_count >= set->mail_max_userip_connections &&
 626              set->mail_max_userip_connections != 0 &&
 627              master_user == NULL)
 628                  return ;
 629   
 630          /* if uid/gid wasn't returned, use the defaults */
 631          if (uid == (uid_t)-1) {
 632                  uid = set->mail_uid_t;
 633                  if (uid == (uid_t)-1) {
 634                          i_error("User %s is missing UID (see mail_uid setting)",
 635                                  user);
 636                          return ;
 637                  }
 638          }
 639          if (gid == (gid_t)-1) {
 640                  gid = set->mail_gid_t;
 641                  if (gid == (gid_t)-1) {
 642                          i_error("User %s is missing GID (see mail_gid setting)",
 643                                  user);
 644                          return ;
 645                  }
 646          }
 647   
 648          if (*chroot_dir == '\0' && *set->valid_chroot_dirs != '\0' &&
 649              (p = strstr(home_dir, "/./")) != NULL) {
 650                  /* wu-ftpd like <chroot>/./<home> - check only if there's even 
 651                     a possibility of using them (non-empty valid_chroot_dirs)*/
 652[+]                 chroot_dir = t_strdup_until(home_dir, p);
 653                  home_dir = p + 2;
 654          } else if (*chroot_dir != '\0' && *home_dir != '/') {
 655                  /* home directories should never be relative, but force this 
 656                     with chroots. */
 657                  home_dir = t_strconcat("/", home_dir, NULL);
 658          }
 659   
 660          if (!dump_capability) {
 661[+]                 if (!validate_uid_gid(set, uid, gid, user))
 662                          return ;
 663          }
 664   
 665          if (*chroot_dir != '\0') {
 666                  if (!validate_chroot(set, chroot_dir)) {
 667                          i_error("Invalid chroot directory '%s' (user %s) "
 668                                  "(see valid_chroot_dirs setting)",
 669                                  chroot_dir, user);
 670                          return ;
 671                  }
 672          } else if (*set->mail_chroot != '\0') {
 673                  /* mail_chroot setting's value doesn't need to be in
 674                     valid_chroot_dirs. */
 675                  chroot_dir = set->mail_chroot;
 676          }
 677          if (*chroot_dir != '\0' && set->mail_drop_priv_before_exec) {
 678                  i_error("Can't chroot to directory '%s' (user %s) "
 679                          "with mail_drop_priv_before_exec=yes",
 680                          chroot_dir, user);
 681                  return ;
 682          }
 683          len = strlen(chroot_dir);
 684          if (len > 2 && strcmp(chroot_dir + len - 2, "/.") == 0 &&
 685              strncmp(home_dir, chroot_dir, len - 2) == 0) {
 686                  /* strip chroot dir from home dir */
 687                  home_dir += len - 2;
 688          }
 689   
 690          if (!dump_capability) {
 691                  throttle = set->mail_debug ? 0 :
 692                          set->mail_log_max_lines_per_sec;
 693[+]                 log_fd = log_create_pipe(&log, throttle);
 694                  if (log_fd == -1)
 695                          return ;
 696          } else {
 697                  log = NULL;
 698                  log_fd = dup(STDERR_FILENO);
 699                  if (log_fd == -1) {
 700                          i_error("dup() failed: %m");
 701                          return ;
 702                  }
 703                  fd_close_on_exec(log_fd, TRUE);
 704          }
 705   
 706          /* See if we need to do the initial NFS check. We want to do this only
 707             once, so the check code needs to be before fork(). */
 708          if (set->nfs_check && !set->mail_nfs_index && !dump_capability) {
 709                  set->nfs_check = FALSE;
 710                  nfs_check = TRUE;
 711          } else {
 712                  nfs_check = FALSE;
 713          }
 714   
 715          pid = fork();
 716          if (pid < 0) {
 717                  i_error("fork() failed: %m");
 718                  (void)close(log_fd);
 719                  return ;
 720          }
 721   
 722          var_expand_table =
 723                  get_var_expand_table(process_names[process_type],
 724                                       user, home_given ? home_dir : NULL,
 725                                       net_ip2addr(&request->local_ip),
 726                                       net_ip2addr(&request->remote_ip),
 727                                       pid != 0 ? pid : getpid(), uid);
 728          str = t_str_new(128);
 729   
 730          if (pid != 0) {
 731                  /* master */
 732                  var_expand(str, set->mail_log_prefix, var_expand_table);
 733   
 734                  if (!dump_capability) {
 735                          log_set_prefix(log, str_c(str));
 736                          log_set_pid(log, pid);
 737                          if (process_group == NULL) {
 738                                  process_group = mail_process_group_create(
 739                                                          process_type, user,
 740                                                          &request->remote_ip);
 741                          }
 742                          mail_process_group_add(process_group, pid);
 743                  }
 744                  (void)close(log_fd);
 745                  *pid_r = pid;
 746                  return ;
 747          }
 748   
 749  #ifdef HAVE_SETPRIORITY 
 750          if (nice_value != 0) {
 751                  if (setpriority(PRIO_PROCESS, 0, nice_value) < 0)
 752                          i_error("setpriority(%d) failed: %m", nice_value);
 753          }
 754  #endif
 755   
 756          if (!dump_capability) {
 757                  str_append(str, "master-");
 758                  var_expand(str, set->mail_log_prefix, var_expand_table);
 759                  log_set_prefix(log, str_c(str));
 760          }
 761   
 762          child_process_init_env();
 763   
 764          /* setup environment - set the most important environment first
 765             (paranoia about filling up environment without noticing) */
 766          restrict_access_set_env(system_groups_user, uid, gid,
 767                                  set->mail_priv_gid_t,
 768                                  dump_capability ? "" : chroot_dir,
 769                                  set->first_valid_gid, set->last_valid_gid,
 770                                  set->mail_access_groups);
 771   
 772          restrict_process_size(set->mail_process_size, (unsigned int)-1);
 773   
 774          if (dump_capability)
 775                  env_put("DUMP_CAPABILITY=1");
 776   
 777          if ((*home_dir == '\0' && *chroot_dir == '\0') || dump_capability) {
 778                  full_home_dir = "";
 779                  ret = -1;
 780          } else {
 781                  full_home_dir = *chroot_dir == '\0' ? home_dir :
 782                          t_strconcat(chroot_dir, home_dir, NULL);
 783                  /* NOTE: if home directory is NFS-mounted, we might not 
 784                     have access to it as root. Change the effective UID and GID
 785                     temporarily to make it work. */
 786                  if (uid != master_uid) {
 787                          if (setegid(gid) < 0)
 788                                  i_fatal("setegid(%s) failed: %m", dec2str(gid));
 789                          if (seteuid(uid) < 0)
 790                                  i_fatal("seteuid(%s) failed: %m", dec2str(uid));
 791                  }
 792   
 793                  alarm(CHDIR_TIMEOUT);
 794                  ret = chdir(full_home_dir);
Show more  




Change Warning 7743.25030 : Buffer Overrun

Priority:
State:
Finding:
Owner:
Note: