Repository navigation
process.setuid results in an abort #32750
Description
Activity
I can recreate this on master,
v10.xprints a proper error message, so looks like a regression to medefinition of
unsigned intseem to have diverged betweenJSandC++? looks like the check passed in the former, but failed later?node/lib/internal/validators.js
Line 101 in 203776f
const validateUint32 = hideStackFrames((value, name, positive) => { Line 247 in 203776f
CHECK(args[0]->IsUint32() || args[0]->IsString()); Reacted by Alex Yangfailed later -> failed * in * later
node --expose-internals -e 'require("internal/validators").validateInt32(-0)'
does not throw, implies this method (
validateInt32) does not considerIsMinusZerowhichIsUint32of v8 does.validateInt32hasn't changed between (passing and failing) versions:
node/lib/internal/validators.js
Line 83 in b023d61
const validateInt32 = hideStackFrames( does this imply
IsUint32has changed its meaning in V8? that doesn't sound logical!My team is trying to find bugs and vulnerabilities at the interface between js and c++, and we think this problem of inconsistency is an interesting study case for us. Can you give us a confirmation for this bug? As proof for us to make a discussion in our work.
Reacted by Gireesh Punathil- addedconfirmed-bugIssues and PRs for confirmed bugs.Issues and PRs for confirmed bugs.
on Apr 10, 2020 @zyscoder - that is an interesting area to research, good luck! I tagged it as
bug/cc @nodejs/v8 in case if there is an obvious explanation.
bisecting now.
Interesting! That problem is not only present in
process.setuid. The following also fails on Node.js 10:> node -e "require('fs').chownSync('test', -0, -0)" src\node_file.cc:2029: Assertion `args[1]->IsUint32()' failed.V8 always returns
false(and it's not new) forIsInt32andIsUint32methods.I see two things that we can do:
- Throw in our int32/uint32 validators if -0 is passed (potentially breaking change)
- Make sure we coerce -0 to 0 either in the validator itself or before passing the value to C++
Thoughts?
Reacted by Gireesh Punathiltechnically
-0is signed, so throwing fromuint32 validatormakes sense to me!The counterargument is that
0and-0are indistinguishable (i.e.,0 === -0) except when checking withObject.is(). Coercion to positive 0 seems like the principle of least surprise to me.Reacted by Anna Henningsen, Michaël Zasso and Alex Yang- added a commit that references this issue
on Apr 14, 2020 - added a commit that references this issue
on Jan 4, 2021 - added a commit that references this issue
on Jan 12, 2021 - added a commit that references this issue
on May 1, 2021 - added a commit that references this issue
on May 22, 2026
What steps will reproduce the bug?
Directly run the following code snippet using node:
How often does it reproduce? Is there a required condition?
No. This potential bug can always be reproduced.
What is the expected behavior?
The argument to 'process.setuid' should be a Uint32 or string value, but we passed a -0 into it. The function should throw an exception or other similar error-reporting stuff rather than crash the whole nodejs process.
What do you see instead?
This is the stack dump produced during abort:
Additional information