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

AddressSanitizer: Null pointer dereference in fx_Function_prototype_hasInstance #748

Closed
eternalsakura opened this issue Dec 13, 2021 · 2 comments
Labels
confirmed issue reported has been reproduced fixed - please verify Issue has been fixed. Please verify and close.

Comments

@eternalsakura
Copy link

Build environment

  • operating system: ubuntu20.04
  • cimmit hash: db8f973
  • compile command:
cd /pathto/moddable/xs/makefiles/lin
make debug or make release
  • test command:
./xst poc

poc

function assertThrows(code, type_opt, cause_opt) {
    if (typeof code === 'function')
        return code();
    if (typeof code === 'string')
        return eval(code);
}
(function () {
    var F = {};
    F[Symbol.hasInstance] = null;
    assertThrows || F ? 7160833982606838.000000: assertThrows(assertThrows, /[\WD]/i, /T61/);
}());
(function () {
    var F = {};
    F[Symbol.hasInstance] = function () {
        return undefined;
    };
    print(0 instanceof F, false);
    F[Symbol.hasInstance] = function () {
        return null;
    };
    print(0 instanceof F, false);
    F[Symbol.hasInstance] = function () {
        return true;
    };
    print(0 instanceof F, true);
}());
(function () {
    var F = {};
    F[Symbol.hasInstance] = function () {
        throw new Error('always throws');
    };
    try {
        0 instanceof F;
    } catch (e) {
        print(e.message, 'always throws');
    }
}());
(function () {
    var BC = function () {
    };
    var bc = new BC();
    var bound = BC.bind();
    print(bound[Symbol.hasInstance](bc), true);
    print(bound[Symbol.hasInstance]([]), false);
}());
print(Function.prototype[Symbol.hasInstance].call(Array, []), true);
print(Function.prototype[Symbol.hasInstance].call({
    "L0VB0": assertThrows
}, {
    "getPrototypeOf": assertThrows
}), false);
print(Function.prototype[Symbol.hasInstance].call(Array, 0), false);
(function () {
    'use strict';
    function F() {
    }
    assertThrows(function () {
        F[Symbol.hasInstance] = v => v;
    }, TypeError);
}());
(function () {
    function F() {
    }
    var counter = 0;
    var proto = Object.getPrototypeOf(F);
    Object.setPrototypeOf(F, null);
    F[Symbol.hasInstance] = function (v) {
        ++counter;
        return true;
    };
    Object.setPrototypeOf(F, proto);
    print(1 instanceof F);
    print(1, counter);
}());
  • asan log
=================================================================
==2131098==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x000000542885 bp 0x7ffc6530e8d0 sp 0x7ffc6530e8a0 T0)
==2131098==The signal is caused by a READ memory access.
==2131098==Hint: address points to the zero page.
    #0 0x542885 in fx_Function_prototype_hasInstance /home/sakura/moddable/xs/sources/xsFunction.c:546:11
    #1 0x59b4b7 in fxRunID /home/sakura/moddable/xs/sources/xsRun.c:842:8
    #2 0x5426e1 in fx_Function_prototype_call /home/sakura/moddable/xs/sources/xsFunction.c:526:2
    #3 0x59b4b7 in fxRunID /home/sakura/moddable/xs/sources/xsRun.c:842:8
    #4 0x5b50e2 in fxRunScript /home/sakura/moddable/xs/sources/xsRun.c:4766:4
    #5 0x61567c in fxRunProgramFile /home/sakura/moddable/xs/tools/xst.c:1387:2
    #6 0x60fbef in main /home/sakura/moddable/xs/tools/xst.c:281:8
    #7 0x7f08b5c6e0b2 in __libc_start_main /build/glibc-eX1tMB/glibc-2.31/csu/../csu/libc-start.c:308:16
    #8 0x42e6bd in _start (/home/sakura/moddable/build/bin/lin/debug/xst+0x42e6bd)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /home/sakura/moddable/xs/sources/xsFunction.c:546:11 in fx_Function_prototype_hasInstance
==2131098==ABORTING
  • release log
[] ~/sk-afl-js/moddable_workdir <main> ~/moddable/build/bin/lin/release/xst fuzz_output/fuzzer1/crashes/id:000021,sig:06,src:002188,op:\(null\),pos:0.js 
false false
false false
true true
always throws always throws
true true
false false
true true
[2]    2105934 segmentation fault  ~/moddable/build/bin/lin/release/xst 
@phoddie phoddie added the confirmed issue reported has been reproduced label Dec 13, 2021
@phoddie
Copy link
Collaborator

phoddie commented Dec 13, 2021

Simplified test case:

function assertThrows() {
	throw new Error;
}

Function.prototype[Symbol.hasInstance].call({}, {
	"getPrototypeOf": assertThrows
});

@phoddie
Copy link
Collaborator

phoddie commented Dec 31, 2021

We have a fix for this pending. It should be available next week.

The crash was because Function.prototype[ @@hasInstance ] didn't check to see if this was callable. In fixing that, we noticed that the steps for the implementation were incorrect for bound functions, which was a conformance issue. That will be fixed as well. Excellent discovery. Thank you!

mkellner pushed a commit that referenced this issue Jan 10, 2022
@phoddie phoddie added the fixed - please verify Issue has been fixed. Please verify and close. label Jan 10, 2022
@phoddie phoddie closed this as completed Jan 18, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
confirmed issue reported has been reproduced fixed - please verify Issue has been fixed. Please verify and close.
Projects
None yet
Development

No branches or pull requests

2 participants