Package: bind9 Version: 1:9.7.1.dfsg.P2-2 Priority: normal Tags: patch
Currently, bind9 does not try to take any precaution when handling 'include' statements in the config files. It will happily accept even an include statement in a file pointing to itself which is, obviously, something that leads nowhere. For example, see attached named.conf.local, which bind9 tries to chew even if it doesn't make sense. Fortunately, 9.7.1 (unlike 9.6) will end up dying due to it trying to open too many files, however, in the meantime, it chews up all the available memory in the system and the message that it outputs does not indicate where the error is. For reference, see attached 'too-many-open-files.log' based on using the above named.conf.local in a stock Debian bind9 package. It would be better if bind9 checked this limit while parsing the configuration files, in order to detect the issue and report it properly. I have developed a patch (attached as file 'bind9-9.7.1.dfsg.P2-parselimit.diff') that tries to handle this issue. It could be even improved to detect the obvious errors of including a file within the same file (which leads to bind recursively trying to open the same file). With the above patch the error produced by bind9 is much more clarifying and, due to early detection, the bind9 server does not get to chew up all the memory before it dies due to openining up too many descriptors. For reference see the attached log 'limit-recursive-include.log' I'm flagging this bug as normal since, in this version, bind9 does actually manage to get hold of himself. Unfortunately, in the lenny version (1:9.6.ESV.R1+dfsg-0+lenny2) the same configuration leads to the named process eating up all the available memory until either a) it grinds the server to a halt or b) the kernel kills it through its out of memory killer. And, yes, I found this the hard way in a lenny server in which a misconfiguration brought the server to a halt by consuming all of its available memory. I would appreciate if you would consider this patch for bind9 and forward it upstream for their consideration. Regards Javier PS: All logs have been generated running 'named -u bind -g'
// // Do any local configuration here // // Consider adding the 1918 zones here, if they are not used in your // organization //include "/etc/bind/zones.rfc1918"; include "/etc/bind/named.conf.local";
28-Sep-2010 20:51:51.919 starting BIND 9.7.1-P2 -u bind -g 28-Sep-2010 20:51:51.919 built with '--prefix=/usr' '--mandir=/usr/share/man' '--infodir=/usr/share/info' '--sysconfdir=/etc/bind' '--localstatedir=/var' '--enable-threads' '--enable-largefile' '--with-libtool' '--enable-shared' '--enable-static' '--with-openssl=/usr' '--with-gssapi=/usr' '--with-gnu-ld' '--with-dlz-postgres=no' '--with-dlz-mysql=no' '--with-dlz-bdb=yes' '--with-dlz-filesystem=yes' '--with-dlz-ldap=yes' '--with-dlz-stub=yes' '--with-geoip=/usr' '--enable-ipv6' 'CFLAGS=-fno-strict-aliasing -DDIG_SIGCHASE -O2' 'LDFLAGS=' 'CPPFLAGS=' 28-Sep-2010 20:51:51.919 adjusted limit on open files from 1024 to 1048576 28-Sep-2010 20:51:51.919 found 2 CPUs, using 2 worker threads 28-Sep-2010 20:51:51.920 using up to 4096 sockets 28-Sep-2010 20:51:51.925 loading configuration from '/etc/bind/named.conf' 28-Sep-2010 20:51:54.933 /etc/bind/named.conf.local:10: open: /etc/bind/named.conf.local: too many open files 28-Sep-2010 20:51:55.731 loading configuration: too many open files 28-Sep-2010 20:51:55.731 exiting (due to fatal error)
diff -Nru bind9-9.7.1.dfsg.P2/debian/changelog bind9-9.7.1.dfsg.P2-parselimit/debian/changelog --- bind9-9.7.1.dfsg.P2/debian/changelog 2010-07-16 13:25:16.000000000 +0200 +++ bind9-9.7.1.dfsg.P2-parselimit/debian/changelog 2010-09-28 19:21:25.000000000 +0200 @@ -1,3 +1,12 @@ +bind9 (1:9.7.1.dfsg.P2-3) unstable; urgency=low + + * /lib/isccfg/include/isccfg/grammar.h, lib/isccfg/parser.c: + Limit the maximum number of include files that can be opened + simultaneously to prevent recursive includes (i.e. named.conf + with an 'include named.conf' statement) from working. + + -- Javier Fernandez-Sanguino Pen~a <j...@debian.org> Tue, 28 Sep 2010 19:19:16 +0200 + bind9 (1:9.7.1.dfsg.P2-2) unstable; urgency=low * Correct conflicts for bind9-host diff -Nru bind9-9.7.1.dfsg.P2/lib/isccfg/include/isccfg/grammar.h bind9-9.7.1.dfsg.P2-parselimit/lib/isccfg/include/isccfg/grammar.h --- bind9-9.7.1.dfsg.P2/lib/isccfg/include/isccfg/grammar.h 2009-06-12 01:47:55.000000000 +0200 +++ bind9-9.7.1.dfsg.P2-parselimit/lib/isccfg/include/isccfg/grammar.h 2010-09-28 21:25:19.000000000 +0200 @@ -203,6 +203,14 @@ */ cfg_obj_t * closed_files; + /* % + * Number of files that we are currently + * parsing, this is the length of the open_files + * stack. We keep this number in order to + * detect infinite recursive includes. + */ + unsigned int open_files_count; + /*% * Current line number. We maintain our own * copy of this so that it is available even diff -Nru bind9-9.7.1.dfsg.P2/lib/isccfg/parser.c bind9-9.7.1.dfsg.P2-parselimit/lib/isccfg/parser.c --- bind9-9.7.1.dfsg.P2/lib/isccfg/parser.c 2009-09-03 01:43:54.000000000 +0200 +++ bind9-9.7.1.dfsg.P2-parselimit/lib/isccfg/parser.c 2010-09-28 21:25:19.000000000 +0200 @@ -395,6 +395,7 @@ pctx->errors = 0; pctx->warnings = 0; pctx->open_files = NULL; + pctx->open_files_count = 0; pctx->closed_files = NULL; pctx->line = 0; pctx->callback = NULL; @@ -432,12 +433,22 @@ return (result); } +#define MAX_OPEN_FILES 100 /* How many open files we want to keep. */ + static isc_result_t parser_openfile(cfg_parser_t *pctx, const char *filename) { isc_result_t result; cfg_listelt_t *elt = NULL; cfg_obj_t *stringobj = NULL; + /* Check wether the limit of open files has been exceeded */ + pctx->open_files_count++; + if (pctx->open_files_count > MAX_OPEN_FILES) { + cfg_parser_error(pctx, 0, "too many included files, last was: %s", + filename); + goto cleanup; + } + result = isc_lex_openfile(pctx->lexer, filename); if (result != ISC_R_SUCCESS) { cfg_parser_error(pctx, 0, "open: %s: %s", @@ -449,6 +460,7 @@ CHECK(create_listelt(pctx, &elt)); elt->obj = stringobj; ISC_LIST_APPEND(pctx->open_files->value.list, elt, link); + return (ISC_R_SUCCESS); cleanup: @@ -2118,6 +2130,8 @@ value.list, elt, link); ISC_LIST_APPEND(pctx->closed_files-> value.list, elt, link); + if (pctx->open_files_count > 0) + pctx->open_files_count--; goto redo; } pctx->seen_eof = ISC_TRUE;
28-Sep-2010 20:45:43.768 starting BIND 9.7.1-P2 -u bind -g 28-Sep-2010 20:45:43.786 built with '--prefix=/usr' '--mandir=/usr/share/man' '--infodir=/usr/share/info' '--sysconfdir=/etc/bind' '--localstatedir=/var' '--enable-threads' '--enable-largefile' '--with-libtool' '--enable-shared' '--enable-static' '--with-openssl=/usr' '--with-gssapi=/usr' '--with-gnu-ld' '--with-dlz-postgres=no' '--with-dlz-mysql=no' '--with-dlz-bdb=yes' '--with-dlz-filesystem=yes' '--with-dlz-ldap=yes' '--with-dlz-stub=yes' '--with-geoip=/usr' '--enable-ipv6' 'CFLAGS=-fno-strict-aliasing -DDIG_SIGCHASE -O2' 'LDFLAGS=' 'CPPFLAGS=' 28-Sep-2010 20:45:43.786 adjusted limit on open files from 1024 to 1048576 28-Sep-2010 20:45:43.786 found 2 CPUs, using 2 worker threads 28-Sep-2010 20:45:43.787 using up to 4096 sockets 28-Sep-2010 20:45:43.792 loading configuration from '/etc/bind/named.conf' 28-Sep-2010 20:45:43.796 /etc/bind/named.conf.local:10: too many included files, last was: /etc/bind/named.conf.local 28-Sep-2010 20:45:43.797 loading configuration: (result code text not available) 28-Sep-2010 20:45:43.797 exiting (due to fatal error)
signature.asc
Description: Digital signature