Bug #31588 | buffer overrun when setting variables | ||
---|---|---|---|
Submitted: | 14 Oct 2007 15:31 | Modified: | 30 Oct 2007 1:00 |
Reporter: | Shane Bester (Platinum Quality Contributor) | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | MySQL Server: General | Severity: | S1 (Critical) |
Version: | 5.0.50, 5.1.23 | OS: | Any |
Assigned to: | Tatiana Azundris Nuernberg | CPU Architecture: | Any |
Tags: | buffer overrun |
[14 Oct 2007 15:31]
Shane Bester
[16 Oct 2007 13:31]
Tatiana Azundris Nuernberg
Analysis is indeed cqt. strmake(dst, src, len) copies over up to len characters, then appends '\0' if needed, so sizeof(dst) must be len + 1, or, conversely, len = sizeof(dst) -1. str incidently gets alloc'd in check_set() as its buffer is exactly full (STRING_BUFFER_USUAL_SIZE characters 'a') when we call c_ptr(), forcing a re-alloc for that size + 1 (to accommodate a terminating '\0'), plus alignment. To make things a little more interestring, if (!(res= var->value->val_str(&str))) uses str for value-length up to and including STRING_BUFFER_USUAL_SIZE (payload, not counting '\0'), so for < S/B/U/S, everything is correct, for > S/B/U/S res has its own buffer (We still overrun 'buff', but we call c_ptr() on res, not str, so str never gets realloc'd, and consequently, we don't try to free it when it goes out of scope. The overrunning of 'buff' still ends up destroying the pointer of str, but since we do not try to dealloc the broken address, we get a lucky escape thanks to the stack-layout.). It's only for == S/B/U/S that we get a re-alloc for str, an overrun of buff that destroys str's pointer, and a subsequent complaint when we try to free that pointer when str goes out of scope. Ah, what fun.
[16 Oct 2007 13:47]
Tatiana Azundris Nuernberg
On a side-note, we can safely strmake(buff, error, min(sizeof(buff) - 1, error_len)); because a) we already limited the size before (if off by one), so the behaviour, at least in spirit, does not change; and b) for current settings, that makes the buffer 79+1 characters, while the error-message limits the string to 64 characters anyway. : )
[17 Oct 2007 11:28]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/35746 ChangeSet@1.2536, 2007-10-17 13:29:18+02:00, tnurnberg@sin.intern.azundris.com +3 -0 Bug#31588: buffer overrun when setting variables Buffer used when setting variables was not dimensioned to accomodate trailing '\0'. An overflow by one character was therefore possible. CS corrects limits to prevent such overflows. The actual error message using this buffered value only prints the first 64 characters of it anyway, so this causes no change visible to the user at this point.
[18 Oct 2007 8:46]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/35816 ChangeSet@1.2686, 2007-10-18 10:47:54+02:00, tnurnberg@sin.intern.azundris.com +3 -0 Bug#31588: buffer overrun when setting variables Buffer used when setting variables was not dimensioned to accomodate trailing '\0'. An overflow by one character was therefore possible. CS corrects limits to prevent such overflows.
[22 Oct 2007 13:42]
Tatiana Azundris Nuernberg
- pushed to 4.1.24, 5.0.52, 5.1.23 in opt - Code review suggestion added as Bug#31752
[29 Oct 2007 8:40]
Bugs System
Pushed into 4.1.24
[29 Oct 2007 8:43]
Bugs System
Pushed into 5.0.52
[29 Oct 2007 8:47]
Bugs System
Pushed into 5.1.23-beta
[29 Oct 2007 8:51]
Bugs System
Pushed into 6.0.4-alpha
[30 Oct 2007 1:00]
Paul DuBois
Noted in 4.1.24, 5.0.52, 5.1.23, 6.0.4 changelogs. A buffer used when setting variables was not dimensioned to accommodate the trailing '\0' byte, so a single-byte buffer overrun was possible.