Edit report at https://bugs.php.net/bug.php?id=53123&edit=1
ID: 53123 Updated by: fel...@php.net Reported by: NahumBao at gmail dot com Summary: fcgi_write buffer overflow when safe_write fail -Status: Open +Status: Closed Type: Bug Package: CGI/CLI related Operating System: Linux PHP Version: 5.2.14 -Assigned To: +Assigned To: felipe Block user comment: N Private report: N New Comment: It seems already fixed. Previous Comments: ------------------------------------------------------------------------ [2010-10-21 07:29:20] NahumBao at gmail dot com 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 this bug report at https://bugs.php.net/bug.php?id=53123&edit=1