Skip to content

Commit 6a8d02e

Browse files
committed
bound binary-protocol datetime/time parameter reads to the declared length
get_param_length() guarantees only `length` bytes for a prepared-statement parameter value sent over the binary protocol. set_param_datetime() reads to[4..6] when length > 4 (needs 7 bytes) and sint4korr(to+7) when length > 7 (needs 11); set_param_time() reads sint4korr(to+8) when length > 8 (needs 12). A client that sends an off-spec datetime length of 5, 6, 8, 9 or 10, or a time length of 9, 10 or 11, makes the server read up to 3 bytes past the validated value, an out-of-bounds read when the value ends at the packet buffer boundary. Gate the optional time and microsecond reads on the canonical encoding lengths (>= 7 and >= 11 for datetime, >= 12 for time) so a short value falls back to the next-shorter form instead of over-reading. Well-formed values (datetime 4/7/11, time 8/12) parse exactly as before.
1 parent 8eda901 commit 6a8d02e

1 file changed

Lines changed: 3 additions & 3 deletions

File tree

sql/sql_prepare.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -578,7 +578,7 @@ void Item_param::set_param_time(uchar **pos, ulong len)
578578
tm.hour= (uint) to[5] + day * 24;
579579
tm.minute= (uint) to[6];
580580
tm.second= (uint) to[7];
581-
tm.second_part= (length > 8) ? (ulong) sint4korr(to+8) : 0;
581+
tm.second_part= (length >= 12) ? (ulong) sint4korr(to+8) : 0;
582582
if (tm.hour > 838)
583583
{
584584
/* TODO: add warning 'Data truncated' here */
@@ -607,7 +607,7 @@ void Item_param::set_param_datetime(uchar **pos, ulong len)
607607
tm.year= (uint) sint2korr(to);
608608
tm.month= (uint) to[2];
609609
tm.day= (uint) to[3];
610-
if (length > 4)
610+
if (length >= 7)
611611
{
612612
tm.hour= (uint) to[4];
613613
tm.minute= (uint) to[5];
@@ -616,7 +616,7 @@ void Item_param::set_param_datetime(uchar **pos, ulong len)
616616
else
617617
tm.hour= tm.minute= tm.second= 0;
618618

619-
tm.second_part= (length > 7) ? (ulong) sint4korr(to+7) : 0;
619+
tm.second_part= (length >= 11) ? (ulong) sint4korr(to+7) : 0;
620620
}
621621
else
622622
set_zero_time(&tm, MYSQL_TIMESTAMP_DATETIME);

0 commit comments

Comments
 (0)