Skip to content

Commit 0504066

Browse files
indutnyrvagg
authored andcommitted
http: fix out-of-order 'finish' bug in pipelining
Changes to `stream_base.cc` are required to support empty writes. Fixes CVE-2015-7384, #3138 Fix: #2639 PR-URL: #3128
1 parent 342c3a1 commit 0504066

File tree

3 files changed

+39
-7
lines changed

3 files changed

+39
-7
lines changed

lib/_http_outgoing.js

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -133,12 +133,6 @@ OutgoingMessage.prototype._writeRaw = function(data, encoding, callback) {
133133
encoding = null;
134134
}
135135

136-
if (data.length === 0) {
137-
if (typeof callback === 'function')
138-
process.nextTick(callback);
139-
return true;
140-
}
141-
142136
var connection = this.connection;
143137
if (connection &&
144138
connection._httpMessage === this &&
@@ -158,6 +152,10 @@ OutgoingMessage.prototype._writeRaw = function(data, encoding, callback) {
158152
this.output = [];
159153
this.outputEncodings = [];
160154
this.outputCallbacks = [];
155+
} else if (data.length === 0) {
156+
if (typeof callback === 'function')
157+
process.nextTick(callback);
158+
return true;
161159
}
162160

163161
// Directly write to socket.

src/stream_base.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ int StreamBase::Writev(const FunctionCallbackInfo<Value>& args) {
154154

155155
// Write string
156156
offset = ROUND_UP(offset, WriteWrap::kAlignSize);
157-
CHECK_LT(offset, storage_size);
157+
CHECK_LE(offset, storage_size);
158158
char* str_storage = req_wrap->Extra(offset);
159159
size_t str_size = storage_size - offset;
160160

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
'use strict';
2+
const common = require('../common');
3+
const assert = require('assert');
4+
const http = require('http');
5+
const net = require('net');
6+
7+
const COUNT = 10;
8+
9+
var received = 0;
10+
11+
var server = http.createServer(function(req, res) {
12+
// Close the server, we have only one TCP connection anyway
13+
if (received++ === 0)
14+
server.close();
15+
16+
res.writeHead(200);
17+
res.write('data');
18+
19+
setTimeout(function() {
20+
res.end();
21+
}, (Math.random() * 100) | 0);
22+
}).listen(common.PORT, function() {
23+
const s = net.connect(common.PORT);
24+
25+
var big = '';
26+
for (var i = 0; i < COUNT; i++)
27+
big += 'GET / HTTP/1.0\r\n\r\n';
28+
s.write(big);
29+
s.resume();
30+
});
31+
32+
process.on('exit', function() {
33+
assert.equal(received, COUNT);
34+
});

0 commit comments

Comments
 (0)