From: Operating system: Linux PHP version: 5.2.14 Package: CGI related Bug Type: Bug Bug description:fcgi_write buffer overflow when safe_write fail
Description: ------------ in fastcgi.c 1094 int fcgi_write(fcgi_request *req, fcgi_request_type type, const char *str, int len) ... 1165 int pos = 0; 1166 int pad; 1167 1168 close_packet(req); 1169 while ((len - pos) > 0xffff) { 1170 open_packet(req, type); 1171 fcgi_make_header(req->out_hdr, type, req->id, 0xfff8); 1172 req->out_hdr = NULL; 1173 if (!fcgi_flush(req, 0)) { ~~~~~~~~~ fail and return; 1174 return -1; 1175 } 1176 if (safe_write(req, str + pos, 0xfff8) != 0xfff8) { 1177 req->keep = 0; 1178 return -1; 1179 } 1180 pos += 0xfff8; 1181 } 1182 1183 pad = (((len - pos) + 7) & ~7) - (len - pos); 1184 rest = pad ? 8 - pad : 0; 1185 1173 line fcgi_flush after call fail return -1, but before fcgi_flush open_packet(req, type) can add req->out_pos. if we call fcgi_write repeated, the req->out_pos will be greater req. 1047 static inline fcgi_header* open_packet(fcgi_request *req, fcgi_request_type type) 1048 { 1049 req->out_hdr = (fcgi_header*) req->out_pos; 1050 req->out_hdr->type = type; 1051 req->out_pos += sizeof(fcgi_header); ~~~~~~~~~~~~~~~~~~ add out_pos 1052 return req->out_hdr; 1053 } fcgi_request define is: 94 typedef struct _fcgi_request { 95 int listen_socket; 96 #ifdef _WIN32 97 int tcp; 98 #endif 99 int fd; 100 int id; 101 int keep; 102 103 int in_len; 104 int in_pad; 105 106 fcgi_header *out_hdr; 107 unsigned char *out_pos; 108 unsigned char out_buf[1024*8]; 109 unsigned char reserved[sizeof(fcgi_end_request_rec)]; 110 111 HashTable env; 112 } fcgi_request; the "env" will be write and result in coredump when use the "env" . my program write much more logs. it will be call "sapi_cgi_log_message" in cgi_main.c static void sapi_cgi_log_message(char *message) 670 { 671 #if PHP_FASTCGI 672 TSRMLS_FETCH(); 673 674 if (fcgi_is_fastcgi() && CGIG(fcgi_logging)) { 675 fcgi_request *request; 676 677 request = (fcgi_request*) SG(server_context); 678 if (request) { 679 int len = strlen(message); 680 char *buf = malloc(len+2); 681 682 memcpy(buf, message, len); 683 memcpy(buf + len, "\n", sizeof("\n")); 684 fcgi_write(request, FCGI_STDERR, buf, len+1); ~~~~~~~~~~~~~~~~~ here will be call 685 free(buf); 686 } else { 687 fprintf(stderr, "%s\n", message); 688 } 689 /* ignore return code */ 690 } else 691 #endif /* PHP_FASTCGI */ 692 fprintf(stderr, "%s\n", message); 693 } I think you can reset req->out_pos after write fail. thank you -- Edit bug report at http://bugs.php.net/bug.php?id=53123&edit=1 -- Try a snapshot (PHP 5.2): http://bugs.php.net/fix.php?id=53123&r=trysnapshot52 Try a snapshot (PHP 5.3): http://bugs.php.net/fix.php?id=53123&r=trysnapshot53 Try a snapshot (trunk): http://bugs.php.net/fix.php?id=53123&r=trysnapshottrunk Fixed in SVN: http://bugs.php.net/fix.php?id=53123&r=fixed Fixed in SVN and need be documented: http://bugs.php.net/fix.php?id=53123&r=needdocs Fixed in release: http://bugs.php.net/fix.php?id=53123&r=alreadyfixed Need backtrace: http://bugs.php.net/fix.php?id=53123&r=needtrace Need Reproduce Script: http://bugs.php.net/fix.php?id=53123&r=needscript Try newer version: http://bugs.php.net/fix.php?id=53123&r=oldversion Not developer issue: http://bugs.php.net/fix.php?id=53123&r=support Expected behavior: http://bugs.php.net/fix.php?id=53123&r=notwrong Not enough info: http://bugs.php.net/fix.php?id=53123&r=notenoughinfo Submitted twice: http://bugs.php.net/fix.php?id=53123&r=submittedtwice register_globals: http://bugs.php.net/fix.php?id=53123&r=globals PHP 4 support discontinued: http://bugs.php.net/fix.php?id=53123&r=php4 Daylight Savings: http://bugs.php.net/fix.php?id=53123&r=dst IIS Stability: http://bugs.php.net/fix.php?id=53123&r=isapi Install GNU Sed: http://bugs.php.net/fix.php?id=53123&r=gnused Floating point limitations: http://bugs.php.net/fix.php?id=53123&r=float No Zend Extensions: http://bugs.php.net/fix.php?id=53123&r=nozend MySQL Configuration Error: http://bugs.php.net/fix.php?id=53123&r=mysqlcfg