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