Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

spawnSync segfaults when given throwing toString #9820

Closed
deian opened this issue Nov 28, 2016 · 9 comments
Closed

spawnSync segfaults when given throwing toString #9820

deian opened this issue Nov 28, 2016 · 9 comments
Assignees
Labels
child_process Issues and PRs related to the child_process subsystem.

Comments

@deian
Copy link
Member

deian commented Nov 28, 2016

  • Version: 6.4.0 - 8.0.0
  • Platform:
  • Subsystem:

spawnSync will segfault if called with an object that defines a throwing toString.

Here is a snippet using the high-level child_process API:

const spawn = require('child_process').spawnSync;

const args = [];
const obj = {};
obj.toString = () => {
  throw 'yo';
  // causes ToString on spawn_sync.cc:964 to return empty handle; Set getfaults
    
};
args[0] = obj;
spawn('ls', args);

It may be safer to call toString in JS land before calling into the binding
code.

@mscdex mscdex added the child_process Issues and PRs related to the child_process subsystem. label Nov 28, 2016
@Fishrock123
Copy link
Contributor

This is probably a larger problem and we may need checks for other APIs.

I think we should error but avoid segfaulting.

@TimothyGu
Copy link
Member

TimothyGu commented Mar 20, 2017

I discussed this with @addaleax on IRC a while ago. Basically we should provide a way for Utf8Value and TwoByteValue to signify an error condition. A few options are possible:

  1. return an invalidated MaybeStackBuffer if ToString errors:
    void func(Local<Value> value) {
      Utf8Value str(env->isolate(), value);
      if (str.IsInvalidated())
        return;
      // do things with str
    }
  2. provide a constructor that sets a boolean pointer in case of error:
    void func(Local<Value> value) {
      bool success = false;
      Utf8Value str(env->isolate(), value, &success);
      if (!success)
        return;
      // do things with str
    }

Option 1 is the cleaner solution (EDIT: and it is also the one BufferValue uses), but given the fact that these two classes have been used all over the code base it might be difficult to change them all.

Option 2 is more compatible since we can make bool* success default to nullptr. I'm leaning toward this option, but at the same time I suspect it might be better to just do a full audit at once as opposed to delaying it for the future.

Any thoughts on this?

@addaleax
Copy link
Member

@TimothyGu I agree, Option 1 sounds better to me. We could also use that to see which Utf8Value calls could be replaced by BufferValue, I would guess there’s quite a few places where that makes sense. (We’d have to split those into different changesets … one is definitely semver-patch and one is definitely semver-minor.)

Do you want to take that on? If not, I should be able to do it too.

@TimothyGu
Copy link
Member

@addaleax #11952. Feel free to fill in on the files I haven't yet gone through!

@Trott
Copy link
Member

Trott commented Jul 30, 2017

@TimothyGu With #11952 closed, should we make a note here of the solution now envisioned?

@TimothyGu
Copy link
Member

TimothyGu commented Jul 31, 2017

@Trott Sure. Right now Utf8Value and TwoByteValue both take any v8::Value, which forces the constructors to convert them to v8::String first. This conversion step is the only place that can cause failures in these two constructors (think of a toString handler that throws). Thus I believe a better way to address this problem would be to make the constructors take v8::String, and forces the user of those classes to handle type conversions and possible errors, instead of relying on IsInvalidated() and other similar methods from the Utf8Value and TwoByteValue classes.

@gireeshpunathil
Copy link
Member

fwiw, this fails in v10.x too (as many attempts to fix this seem to have stalled)

@tlhunter
Copy link
Contributor

tlhunter commented Sep 30, 2018

This code sample no longer segfaults as of v10.10.0, and segfaults as late as v10.9.0.

@apapirovski
Copy link
Member

Ok, sounds like we should just close it out then.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
child_process Issues and PRs related to the child_process subsystem.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants