On Wed, Nov 03, 2010 at 02:33:12PM +0200, Alexey Suslikov wrote: > This is somewhat ports related, but I decided to ask here before going > further with diff. > > Well, we have Asterisk 1.6.2.14-rc1 going segfault: > > #0 generic_http_callback (format=FORMAT_XML, remote_address=0x4001, > uri=0x4001 <Address 0x4001 out of bounds>, method=205216842, > params=0x20eb5bc00, status=0x2057b2c74, title=0x2057b2c78, > contentlength=0x2057b2c84) at manager.c:4005 > 4005 > > #0 generic_http_callback (format=FORMAT_XML, remote_address=0x4001, > uri=0x4001 <Address 0x4001 out of bounds>, method=205216842, > params=0x20eb5bc00, status=0x2057b2c74, title=0x2057b2c78, > contentlength=0x2057b2c84) at manager.c:4005 > buf = 0x208dd5000 <Address 0x208dd5000 out of bounds> > l = 16384 > s = {session = 0x203382800, f = 0x2036d3440, fd = 245} > session = (struct mansession_session *) 0x203382800 > ident = 390437576 > blastaway = 0 > v = (struct ast_variable *) 0x4000 > template = "/tmp/ast-http-U9afaz" > out = (struct ast_str *) 0x207fd7800 > m = {hdrcount = 2, headers = {0x2057b2470 "Action: CoreShowChannels", > 0x2057b2450 "mansession_id: 17459ac8", 0x0 <repeats 126 times>}} > x = 16385 > hdrlen = 0 > > Relevant lines are: > > if (s.f != NULL) { /* have temporary output */ > char *buf; > size_t l; > > if ((l = ftell(s.f))) { > if (MAP_FAILED == (buf = mmap(NULL, l + 1, > PROT_READ | PROT_WRITE, MAP_PRIVATE, s.fd, 0))) { > ast_log(LOG_WARNING, "mmap failed. > Manager output was not processed\n"); > } else { > =>4005: buf[l] = '\0'; > if (format == FORMAT_XML || format == > FORMAT_HTML) { > xml_translate(&out, buf, > params, format); > } else { > ast_str_append(&out, 0, "%s", buf); > } > munmap(buf, l + 1); > } > } else if (format == FORMAT_XML || format == FORMAT_HTML) { > xml_translate(&out, "", params, format); > } > fclose(s.f); > s.f = NULL; > s.fd = -1; > } > > So if ftell() returns value of l exactly at the end of file, accessing > l + 1 leads to segfault while mmaping l + 1 is ok, right?
Byte l+1 is not present in the file. Reading or writing on that byte is going to yield undefined behaviour regardless. Requesting a length larger than the file length is fine. mmap(2) maps 'at most len bytes'. http://www.opengroup.org/onlinepubs/7990989775/xsh/mmap.html mentions SIGBUS instead of SIGSEGV for the pages that aren't be mapped. Ciao, -- Ariane