Package: rinetd Version: 0.62-5.1 Severity: important Tags: upstream patch First, the function readConfiguration will be called at program start up; it reads config file and identify what line is a forwarding rule, and count with a global var 'seTotal'; then process the rule, including get a socket fd for it, and store to a array 'seFds'; if any step fails, this fd will be set to -1 and program will trying to process next rule. Next, the program is finished the readConfiguration and handling thus socket fds; if this program received a SIGHUP signal, it will calling readConfiguration again to reload configuration; and it will need to clean up socket fds and allocated memories last time; a loop for clean fds loops 'seTotal' times to close fd and freeing buffer if that fd is not -1 (will not to free a pointer with the index for a invalid socket fd). The problem is a in invalid fd doesn't always have a -1 value, bucause the rules processing loop doesn't count index if an error occurred. For example if 2 rules fails, only 1 field in the 'seFds' will be set to -1 ; when the program is trying to reload config, wrong pointer will be freed.
I wrote a patch and attached to this mail. -- System Information: Debian Release: 8.2 APT prefers stable-updates APT policy: (500, 'stable-updates'), (500, 'stable') Architecture: amd64 (x86_64) Kernel: Linux 2.6.32-042stab108.8 (SMP w/2 CPU cores) Locale: LANG=zh_CN.UTF-8, LC_CTYPE=zh_CN.UTF-8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/dash Init: systemd (via /run/systemd/system) Versions of packages rinetd depends on: ii libc6 2.19-18+deb8u1 rinetd recommends no packages. rinetd suggests no packages. -- Configuration Files: /etc/rinetd.conf changed [not included] -- no debconf information
rinetd-0.62/debian 和 rinetd-0.62-bugfix/debian 有共同的子目录 diff -c rinetd-0.62/rinetd.c rinetd-0.62-bugfix/rinetd.c *** rinetd-0.62/rinetd.c 2015-12-02 12:19:09.000000000 -0500 --- rinetd-0.62-bugfix/rinetd.c 2015-12-02 12:18:52.674934894 -0500 *************** *** 458,464 **** goto lowMemory; } /* 2. Make a second pass to configure them. */ ! i = 0; ai = 0; di = 0; lnum = 0; --- 458,464 ---- goto lowMemory; } /* 2. Make a second pass to configure them. */ ! i = -1; ai = 0; di = 0; lnum = 0; *************** *** 466,475 **** if (!in) { goto lowMemory; } - if (seTotal > 0) { - seAllowRulesTotal[i] = 0; - seDenyRulesTotal[i] = 0; - } while (1) { char *bindAddress; unsigned short bindPort; --- 466,471 ---- *************** *** 570,575 **** --- 566,576 ---- logFormatCommon = 1; } else { /* A regular forwarding rule. */ + i++; + if (i < seTotal) { + seAllowRulesTotal[i] = 0; + seDenyRulesTotal[i] = 0; + } bindPortS = strtok(0, " \t\r\n"); if (!bindPortS) { syslog(LOG_ERR, "no bind port " *************** *** 680,690 **** } strcpy(seToHosts[i], connectAddress); seToPorts[i] = connectPort; - i++; - if (i < seTotal) { - seAllowRulesTotal[i] = 0; - seDenyRulesTotal[i] = 0; - } } } fclose(in); --- 681,686 ----