Hi Wlad,
On 09/05/2011 21:37, Vladislav Vaintroub wrote:
> I think the analysis is not completely correct here.
>
> The way Windows authentication works is such that0) Server sends
> welcome packet. 1) client sends client authentication packet that
> contains authentication method but without payload. 2) then server
> sends UPN to client 3) then client puts UPN into
> InitializeSecurityContext() and sends the resulting blob to server.
> (following steps omitted)
>
> The 255 limit is would be a limit in step 1). But since payload is
> not used in this step , there is also no limit.
My understanding is different. Basically, the UPN sent first by server
is wrapped in the welcome packet already and then the first
authentication payload from client is wrapped inside the normal client
authentication packet (in hope that all will be settled during this
standard, 2 packet sequence). I included my analysis in bug#11878962 -
please review it to see if I made some mistakes. So far Joro, who wrote
the code, has confirmed that it is a problem so I assumed my analysis is
correct.
Rafal
---- analysis from bug#11878962 ----------
A client which uses authentication plugin can send arbitrary data to the
server-side plugin using
MYSQL_PLUGIN_VIO::write_packet(vio, ucchar *buf, int buf_len).
When this method is called first time (see client_mpvio_write_packet()
in client.c:2680), the data is wrapped into a client authentication
packet (send_client_reply_packet() in client.c:2450).
In the client authentication packet, the data payload is represented as
a length coded string of bytes with the first byte containing length.
Thus length of the payload is limited to 255 bytes. However, there are
no checks in the code which would prevent client from trying to send
more than 255 bytes using MYSQL_PLUGIN_VIO::write_packet().
If client tries to do so, then send_client_reply_packet() will execute
the following code (where end points at the end of the constructed packet):
if (data_len)
{
if (mysql->server_capabilities & CLIENT_SECURE_CONNECTION)
{
*end++= data_len;
memcpy(end, data, data_len);
end+= data_len;
}
...
Since the size field is 1 byte, the length stored in the packet will be
different from data_len, if data_len > 256. Nevertheless, all the data
will be appended to the packet without noticing this. A receiver of such
a packet will interpret it wrongly which can lead to unpredictable
behavior (probably crash).