Skip to content
This repository was archived by the owner on Apr 22, 2023. It is now read-only.

Add signature to SET_PROTOTYPE_METHOD and use args.Holder() in methods. #7261

Closed
wants to merge 1 commit into from

Conversation

cscott
Copy link

@cscott cscott commented Mar 6, 2014

This prevents segfaults when a native method is reassigned to a different
object to corrupt args.This().

Closes #6690.

@Nodejs-Jenkins
Copy link

Thank you for contributing this pull request! Here are a few pointers to make sure your submission will be considered for inclusion.

Commit cscott/node@37f8296 has the following error(s):

  • First line of commit message must be no longer than 50 characters
  • Commit message must indicate the subsystem this commit changes
  • Commit message line too long: 2

The following commiters were not found in the CLA:

  • C. Scott Ananian

You can fix all these things without opening another issue.

Please see CONTRIBUTING.md for more information

@indutny
Copy link
Member

indutny commented Mar 6, 2014

I think this may have serious impact on performance of crossing C++/JS boundary... cc @trevnorris

@cscott
Copy link
Author

cscott commented Mar 6, 2014

It may (or may not) have a performance impact, but it has serious security
implications. See #6690.

@indutny
Copy link
Member

indutny commented Mar 6, 2014

@cscott you should never directly expose C++ methods to JS if you care about security, they should always be wrapped in a javascript objects. And another note, if you give access to C++ stuff to the untrusted code - application is already vulnerable.

@bnoordhuis
Copy link
Member

I think this may have serious impact on performance of crossing C++/JS boundary

It generally does but this looks okay. Upstream V8 won't inline API function calls that have non-trivial signatures but here the only restriction is on the receiver.

@trevnorris
Copy link

@bnoordhuis Is there going to be much performance difference between the following two snippets?

template<typename T>
Local<Object> FunctionCallbackInfo<T>::This() const {
  return Local<Object>(reinterpret_cast<Object*>(values_ + 1));
}


template<typename T>
Local<Object> FunctionCallbackInfo<T>::Holder() const {
  return Local<Object>(reinterpret_cast<Object*>(
      &implicit_args_[kHolderIndex]));
}

@@ -196,7 +196,7 @@ void UDPWrap::Bind6(const FunctionCallbackInfo<Value>& args) {
#define X(name, fn) \
void UDPWrap::name(const FunctionCallbackInfo<Value>& args) { \
HandleScope scope(args.GetIsolate()); \
UDPWrap* wrap = Unwrap<UDPWrap>(args.This()); \
UDPWrap* wrap = Unwrap<UDPWrap>(args.Holder()); \

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: forgot to remove a space before the \. makes the line exceed 80 chars.

@trevnorris
Copy link

@indutny If this is added, can we add a custom cpplint check like "\<Unwrap<\w*>(args\.This())" to make sure any future edits don't accidentally use This()?

@bnoordhuis
Copy link
Member

Is there going to be much performance difference between the following two snippets?

There should be no measurable difference, they're both bitcasts of a stack slot.

That's assuming they're in the same cache line but even if that isn't the case, I'd be pretty amazed if you could make that show up during profiling.

@trevnorris
Copy link

Well, I haven't been able to find any noticeable performance impact. So I'm fine with this.

THB I only half get how v8::Signature works, but i'm also only running on half brain cells.

@indutny
Copy link
Member

indutny commented Mar 11, 2014

@trevnorris about linter: go for it :)

@cscott
Copy link
Author

cscott commented Mar 14, 2014

Rebased on current HEAD; fixed style issues flagged by @trevnorris above.

@cscott
Copy link
Author

cscott commented Mar 14, 2014

The test failures appear to be due to #7309, not this patch.

This prevents segfaults when a native method is reassigned to a
different object (which corrupts `args.This()`).  When unwrapping,
clients should use `args.Holder()` instead of `args.This()`.

Closes nodejs#6690.
@cscott
Copy link
Author

cscott commented Mar 17, 2014

Rebased on current master.

Note that Buffer uses NODE_SET_METHOD instead of NODE_SET_PROTOTYPE_METHOD and so is not protected by this patch. For example:

b = new Buffer(8);
o = { fill: b.fill };
o.fill(0); // segfaults

@trevnorris
Copy link

@cscott True. The reason for that is NODE_SET_PROTOTYPE_METHOD only works for FunctionTemplate, but we're adding methods to a JS Function. I'm not aware of a way to work around this.

@trevnorris
Copy link

Merged in 08a5b44.

@trevnorris trevnorris closed this Apr 2, 2014
@cscott
Copy link
Author

cscott commented Apr 2, 2014

Thanks!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants