[5] DFG RegExp constructor miscompilation via missing newTarget propagation
Severity: Medium | Component: JSC DFG JIT | 47b17ca
Regression test를 통해 confidence 0.92로 확인된 JavaScript 수준의 object identity 위반(constructor가 새 객체 대신 동일 객체를 반환)이 관측 가능한 영향입니다. 직접적인 memory corruption은 없으며, 영향 확대 여부는 혼동된 identity를 downstream JavaScript 코드가 어떻게 활용하는지에 달려 있습니다. 이는 application에 따라 달라지며, 특정 validation 패턴과의 chaining이 필요합니다.
DFG의 operationNewRegExpUntyped에서 regExpConstructor를 callee와 newTarget 파라미터 모두에 전달하도록 수정되었습니다. new RegExp(...) 호출 시 newTarget이 반드시 정의되어야 한다는 ECMAScript 명세 요건에 맞춘 변경입니다.
Source/JavaScriptCore/dfg/DFGOperations.cpp
JSGlobalObject* regExpGlobalObject = structure->globalObject();
- OPERATION_RETURN(scope, constructRegExp(regExpGlobalObject, ArgList { args, 2 }, regExpGlobalObject->regExpConstructor()));
+ JSObject* regExpConstructor = regExpGlobalObject->regExpConstructor();
+ OPERATION_RETURN(scope, constructRegExp(regExpGlobalObject, ArgList { args, 2 }, regExpConstructor, regExpConstructor));
JSTests/stress/dfg-miscompiles-new-regexp.js
+function opt(regExp) {
+ return new RegExp(regExp, undefined);
+}
+
+function main() {
+ const regExp = /a/;
+ for (let i = 0; i < testLoopCount; i++) {
+ if (opt(regExp) === regExp) {
+ throw new Error(`Bug triggered at ${i}`);
+ break;
+ }
+ }
+}
+main();
Patch Details
constructRegExp 호출에 인수 하나가 추가되었습니다. 기존에는 regExpGlobalObject, ArgList { args, 2 }, regExpGlobalObject->regExpConstructor() 세 개의 인수가 전달되었습니다. 수정 후에는 동일한 regExpConstructor가 네 번째 인수로 newTarget 파라미터에 전달됩니다. getter를 두 번 호출하지 않기 위해 regExpConstructor는 지역 변수로 추출되었습니다.
Background
JSC는 hot function을 interpreter(LLInt), baseline JIT, DFG(mid-tier optimizing JIT) 순서로 컴파일합니다. NewRegExpUntyped 노드는 DFG bytecode parser가 new RegExp(...) 호출에서 newTarget이 call target과 다를 때 생성합니다. 이는 일반 함수 호출이 아닌 constructor 호출임을 나타냅니다.
ECMAScript §22.2.3.1에 따르면, RegExp가 new 없이 함수로 호출될 때는 패턴이 이미 RegExp이고 flags가 undefined이면 입력 패턴을 그대로 반환하는 것이 허용됩니다. 반면 constructor로 호출될 때(new)는 항상 새로운 RegExp 객체를 생성해야 합니다. 이 차이는 NewTarget이 정의되어 있는지 여부에 달려 있습니다. constructRegExp는 네 번째 파라미터를 newTarget으로 사용하며, 이 파라미터가 없으면 함수 호출 경로를 따르게 됩니다.
Analysis
DFG operation stub에서 newTarget 전파 누락으로 인한 constructor semantics의 함수 호출 semantics 저하.
newTarget이 없으면 constructRegExp는 ES2025 §22.2.3.1의 함수 호출 경로를 따릅니다. 패턴이 이미 RegExp이고 flags가 undefined인 경우, 명세는 동일한 RegExp 객체를 반환하는 것을 허용합니다. 결과적으로 new RegExp(existingRegExp, undefined) 형태의 DFG 컴파일 코드에서 새로운 복사본 대신 원본 객체가 반환될 가능성이 있습니다. 이는 new 연산자가 항상 별개의 객체를 생성해야 한다는 불변 조건을 위반하는 것입니다. Bytecode parser는 commit 메시지에 설명된 대로 newTargetNode != callTargetNode 검사를 통해 이를 new 호출로 올바르게 식별합니다. 다만 이 정보는 operation 경계에서 손실됩니다.
Aaa Aaaa Aaaaaaaa Aaa Aaaaa Aaaaaa Aaaaaaaaaaaa Aaa Aaaaaaaa Aaaa Aaaaaaaaaaaa Aaaa Aa Aaaaa Aaaa a Aaaa Aaa Aaa Aa Aaaaa Aaa Aaaaa Aa Aaa Aaaa Aaa a Aaa Aaa Aaaaaa Aaaa Aa Aaaaa Aaaaaaa Aaa a Aaaaa Aa Aa Aaaaaaaaaaaa Aaaaa Aaa Aaaaa Aa Aa Aaa Aaaa Aaaa Aaaa Aa Aaaa Aaaaaa Aaaaaa Aaa Aaaa Aaaaaaaaaaa Aaaaa Aaaaaa Aaaaa Aaaaaaaaaaaa Aaaaaaaaa Aaa Aa Aaaaa Aaaaaaaaaaaa Aaa Aaaaa Aaaaaa
a Aaaaaaaaaaaaaa Aaa Aaa Aaaa Aaaaa Aaaa Aaaaaa Aaaaaaaa Aaa Aaaaaaa Aa Aaa Aaaaaaaa Aaa Aaaaaaaaaa Aa Aaaaaa Aaaaaaaa Aaa Aa Aaa Aaaaaa Aaaa Aaaaaa Aaaaaaaaaaaa Aaaaaaa Aaaaaaa Aaaa Aaaaa
a Aaa Aaaaa Aaaa Aaaaa Aa Aaaa Aa Aaaaaaaaaa a Aaaa Aaaaaaaaaaaaaa Aaaaaaaaaa Aaaa Aa Aaa Aaaaaaaaa Aaaaaaa Aaa Aaa Aaaaa Aaaaaaaaaaaaaaaaaaaaaaaaa Aaaa Aaaaa Aa Aaaaaaaaaa Aaaaaaaaaaaaaaaaaaa Aaaaaaaaaaaa Aaaaaaaaa Aa Aaa Aaa Aaaaaa
🔒Explores the downstream security implications of object identity confusion and how shared mutable state could be weaponized
더 확인하려면 구독해 주세요
Audit directions
a Aaaaaaa Aaaaaaaaaaa Aaaaaaaaaa Aaaaa Aaaaaaaaaa Aaaa Aaaa Aa Aaaa Aa Aaa Aaaaaaaaa Aaaaa Aaaaaaaaaaaaaaaaaa Aa Aaaaaaaaaaaaaaa Aaaa Aaaaaaaaaaaaaa Aaaaaaa Aaaaaaaaa Aa Aa Aaaa Aaa Aaaaaa Aaaaaaaaaaaaaaaaaaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aaaaa a Aaaaaaaaaaa Aaaaaa Aaa Aaa Aaaaaaaaaa Aaaaa Aaaaaa
a Aaaaaaa Aaa Aaaaaaaa Aaaaaaaa Aaaaaaa Aaaaaaaaa Aaaa Aaa Aaaa Aaaaaaaa Aaaa Aaaaaaaa Aaaaaaa Aa Aaaa Aaaaaaaaaaaaaa Aaa Aaaa Aaaa a Aaaa Aaaaaaa Aaaaaaaaaa Aa Aaaa Aaa Aaa Aaaaa Aaaaa Aaaaaaaaaa Aaaa Aa Aaa Aaaaaaa Aaaaaaa Aaaa Aaaaaaa Aaaa Aaaaaaaaaa Aa Aa Aaa Aaaaa a Aaaaaaaaa Aaaaa Aaaaaaaaaa Aaaa Aaaaa Aaaaaa Aaaaaaaaaaaaaaaaaaaaaaaaa Aaaaaaaaaaaaaaa Aaa Aaaa Aaa Aaaaaa
a Aaaaaaa Aaaaaaaaaaaaaaaaaaaaaaaaa Aaaa Aaaaa Aa Aaaaaaaaaa Aaaaaaaaaaaa Aaaaaaa Aaaaaaaaaaaa Aaaaaaa Aaaaaaaaaaaa Aa Aa Aa a Aaa Aaa Aaaa Aa Aaa Aaaaa Aaaa Aaaaaaaaaaaaaa Aaa Aa Aaaaa Aaaaaa Aaaaaaaa Aaa Aaa Aaaa Aaaa a Aaaaaaaaaaaaa Aa Aa Aaaaaa a Aaaaaaaaaaaa Aaa Aaaaaaaaa Aaaaa Aaa Aaaaaa
🔒Multiple audit patterns identified for DFG call-vs-construct semantic mismatches, with concrete search targets across operation stubs
더 확인하려면 구독해 주세요