[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