[Bug 206648] Fix double strlen in ktrstruct
bugzilla-noreply at freebsd.org
bugzilla-noreply at freebsd.org
Tue Jan 26 17:29:06 UTC 2016
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=206648
Bug ID: 206648
Summary: Fix double strlen in ktrstruct
Product: Base System
Version: 11.0-CURRENT
Hardware: Any
OS: Any
Status: New
Severity: Affects Many People
Priority: ---
Component: kern
Assignee: freebsd-bugs at FreeBSD.org
Reporter: ecturt at gmail.com
The `ktrstruct` function from `sys/kern/kern_ktrace.c` was calling `strlen` on
`name` twice, which could have lead to a race attack (contents of `name`
changed between these two calls). I've verified that this wasn't previously
optimised into a single call to `strlen` in a compiled kernel.
There is no way to exploit this bug since it is only used by macros which pass
strings with static contents:
#define ktrsockaddr(s) \
ktrstruct("sockaddr", (s), ((struct sockaddr *)(s))->sa_len)
#define ktrstat(s) \
ktrstruct("stat", (s), sizeof(struct stat))
However, this situation is fragile, and should be patched to prevent the
possibility of being exploited in the future if ever `ktrstruct` is passed a
non-static name. At the very least, this patch will also be a very minor
optimisation.
Current:
void
ktrstruct(name, data, datalen)
const char *name;
void *data;
size_t datalen;
{
struct ktr_request *req;
char *buf = NULL;
size_t buflen;
if (!data)
datalen = 0;
buflen = strlen(name) + 1 + datalen;
buf = malloc(buflen, M_KTRACE, M_WAITOK);
strcpy(buf, name);
bcopy(data, buf + strlen(name) + 1, datalen);
if ((req = ktr_getrequest(KTR_STRUCT)) == NULL) {
free(buf, M_KTRACE);
return;
}
req->ktr_buffer = buf;
req->ktr_header.ktr_len = buflen;
ktr_submitrequest(curthread, req);
}
Patched:
void
ktrstruct(name, data, datalen)
const char *name;
void *data;
size_t datalen;
{
struct ktr_request *req;
char *buf = NULL;
size_t namelen;
size_t buflen;
if (!data)
datalen = 0;
namelen = strlen(name);
buflen = namelen + 1 + datalen;
buf = malloc(buflen, M_KTRACE, M_WAITOK);
strcpy(buf, name);
bcopy(data, buf + namelen + 1, datalen);
if ((req = ktr_getrequest(KTR_STRUCT)) == NULL) {
free(buf, M_KTRACE);
return;
}
req->ktr_buffer = buf;
req->ktr_header.ktr_len = buflen;
ktr_submitrequest(curthread, req);
}
--
You are receiving this mail because:
You are the assignee for the bug.
More information about the freebsd-bugs
mailing list