论坛首页 漏洞分析研究区 阅读主题

[原创] CVE-2023-4069:Maglev图建立阶段的一个漏洞

57 浏览 2 回复
#1 楼主 2026-06-01 21:09:20
issue链接:f48K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6A6M7%4y4#2k6i4y4Q4x3X3g2U0K9s2u0G2L8h3W2#2L8g2)9J5k6h3!0J5k6#2)9J5c8X3W2K6M7%4g2W2M7#2)9J5c8U0b7H3x3o6j5%4y4e0x3H3baaK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6U0K9s2u0G2L8h3W2#2L8g2)9J5k6s2u0W2N6X3W2W2N6#2)9J5k6h3N6G2L8$3N6D9k6i4y4G2N6i4u0U0k6g2)9J5k6h3y4G2L8g2)9J5c8X3y4Q4x3V1k6$3z5q4)9J5c8Y4j5^5i4K6u0r3i4K6u0n7i4K6u0r3y4o6j5&6y4o6l9H3y4H3`.`.revision commit hash : 36dK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6U0K9s2u0G2L8h3W2#2L8g2)9J5k6h3N6G2L8$3N6D9k6i4y4G2N6i4u0U0k6g2)9J5k6h3y4G2L8g2)9J5c8Y4j5^5i4K6u0r3N6U0S2Q4x3V1k6Q4x3V1u0Q4x3V1k6W2k6o6V1K6j5X3g2X3y4$3q4T1y4K6R3$3k6o6f1K6y4U0N6U0x3X3q4W2y4K6R3^5x3U0V1J5x3X3x3J5x3$3q4S2x3r3g2V1j5e0j5@1diff链接:338K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6U0K9s2u0G2L8h3W2#2L8g2)9J5k6h3N6G2L8$3N6D9k6i4y4G2N6i4u0U0k6g2)9J5k6h3y4G2L8g2)9J5c8Y4j5^5i4K6u0r3N6U0S2Q4x3V1k6Q4x3V1u0Q4x3V1k6W2k6o6V1K6j5X3g2X3y4$3q4T1y4K6R3$3k6o6f1K6y4U0N6U0x3X3q4W2y4K6R3^5x3U0V1J5x3X3x3J5x3$3q4S2x3r3g2V1j5e0j5@1i4K6t1#2y4f1g2Q4x3U0f1J5x3g2)9J5c8R3`.`.Reflect.construct()函数原型参数使用实例FastNewObject的实现代码,位于src/builtins/builtins-constructor-gen.cc首先获取上下文环境,其中包括target和new_target,接着定义一个call_runtime的label,如果快速路径分配失败,则会通过这个label跳转到慢速路径进行对象分配。调用FastNewObject进入快速路径,如果快速路径分配失败,则会跳转到BIND(&call_runtime),然后执行Runtime::kNewObject,进入慢速路径的分配对于慢速路径的runtime函数可以在vscode里全局搜索RUNTIME_FUNCTION(Runtime_xxxxx,这里的xxxxx代表函数名,上方的kNewObject,那么就用这里的函数名应该是NewObject,所以就可以搜索RUNTIME_FUNCTION(Runtime_NewObject)这里是全部完整的代码,位于src/builtins/builtins-constructor-gen.cc分开看,首先判断new_target_func是不是JSFunction,不是就进入call_runtime的逻辑,和前面定义的Label call_runtime(this)对应上了,这里对应的是慢速路径接着先获取new_target的inital map,然后判断new_target_func的initial_map是否是smi,因为如果是map类型,那么必然不会是smi,所以如果是smi,就会进入call_runtime的逻辑,然后将initial_map_or_proto转换为HeapObject判断是否为map类型,如果不是,那么就进入call_runtime的逻辑,这里验证的这个initial map是否真的存在GotoIf(TaggedIsSmi(initial_map_or_proto), call_runtime) 等价于if( TaggedIsSmi(initial_map_or_proto) ){call_runtime}
简化一下就是GotoIf(A,B);{C};等价于if(A){B}else{C};从initial map上load constructor,然后判断new_target的constructor和target是否一致TVARIABLE(HeapObject, properties),这里的T代表Turbofan ,后面VARIABLE表示变量声明,类型是HeapObject,变量名称是properties下面的逻辑会根据map的不同类型进行跳转如果map的类型是DictionaryMap,那么会直接跳转到BIND(&allocate_properties),然后V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL编译选项是否开启,为properties采用不同的内存分配,接着会跳转到BIND(&instantiate_map),为map进行内存分配如果map的类型不是DictionaryMap,那么会直接为properties分配,接着跳转到BIND(&instantiate_map)处,为map进行内存分配下面总结一下,成功进行快速对象分配的条件是当快速路径分配失败的时候,会通过Label call_runtime(this)跳转到BIND(&call_runtime),也就是执行这个语句TailCallRuntime(Runtime::kNewObject, context, target, new_target);Runtime::kNewObject 是一个枚举值,定义在 src/runtime/runtime.h 中。这个枚举值对应的是 Runtime_NewObject 函数,定义在 src/runtime/runtime-object.cc 中。这个函数的流程比较简单,获取当前的隔离实例,检查参数个数,获取target和new_target,最后将参数传递并调用JSObject::NewJSObject::New() 的源码位于src/objects/js-objects.cc,函数体开始的注释是对于new_target的所有可能性的说明,接着是一些DCHECK,可以看到target被命名成了constructor,new_target还是没有变化调用JSFunction::GetDerivedMap来获取initial_map,然后根据V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL编译选项设置initial_capacity,最后调用NewFastOrSlow

...(已截断)

---
来源: 看雪论坛
原文链接: https://bbs.kanxue.com/thread-287523.htm
#2 2026-06-01 21:09:20
感谢分享,高质量文章,写的很全面~
#3 2026-06-01 21:09:20
感谢分享

请登录后参与讨论

立即登录 注册账号