From: Sean Bright Date: Wed, 15 Jun 2011 15:22:50 +0000 (+0000) Subject: Merged revisions 323559 via svnmerge from X-Git-Tag: 1.6.2.19-rc1~3^2~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fb9e90765293feb48add911e8c15d4e996cb89fe;p=thirdparty%2Fasterisk.git Merged revisions 323559 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r323559 | seanbright | 2011-06-15 11:15:30 -0400 (Wed, 15 Jun 2011) | 25 lines Resolve a segfault/bus error when we try to map memory that falls on a page boundary. The fix for ASTERISK-15359 was incorrect in that it added 1 to the length of the mmap'd region. The problem with this is that reading/writing to that extra byte outside of the bounds of the underlying fd causes a bus error. The real issue is that we are working with both a FILE * and the raw fd underneath it and not synchronizing between them. The code that was removed in ASTERISK-15359 was correct, but we weren't flushing the FILE * before mapping the fd. Looking at the manager code in 1.4 reveals that the FILE * in 'struct mansession' is never used except to create a temporary file that we immediately fdopen. This means we just need to write a 0 byte to the fd and everything will just work. The other branches require a call to fflush() which, while not a guaranteed fix, should reduce the likelihood of a crash. This all makes sense in my head. (closes issue ASTERISK-16460) Reported by: Ravelomanantsoa Hoby (hoby) Patches: issue17747_1.4_svn_markII.patch uploaded by Sean Bright (license #5060) ........ git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.6.2@323579 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- diff --git a/main/manager.c b/main/manager.c index da7f03a599..c691f30f4d 100644 --- a/main/manager.c +++ b/main/manager.c @@ -4051,8 +4051,12 @@ static struct ast_str *generic_http_callback(enum output_format format, char *buf; size_t l; + /* Ensure buffer is NULL-terminated */ + fprintf(s.f, "%c", 0); + fflush(s.f); + if ((l = ftell(s.f))) { - if (MAP_FAILED == (buf = mmap(NULL, l + 1, PROT_READ | PROT_WRITE, MAP_PRIVATE, s.fd, 0))) { + if (MAP_FAILED == (buf = mmap(NULL, l, PROT_READ | PROT_WRITE, MAP_PRIVATE, s.fd, 0))) { ast_log(LOG_WARNING, "mmap failed. Manager output was not processed\n"); } else { buf[l] = '\0'; @@ -4061,13 +4065,14 @@ static struct ast_str *generic_http_callback(enum output_format format, } else { ast_str_append(&out, 0, "%s", buf); } - munmap(buf, l + 1); + munmap(buf, l); } } else if (format == FORMAT_XML || format == FORMAT_HTML) { xml_translate(&out, "", params, format); } fclose(s.f); s.f = NULL; + close(s.fd); s.fd = -1; }