Skip to content

Commit 32f905f

Browse files
committed
Fix MySQLnd possible buffer over read in auth_protocol
1 parent 7dd336a commit 32f905f

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
@@ -447,8 +447,31 @@ php_mysqlnd_greet_read(MYSQLND_CONN_DATA * conn, void * _packet)
447447
if (packet->server_capabilities & CLIENT_PLUGIN_AUTH) {
448448
BAIL_IF_NO_MORE_DATA;
449449
/* The server is 5.5.x and supports authentication plugins */
450-
packet->auth_protocol = estrdup((char *)p);
451-
p+= strlen(packet->auth_protocol) + 1; /* eat the '\0' */
450+
size_t remaining_size = packet->header.size - (size_t)(p - buf);
451+
if (remaining_size == 0) {
452+
/* Might be better to fail but this will fail anyway */
453+
packet->auth_protocol = estrdup("");
454+
} else {
455+
/* Check if NUL present */
456+
char *null_terminator = memchr(p, '\0', remaining_size);
457+
size_t auth_protocol_len;
458+
if (null_terminator) {
459+
/* If present, do basically estrdup */
460+
auth_protocol_len = null_terminator - (char *)p;
461+
} else {
462+
/* If not present, copy the rest of the buffer */
463+
auth_protocol_len = remaining_size;
464+
}
465+
char *auth_protocol = emalloc(auth_protocol_len + 1);
466+
memcpy(auth_protocol, p, auth_protocol_len);
467+
auth_protocol[auth_protocol_len] = '\0';
468+
packet->auth_protocol = auth_protocol;
469+
470+
p += auth_protocol_len;
471+
if (null_terminator) {
472+
p++;
473+
}
474+
}
452475
}
453476

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

0 commit comments

Comments
 (0)