Fix buffer overread in preloaded hostuuid parsing
Commit b6be9566d2
stopped prison0_init writing outside of the
preloaded hostuuid's bounds. However, the preloaded data will not
(normally) have a NUL in it, and so validate_uuid will walk off the end
of the buffer in its call to sscanf. Previously if there was any
whitespace in the string we'd at least know there's a NUL one past the
end due to the off-by-one error, but now no such byte is guaranteed.
Fix this by copying to a temporary buffer and explicitly adding a NUL.
Whilst here, change the strlcpy call to use a far less suspicious
argument for dstsize; in practice it's fine, but it's an unusual pattern
and not necessary.
Found by: CHERI
Reviewed by: emaste, kevans, jhb
MFC after: 1 week
Differential Revision: https://reviews.freebsd.org/D33616
This commit is contained in:
parent
221376db0c
commit
d2ef377430
@ -239,6 +239,8 @@ prison0_init(void)
|
||||
{
|
||||
uint8_t *file, *data;
|
||||
size_t size;
|
||||
char buf[sizeof(prison0.pr_hostuuid)];
|
||||
bool valid;
|
||||
|
||||
prison0.pr_cpuset = cpuset_ref(thread0.td_cpuset);
|
||||
prison0.pr_osreldate = osreldate;
|
||||
@ -258,10 +260,31 @@ prison0_init(void)
|
||||
while (size > 0 && data[size - 1] <= 0x20) {
|
||||
size--;
|
||||
}
|
||||
if (validate_uuid(data, size, NULL, 0) == 0) {
|
||||
(void)strlcpy(prison0.pr_hostuuid, data,
|
||||
size + 1);
|
||||
} else if (bootverbose) {
|
||||
|
||||
valid = false;
|
||||
|
||||
/*
|
||||
* Not NUL-terminated when passed from loader, but
|
||||
* validate_uuid requires that due to using sscanf (as
|
||||
* does the subsequent strlcpy, since it still reads
|
||||
* past the given size to return the true length);
|
||||
* bounce to a temporary buffer to fix.
|
||||
*/
|
||||
if (size >= sizeof(buf))
|
||||
goto done;
|
||||
|
||||
memcpy(buf, data, size);
|
||||
buf[size] = '\0';
|
||||
|
||||
if (validate_uuid(buf, size, NULL, 0) != 0)
|
||||
goto done;
|
||||
|
||||
valid = true;
|
||||
(void)strlcpy(prison0.pr_hostuuid, buf,
|
||||
sizeof(prison0.pr_hostuuid));
|
||||
|
||||
done:
|
||||
if (bootverbose && !valid) {
|
||||
printf("hostuuid: preload data malformed: '%.*s'\n",
|
||||
(int)size, data);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user