Skip to content

Commit 61d4e45

Browse files
committed
Modify multipart_complete for incomplete final boundary
1 parent cb95a24 commit 61d4e45

File tree

1 file changed

+56
-45
lines changed

1 file changed

+56
-45
lines changed

apache2/msc_multipart.c

Lines changed: 56 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1044,59 +1044,70 @@ int multipart_complete(modsec_rec *msr, char **error_msg) {
10441044
* [CRLF epilogue]
10451045
*/
10461046
unsigned int buf_data_len = (unsigned int)(MULTIPART_BUF_SIZE - msr->mpd->bufleft);
1047-
size_t final_boundary_len = 4 + strlen(msr->mpd->boundary);
1048-
if ( (buf_data_len >= final_boundary_len)
1047+
size_t boundary_len = strlen(msr->mpd->boundary);
1048+
if ( (buf_data_len >= 2 + boundary_len)
10491049
&& (*(msr->mpd->buf) == '-')
10501050
&& (*(msr->mpd->buf + 1) == '-')
1051-
&& (strncmp(msr->mpd->buf + 2, msr->mpd->boundary, strlen(msr->mpd->boundary)) == 0)
1052-
&& (*(msr->mpd->buf + 2 + strlen(msr->mpd->boundary)) == '-')
1053-
&& (*(msr->mpd->buf + 2 + strlen(msr->mpd->boundary) + 1) == '-') )
1051+
&& (strncmp(msr->mpd->buf + 2, msr->mpd->boundary, boundary_len) == 0) )
10541052
{
1055-
/* If body fits in limit and ends with final boundary plus just CR, reject it. */
1056-
if ( (msr->mpd->allow_process_partial == 0)
1057-
&& (buf_data_len == final_boundary_len + 1)
1058-
&& (*(msr->mpd->buf + final_boundary_len) == '\r') )
1053+
if ( (buf_data_len >= 2 + boundary_len + 2)
1054+
&& (*(msr->mpd->buf + 2 + boundary_len) == '-')
1055+
&& (*(msr->mpd->buf + 2 + boundary_len + 1) == '-') )
10591056
{
1060-
*error_msg = apr_psprintf(msr->mp, "Multipart: Invalid epilogue after final boundary.");
1061-
return -1;
1062-
}
1057+
/* If body fits in limit and ends with final boundary plus just CR, reject it. */
1058+
if ( (msr->mpd->allow_process_partial == 0)
1059+
&& (buf_data_len == 2 + boundary_len + 2 + 1)
1060+
&& (*(msr->mpd->buf + 2 + boundary_len + 2) == '\r') )
1061+
{
1062+
*error_msg = apr_psprintf(msr->mp, "Multipart: Invalid epilogue after final boundary.");
1063+
return -1;
1064+
}
10631065

1064-
if ((msr->mpd->crlf_state_buf_end == 2) && (msr->mpd->flag_lf_line != 1)) {
1065-
msr->mpd->flag_lf_line = 1;
1066-
if (msr->mpd->flag_crlf_line) {
1067-
msr_log(msr, 4, "Multipart: Warning: mixed line endings used (CRLF/LF).");
1068-
} else {
1069-
msr_log(msr, 4, "Multipart: Warning: incorrect line endings used (LF).");
1066+
if ((msr->mpd->crlf_state_buf_end == 2) && (msr->mpd->flag_lf_line != 1)) {
1067+
msr->mpd->flag_lf_line = 1;
1068+
if (msr->mpd->flag_crlf_line) {
1069+
msr_log(msr, 4, "Multipart: Warning: mixed line endings used (CRLF/LF).");
1070+
} else {
1071+
msr_log(msr, 4, "Multipart: Warning: incorrect line endings used (LF).");
1072+
}
10701073
}
1074+
if (msr->mpd->mpp_substate_part_data_read == 0) {
1075+
/* it looks like the final boundary, but it's where part data should begin */
1076+
msr->mpd->flag_invalid_part = 1;
1077+
msr_log(msr, 4, "Multipart: Warning: Invalid part (data contains final boundary)");
1078+
}
1079+
/* Looks like the final boundary - process it. */
1080+
if (multipart_process_boundary(msr, 1 /* final */, error_msg) < 0) {
1081+
msr->mpd->flag_error = 1;
1082+
return -1;
1083+
}
1084+
1085+
/* The payload is complete after all. */
1086+
msr->mpd->is_complete = 1;
10711087
}
1072-
if (msr->mpd->mpp_substate_part_data_read == 0) {
1073-
/* it looks like the final boundary, but it's where part data should begin */
1074-
msr->mpd->flag_invalid_part = 1;
1075-
msr_log(msr, 4, "Multipart: Warning: Invalid part (data contains final boundary)");
1076-
}
1077-
/* Looks like the final boundary - process it. */
1078-
if (multipart_process_boundary(msr, 1 /* final */, error_msg) < 0) {
1079-
msr->mpd->flag_error = 1;
1080-
return -1;
1081-
}
1088+
else if (msr->mpd->allow_process_partial == 1) {
1089+
int is_final = 0;
1090+
if (buf_data_len >= 2 + boundary_len + 1) {
1091+
if (*(msr->mpd->buf + 2 + boundary_len) == '-') {
1092+
if ( (buf_data_len >= 2 + boundary_len + 2)
1093+
&& (*(msr->mpd->buf + 2 + boundary_len + 1) != '-') ) {
1094+
*error_msg = apr_psprintf(msr->mp, "Multipart: Invalid final boundary.");
1095+
return -1;
1096+
}
1097+
is_final = 1;
1098+
}
1099+
else if ( (*(msr->mpd->buf + 2 + boundary_len) != '\r')
1100+
|| ((buf_data_len >= 2 + boundary_len + 2)
1101+
&& (*(msr->mpd->buf + 2 + boundary_len + 1) != '\n')) ) {
1102+
*error_msg = apr_psprintf(msr->mp, "Multipart: Invalid boundary.");
1103+
return -1;
1104+
}
1105+
}
10821106

1083-
/* The payload is complete after all. */
1084-
msr->mpd->is_complete = 1;
1085-
}
1086-
else if (msr->mpd->allow_process_partial == 1
1087-
&& (buf_data_len >= 2 + strlen(msr->mpd->boundary))
1088-
&& (*(msr->mpd->buf) == '-')
1089-
&& (*(msr->mpd->buf + 1) == '-')
1090-
&& (strncmp(msr->mpd->buf + 2, msr->mpd->boundary, strlen(msr->mpd->boundary)) == 0) )
1091-
{
1092-
if ( ((buf_data_len >= 3 + strlen(msr->mpd->boundary))
1093-
&& ((*(msr->mpd->buf + 2 + strlen(msr->mpd->boundary)) != '-')
1094-
&& (*(msr->mpd->buf + 2 + strlen(msr->mpd->boundary)) != '\r')))
1095-
|| ((buf_data_len >= final_boundary_len)
1096-
&& *(msr->mpd->buf + 2 + strlen(msr->mpd->boundary) + 1) != '-') )
1097-
{
1098-
*error_msg = apr_psprintf(msr->mp, "Multipart: Invalid final boundary.");
1099-
return -1;
1107+
if (multipart_process_boundary(msr, is_final, error_msg) < 0) {
1108+
msr->mpd->flag_error = 1;
1109+
return -1;
1110+
}
11001111
}
11011112
}
11021113
}

0 commit comments

Comments
 (0)