Apache 2.4报ajp_msg_append_cvt_string溢出,咨询msg->max_size来源及修复方法
AJP消息max_size字段来源与溢出报错修复方案
max_size的来源
ajp_msg_t结构体的max_size字段是AJP消息缓冲区的最大容量,在消息对象初始化时就已经确定- 初始化逻辑位于
ajp_msg_create()函数中,AJP协议默认的标准包大小为8192字节,默认初始化时max_size就会被设为这个值,同时会分配对应大小的内存缓冲区 - 如果你使用的是mod_proxy_ajp模块连接Tomcat等后端服务,这个值还和两端的AJP连接器配置绑定,两端的包大小配置必须保持一致
溢出报错原因与修复方案
你遇到的ajp_msg_append_cvt_string(): BufferOverflowException 4 8186报错,意思是当前消息已经使用了4字节,剩余可用空间为8186字节,要追加的内容算上长度标识和结束符之后超过了剩余空间,触发了缓冲区溢出校验。
修复方式有两种:
- 优先排查业务侧超长内容:检查是否存在超大的Cookie、超长的自定义请求头、过大的GET参数,这类内容会被写入AJP消息中,超过默认8K的限制,优化这些内容的长度即可解决问题,不需要修改服务配置。
- 调整AJP包大小配置:如果确实需要传递大内容,可以同时调整Apache和后端的AJP配置:
- Apache侧在
httpd.conf的对应ProxyPass配置项后添加max-packet-size=65536,最大支持设置为65536(64K) - 后端Tomcat侧在
server.xml的AJP Connector配置中添加属性packetSize="65536",必须和Apache侧配置完全一致,否则会出现报文解析错误
- Apache侧在
相关源码参考
/* * Add a String in AJP message, and transform the String in ASCII * if convert is set and we're on an EBCDIC machine * * @param msg AJP Message to get value from * @param value Pointer to String * @param convert When set told to convert String to ASCII * @return APR_SUCCESS or error */ apr_status_t ajp_msg_append_string_ex(ajp_msg_t *msg, const char *value, int convert) { apr_size_t len; if (value == NULL) { return(ajp_msg_append_uint16(msg, 0xFFFF)); } len = strlen(value); if ((msg->len + len + 3) > msg->max_size) { return ajp_log_overflow(msg, "ajp_msg_append_cvt_string"); } /* ignore error - we checked once */ ajp_msg_append_uint16(msg, (apr_uint16_t)len); /* We checked for space !! */ memcpy(msg->buf + msg->len, value, len + 1); /* including \0 */ if (convert) { /* convert from EBCDIC if needed */ ap_xlate_proto_to_ascii((char *)msg->buf + msg->len, len + 1); } msg->len += len + 1; return APR_SUCCESS; }
内容的提问来源于stack exchange,提问作者Vinay Tiwari
相关产品推荐
相关产品推荐

