Skip to content

Commit fd4d65b

Browse files
bukkaSakiTakamachi
authored andcommitted
Fix MySQLnd possible buffer over read in auth_protocol
1 parent 48b9bcd commit fd4d65b

File tree

1 file changed

+25
-2
lines changed

1 file changed

+25
-2
lines changed

ext/mysqlnd/mysqlnd_wireprotocol.c

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -455,8 +455,31 @@ php_mysqlnd_greet_read(MYSQLND_CONN_DATA * conn, void * _packet)
455455
if (packet->server_capabilities & CLIENT_PLUGIN_AUTH) {
456456
BAIL_IF_NO_MORE_DATA;
457457
/* The server is 5.5.x and supports authentication plugins */
458-
packet->auth_protocol = estrdup((char *)p);
459-
p+= strlen(packet->auth_protocol) + 1; /* eat the '\0' */
458+
size_t remaining_size = packet->header.size - (size_t)(p - buf);
459+
if (remaining_size == 0) {
460+
/* Might be better to fail but this will fail anyway */
461+
packet->auth_protocol = estrdup("");
462+
} else {
463+
/* Check if NUL present */
464+
char *null_terminator = memchr(p, '\0', remaining_size);
465+
size_t auth_protocol_len;
466+
if (null_terminator) {
467+
/* If present, do basically estrdup */
468+
auth_protocol_len = null_terminator - (char *)p;
469+
} else {
470+
/* If not present, copy the rest of the buffer */
471+
auth_protocol_len = remaining_size;
472+
}
473+
char *auth_protocol = emalloc(auth_protocol_len + 1);
474+
memcpy(auth_protocol, p, auth_protocol_len);
475+
auth_protocol[auth_protocol_len] = '\0';
476+
packet->auth_protocol = auth_protocol;
477+
478+
p += auth_protocol_len;
479+
if (null_terminator) {
480+
p++;
481+
}
482+
}
460483
}
461484

462485
DBG_INF_FMT("proto=%u server=%s thread_id=%u",

0 commit comments

Comments
 (0)