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