diff -ru asterisk-16.9.0-rc1/main/app.c asterisk-16.9.0-rc1_mod/main/app.c --- asterisk-16.9.0-rc1/main/app.c 2020-03-05 18:39:25.000000000 +0100 +++ asterisk-16.9.0-rc1_mod/main/app.c 2020-03-11 11:17:15.776918843 +0100 @@ -81,6 +81,9 @@ static AST_LIST_HEAD_STATIC(zombies, zombie); +#ifdef HAVE_CAP +static cap_t child_cap; +#endif /* * @{ \brief Define \ref stasis topic objects */ @@ -3003,12 +3006,7 @@ } else { /* Child */ #ifdef HAVE_CAP - cap_t cap = cap_from_text("cap_net_admin-eip"); - - if (cap_set_proc(cap)) { - ast_log(LOG_WARNING, "Unable to remove capabilities.\n"); - } - cap_free(cap); + cap_set_proc(child_cap); #endif /* Before we unblock our signals, return our trapped signals back to the defaults */ @@ -3118,6 +3116,9 @@ static void app_cleanup(void) { +#ifdef HAS_CAP + cap_free(child_cap); +#endif ao2_cleanup(queue_topic_pool); queue_topic_pool = NULL; ao2_cleanup(queue_topic_all); @@ -3127,7 +3128,9 @@ int app_init(void) { ast_register_cleanup(app_cleanup); - +#ifdef HAVE_CAP + child_cap = cap_from_text("cap_net_admin-eip"); +#endif queue_topic_all = stasis_topic_create("queue:all"); if (!queue_topic_all) { return -1; diff -ru asterisk-16.9.0-rc1/main/asterisk.c asterisk-16.9.0-rc1_mod/main/asterisk.c --- asterisk-16.9.0-rc1/main/asterisk.c 2020-03-05 18:39:25.000000000 +0100 +++ asterisk-16.9.0-rc1_mod/main/asterisk.c 2020-03-11 11:17:42.720844589 +0100 @@ -385,6 +385,10 @@ static char randompool[256]; +#ifdef HAVE_CAP +static cap_t child_cap; +#endif + static int sig_alert_pipe[2] = { -1, -1 }; static struct { unsigned int need_reload:1; @@ -1096,13 +1100,7 @@ if (pid == 0) { #ifdef HAVE_CAP - cap_t cap = cap_from_text("cap_net_admin-eip"); - - if (cap_set_proc(cap)) { - /* Careful with order! Logging cannot happen after we close FDs */ - ast_log(LOG_WARNING, "Unable to remove capabilities.\n"); - } - cap_free(cap); + cap_set_proc(child_cap); #endif #ifdef HAVE_WORKING_FORK if (ast_opt_high_priority) { @@ -1801,10 +1799,8 @@ if (pri) { sched.sched_priority = 10; if (sched_setscheduler(0, SCHED_RR, &sched)) { - ast_log(LOG_WARNING, "Unable to set high priority\n"); return -1; - } else - ast_verb(1, "Set to realtime thread\n"); + } } else { sched.sched_priority = 0; /* According to the manpage, these parameters can never fail. */ @@ -3917,8 +3913,14 @@ exit(1); } +#ifdef HAVE_CAP + child_cap = cap_from_text("cap_net_admin-eip"); +#endif /* Not a remote console? Start the daemon. */ asterisk_daemon(isroot, runuser, rungroup); +#ifdef HAS_CAP + cap_free(child_cap); +#endif return 0; } diff -ru asterisk-16.9.0-rc1/main/strcompat.c asterisk-16.9.0-rc1_mod/main/strcompat.c --- asterisk-16.9.0-rc1/main/strcompat.c 2020-03-05 18:39:25.000000000 +0100 +++ asterisk-16.9.0-rc1_mod/main/strcompat.c 2020-03-11 10:52:42.480969244 +0100 @@ -38,6 +38,8 @@ #include "asterisk/utils.h" +#define POLL_SIZE 1024 + #ifndef HAVE_STRSEP char *strsep(char **str, const char *delims) { @@ -426,59 +428,42 @@ #ifndef HAVE_CLOSEFROM void closefrom(int n) { - long x; - struct rlimit rl; - DIR *dir; - char path[16], *result; - struct dirent *entry; - - snprintf(path, sizeof(path), "/proc/%d/fd", (int) getpid()); - if ((dir = opendir(path))) { - while ((entry = readdir(dir))) { - /* Skip . and .. */ - if (entry->d_name[0] == '.') { + int maxfd = sysconf (_SC_OPEN_MAX); + if (maxfd == -1) + maxfd = 1024; + if (maxfd > 65536) + maxfd = 65536; + struct pollfd fds[POLL_SIZE]; + int fd=n, loopmax, i; + while (fdPOLL_SIZE) { + loopmax = POLL_SIZE; + } + for (i=0;id_name, &result, 10)) && x >= n) { #ifdef STRICT_COMPAT - close(x); + close(fds[i].fd); #else - /* This isn't strictly compatible, but it's actually faster - * for our purposes to set the CLOEXEC flag than to close - * file descriptors. - */ - long flags = fcntl(x, F_GETFD); - if (flags == -1 && errno == EBADF) { - continue; - } - fcntl(x, F_SETFD, flags | FD_CLOEXEC); -#endif - } - } - closedir(dir); - } else { - getrlimit(RLIMIT_NOFILE, &rl); - if (rl.rlim_cur > 65535) { - /* A more reasonable value. Consider that the primary source of - * file descriptors in Asterisk are UDP sockets, of which we are - * limited to 65,535 per address. We additionally limit that down - * to about 10,000 sockets per protocol. While the kernel will - * allow us to set the fileno limit higher (up to 4.2 billion), - * there really is no practical reason for it to be that high. + /* This isn't strictly compatible, but it's actually faster + * for our purposes to set the CLOEXEC flag than to close + * file descriptors. */ - rl.rlim_cur = 65535; - } - for (x = n; x < rl.rlim_cur; x++) { -#ifdef STRICT_COMPAT - close(x); -#else - long flags = fcntl(x, F_GETFD); + long flags = fcntl(fds[i].fd, F_GETFD); if (flags == -1 && errno == EBADF) { continue; } - fcntl(x, F_SETFD, flags | FD_CLOEXEC); + fcntl(fds[i].fd, F_SETFD, flags | FD_CLOEXEC); #endif } + fd+=loopmax; } } #endif