Skip to content

Commit 2a885e3

Browse files
committed
Fix MySQLnd possible buffer over read in auth_protocol
1 parent 738c85c commit 2a885e3

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

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

0 commit comments

Comments
 (0)