ARTICLE DETAIL

资讯详情

深耕商务建站与企业官网运营的一线实战洞察。

CVE-2026-109618 和 CVE-2026-109619的修复补丁解读

CVE-2026-109618 和 CVE-2026-109619的修复补丁解读 这份 diff 文件包含了针对 PHP 7.1 的两个高危漏洞CVE-2026-109618和CVE-2026-109619的修复补丁以及相关的安全加固。为了方便你阅读我严格按照文件中的代码块对**每一行发生变化的代码以或-开头**进行了逐行中文注释。1.ext/session/session.c(禁用原生上传进度)-if(!PS(rfc1867_enabled)){if(!PS(rfc1867_enabled)||1){/* Backport CVE-2026-109619 */注释在原来的判断后强行加上|| 1使得这个条件永远为真。效果是直接return彻底禁用了 PHP 原生的session.upload_progress上传进度功能。因为该功能涉及复杂的全局状态官方在修复 CVE-2026-109619 时选择直接将其废弃/关闭以绝后患。2.main/main.c(新增 multipart 限制与清理全局变量)PHP_INI_ENTRY(max_multipart_body_parts,-1,PHP_INI_SYSTEM|PHP_INI_PERDIR,NULL)注释在 PHP 核心配置中注册一个新的 ini 选项max_multipart_body_parts默认值为-1。限制只能在系统级SYSTEM或目录级PERDIR修改不能用ini_set动态修改。for(i0;iNUM_TRACK_VARS;i){zval_ptr_dtor(PG(http_globals)[i]);/* Backport CVE-2026-109619: pode ser acessado antes de php_request_startup() */ZVAL_UNDEF(PG(http_globals)[i]);}注释在请求结束时释放了超全局变量如$_GET,$_POST的内存后必须立刻将其标记为未定义ZVAL_UNDEF。防止下一个请求启动前有代码意外访问造成“释放后使用”UAF漏洞。这段代码在文件里出现了两次对应不同的退出清理路径。3.main/rfc1867.c(收紧文件上传解析边界)staticchar*php_mime_get_hdr_value(zend_llist header,char*key);注释前置声明一个辅助函数用于检查某个 Header头部是否已经在链表中存在。-do{value;}while(isspace(*value));--keyestrdup(line);-smart_string_appends(buf_value,value);/* Backport: manter so cabecalhos usados, ignorar duplicados */if((strcasecmp(line,Content-Disposition)strcasecmp(line,Content-Type))||php_mime_get_hdr_value(*header,line)){keyNULL;}else{keyestrdup(line);do{value;}while(isspace((unsignedchar)*value));smart_string_appends(buf_value,value);}注释解析 Multipart 上传请求的 Header 时只保留Content-Disposition和Content-Type。如果遇到其他无关的 Header或者遇到了重复的 Header通过php_mime_get_hdr_value检查直接把key置为NULL丢弃。这防止了攻击者利用畸形或海量 Header 消耗服务器资源。同时修复了isspace的入参强转类型防止越界。intupload_cntINI_INT(max_file_uploads);intbody_parts_cntINI_INT(max_multipart_body_parts);intbody_parts_limit;注释读取刚才新增的max_multipart_body_parts配置值并声明限制变量。if(body_parts_cnt0){body_parts_cntPG(max_input_vars)upload_cnt;}body_parts_limitbody_parts_cnt;注释如果配置值为-1默认则自动计算上限等于max_input_vars最大表单字段数加上max_file_uploads最大上传文件数。并将计算后的值保存下来用于报错提示。if(--body_parts_cnt0){php_error_docref(NULL,E_WARNING,Multipart body parts limit exceeded %d. To increase the limit change max_multipart_body_parts in php.ini.,body_parts_limit);gotofileupload_done;}注释在循环解析每个字段/文件前计数器减一。如果超出限制小于 0抛出警告E_WARNING然后通过goto直接跳到上传结束的代码块丢弃后续内容。防止单次请求包含海量 part 造成 DoS 攻击。4.main/SAPI.c(清理请求上下文指针)if(SG(request_info).auth_user){efree(SG(request_info).auth_user);SG(request_info).auth_userNULL;}注释在释放用户认证信息auth_user,auth_password,auth_digest、content_type_dup、current_user的内存后必须将指针置为NULL。防止野指针残留到下一个请求中CVE-2026-109619 修复的一部分。5.Zend/zend_alloc.c(修复 OOM 时的致命错误处理)#includezend_execute.h注释引入执行器头文件因为下面新增的报错函数需要调用zend_is_executing()等 API 来获取当前执行的文件名和行号。-exit(1);_exit(1);注释将标准的exit()替换为系统级_exit()。exit()会触发析构函数和缓冲区刷新而_exit()会直接强杀进程不执行任何清理。/* Backport CVE-2026-109618: fatal de memoria sem bailout; encerra o processo */ZEND_API ZEND_COLD ZEND_NORETURNvoidzend_mm_safe_error_ex(constchar*format,...){zend_string*script_filenameNULL;uint32_tscript_lineno0;charbuf[1024];va_list args;if(zend_is_executing()){script_filenamezend_get_executed_filename_ex();script_linenozend_get_executed_lineno();}elseif(zend_is_compiling()){script_filenamezend_get_compiled_filename();script_linenozend_get_compiled_lineno();}va_start(args,format);vsnprintf(buf,sizeof(buf),format,args);va_end(args);fprintf(stderr,\nFatal error: %s in %s on line %d\n,buf,script_filename?ZSTR_VAL(script_filename):Unknown,script_lineno);#ifdef ZEND_WIN32fflush(stderr);#endif_exit(1);}注释新增了一个专门处理内存溢出的函数。它尝试获取报错的文件名和行号格式化错误信息后直接写入系统标准错误stderr然后通过_exit(1)直接杀掉进程不再像以前那样走正常的异常抛出bailout流程。-heap-overflow1;-zend_try{...}zend_catch{...}zend_end_try();-heap-overflow0;-zend_bailout();-exit(1);(void)heap;zend_mm_safe_error_ex(format,...);注释删除了旧版 OOM 处理的复杂逻辑。现在一旦发生 OOM直接调用上面新增的zend_mm_safe_error_ex函数强杀进程。fprintf(stderr,Out of memory\n);-exit(1);_exit(1);注释同样针对系统级别真正的 OOM将退出方式改为强杀_exit。6.Zend/zend_alloc.h(函数声明)ZEND_API ZEND_COLD ZEND_NORETURNvoidzend_mm_safe_error_ex(constchar*format,...);注释在头文件中声明新增的 OOM 处理函数以便其他 C 文件可以调用它。7.Zend/zend_execute_API.c(清理执行器全局状态 - 核心修复)/* Backport CVE-2026-109619: estado que pode ser acessado antes de init_executor */ZVAL_UNDEF(EG(user_error_handler));ZVAL_UNDEF(EG(user_exception_handler));memset(EG(user_error_handlers_error_reporting),0,sizeof(EG(user_error_handlers_error_reporting)));memset(EG(user_error_handlers),0,sizeof(EG(user_error_handlers)));memset(EG(user_exception_handlers),0,sizeof(EG(user_exception_handlers)));EG(objects_store).object_bucketsNULL;EG(objects_store).top1;EG(error_handling)EH_NORMAL;EG(exception)NULL;注释这段是修复 CVE-2026-109619 的核心。在请求结束清理执行器Executor时强制重置所有与错误处理、异常处理、对象池相关的全局状态。清空或置空这些变量确保下一个请求或者在异常退出后不会读取到上一个请求残留的“脏数据”指针。8.Zend/zend_llist.c(清理链表残留)l-headNULL;l-tailNULL;l-count0;注释在清空双向链表时除了将计数置为 0还要把链表的头指针head和尾指针tail显式置为NULL防止悬挂指针。地址https://github.com/vperetti/php-cve-2026-109618-109619-backports使用方法https://blog.csdn.net/liuruiaaa/article/details/168773241
返回列表
PREV
查看更多资讯
NEXT
返回资讯列表