Skip to content

Commit 7bd0f5c

Browse files
Teo Koon PengMinggang Wang
authored andcommitted
fix use-after-free in subscription callbacks (#680)
* testcase for uaf * add --expose-gc in test script * change copyright to OSRF Fix #673
1 parent c11f1f2 commit 7bd0f5c

File tree

2 files changed

+90
-1
lines changed

2 files changed

+90
-1
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"scripts": {
1616
"install": "node-gyp rebuild",
1717
"docs": "cd docs && make",
18-
"test": "node ./scripts/compile_tests.js && node ./scripts/run_test.js && node ./scripts/generate_tsd.js && dtslint test/types",
18+
"test": "node ./scripts/compile_tests.js && node --expose-gc ./scripts/run_test.js && node ./scripts/generate_tsd.js && dtslint test/types",
1919
"lint": "eslint --max-warnings=0 index.js types/*.d.ts scripts lib example rosidl_gen rosidl_parser test benchmark/rclnodejs && node ./scripts/cpplint.js",
2020
"postinstall": "node scripts/generate_messages.js",
2121
"format": "clang-format -i -style=file ./src/*.cpp ./src/*.hpp && prettier --trailing-comma es5 --single-quote --write \"{.,{lib,rosidl_gen,rostsd_gen,rosidl_parser,types,example,test}/**}/*.{js,md,ts}\""

test/test-promise-gc.js

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/*
2+
* Copyright (C) 2020 Open Source Robotics Foundation
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
*/
17+
18+
/* eslint-disable camelcase */
19+
'use strict';
20+
21+
const assert = require('assert');
22+
const rclnodejs = require('../index.js');
23+
24+
/**
25+
* These tests need to be run with `--expose-gc` flags.
26+
*/
27+
describe('Test promise wrapper with garbage collection', function () {
28+
this.timeout(60 * 1000);
29+
30+
before(function () {
31+
return rclnodejs.init();
32+
});
33+
34+
after(function () {
35+
rclnodejs.shutdown();
36+
});
37+
38+
[
39+
{
40+
typeClass: 'std_msgs/msg/String',
41+
msg: {
42+
data: 'Hello World!',
43+
},
44+
},
45+
{
46+
typeClass: 'std_msgs/msg/UInt8MultiArray',
47+
msg: {
48+
layout: { dim: [{ label: 'test', size: 10, stride: 10 }], data_offset: 0 },
49+
data: Uint8Array.from([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]),
50+
},
51+
},
52+
{
53+
typeClass: 'sensor_msgs/msg/JointState',
54+
msg: {
55+
header: {
56+
stamp: {
57+
sec: 123456,
58+
nanosec: 789,
59+
},
60+
frame_id: 'main frame',
61+
},
62+
name: ['Tom', 'Jerry'],
63+
position: Float64Array.from([1, 2]),
64+
velocity: Float64Array.from([2, 3]),
65+
effort: Float64Array.from([4, 5, 6]),
66+
},
67+
},
68+
].forEach(({ typeClass, msg }, i) =>
69+
it(`${typeClass} message does not get garbage collected`, async function () {
70+
const node = rclnodejs.createNode(`promise_gc_${i}`);
71+
rclnodejs.spin(node);
72+
73+
const topic = `promise_gc_channel_${i}`;
74+
75+
const publisher = node.createPublisher(typeClass, topic);
76+
const timer = node.createTimer(100, () => publisher.publish(msg));
77+
78+
const result = await new Promise((res) =>
79+
node.createSubscription(typeClass, topic, (msg) => {
80+
timer.cancel();
81+
node.destroy();
82+
res(msg);
83+
})
84+
);
85+
global.gc();
86+
assert.deepEqual(result, msg);
87+
})
88+
);
89+
});

0 commit comments

Comments
 (0)