BUG #19422: Malformed raius packet
The following bug has been logged on the website:
Bug reference: 19422
Logged by: Stanislav Osipov
Email address: stasos24@gmail.com
PostgreSQL version: 18.3
Operating system: Ubuntu 22
Description:
User can create malformed radius packet by sending username, which length is
253
This is would lead to overwriting raidius attributes without causing
security consequences
Due to calling radius_add_attribute at PerformRadiusTransaction:
[https://github.com/postgres/postgres/blob/386ca3908de28dd882a62b8f97a329db07b23138/src/backend/libpq/auth.c#L3012]
radius_add_attribute(packet, RADIUS_USER_NAME, (const unsigned char *)
user_name, strlen(user_name));
[https://github.com/postgres/postgres/blob/386ca3908de28dd882a62b8f97a329db07b23138/src/backend/libpq/auth.c#L2828]
{...
attr = (radius_attribute *) ((unsigned char *) packet +
packet->length);
attr->attribute = type;
attr->length = len + 2; /* total size includes type and
length */
memcpy(attr->data, data, len);
packet->length += attr->length;
}
User may overflow attr->length (uint8) by sending user_name with length of
254 that would led to overwriting user_name attribute and to incorrect
computation of packet->length by next call of radius_add_attribute
[https://github.com/postgres/postgres/blob/386ca3908de28dd882a62b8f97a329db07b23138/src/backend/libpq/auth.c#L3013]
Even though it overflows only in bounds of array, it may have negative
affect in the future.
On Mon, Mar 02, 2026 at 09:04:14AM +0000, PG Bug reporting form wrote:
User may overflow attr->length (uint8) by sending user_name with length of
254 that would led to overwriting user_name attribute and to incorrect
computation of packet->length by next call of radius_add_attribute
[https://github.com/postgres/postgres/blob/386ca3908de28dd882a62b8f97a329db07b23138/src/backend/libpq/auth.c#L3013]
Even though it overflows only in bounds of array, it may have negative
affect in the future.
Fun, due to the increment of 2 added a couple of lines down. There is
an overflow calculation. There is nothing critical here.
Looking at RFC 2865, there is nothing about a limit of size for the
attributes. This means that we are only limited by our
RADIUS_BUFFER_SIZE. Hence, we could bump radius_attribute.length to
uint16 and add some casts in the check for RADIUS_BUFFER_SIZE so as
we don't overflow the addition before adding an attribute to the
packet? On the other hand, we could aim for simpler and just reject
any attributes larger than 255 bytes. I doubt that anybody would be
insane enough to use fields larger than that 255 bytes anyway. Both
solutions are equal in simplicity here.
Thoughts?
--
Michael
On Tue, Mar 03, 2026 at 04:20:37PM +0900, Michael Paquier wrote:
Looking at RFC 2865, there is nothing about a limit of size for the
attributes. This means that we are only limited by our
RADIUS_BUFFER_SIZE. Hence, we could bump radius_attribute.length to
uint16 and add some casts in the check for RADIUS_BUFFER_SIZE so as
we don't overflow the addition before adding an attribute to the
packet? On the other hand, we could aim for simpler and just reject
any attributes larger than 255 bytes. I doubt that anybody would be
insane enough to use fields larger than that 255 bytes anyway. Both
solutions are equal in simplicity here.
It is worth noting that RADIUS support has been removed as of Postgres
19 in commit a1643d40b308, so I doubt that we need to take any action
here.
Or would somebody be interested enough to send a patch?
--
Michael