strscpy
Maxime Villard <[email protected]> Mon, 18 May 2020 18:46:15 +0200
| Newsgroups | gmane.os.netbsd.devel.security |
|---|---|
| Message-ID | <[email protected]> |
I see the need to have the strscpy() function:
https://www.kernel.org/doc/htmldocs/kernel-api/API-strscpy.html
Contrary to strlcpy(), it is safe FOR REAL, because it doesn't attempt a strlen
on the source. It would be good to:
- Add strscpy() to libkern, as a C function shared across all architectures.
- Use it to replace copystr(), and subsequently the unsafe strlcpy()s or just
all of them directly. copystr() is a historical function that has the same
level of safety as strscpy(), but (1) has a format that is not usual
(pointer to store the length), (2) is very rarely used, and (3) is often
implemented in ASM which annoys sanitizers that need wrappers as a result.
strscpy() would be the only advertised string copy function, with arguments
that match the well-known strncpy() and strlcpy() functions.
Maxime
Le 08/02/2020 à 15:54, Maxime Villard a écrit :
> [I am not subscribed to this list, so if you want to answer, make sure to CC me]
>
> Contrary to what it seems, strlcpy is not safe with an untrusted second
> argument, because it does strlen on it, and therefore expects it to be NUL-
> terminated.
>
> It looks like we have some problems in some syscalls, which call strlcpy on
> user buffers that got copyin'ed. If these buffers aren't NUL-terminated,
> strlcpy will read memory until encountering a '\0'.
>
> Example, netbsd32_ioctl.c with kASan:
>
> #include <stdio.h>
> #include <stdlib.h>
> #include <unistd.h>
> #include <sys/ioctl.h>
> #include <fcntl.h>
> #include <net/if.h>
> #include <sys/sockio.h>
> #include <string.h>
> int main() {
> char buf[256];
> memset(buf, 0xAA, sizeof(buf));
> int fd = open("test.c", O_RDONLY);
> ioctl(fd, SIOCGIFADDRPREF, buf);
> }
>
> $ gcc -o test test.c -m32
> $ ./test
> ASan: Unauthorized Access In 0x...: Addr 0x... [1 byte, read, RedZonePartial]
> #0 0x... in strlcpy <netbsd>
> #1 0x... in netbsd32_ioctl <netbsd>
> #2 0x... in netbsd32_syscall <netbsd>
> #3 0x... in handle_syscall <netbsd>
>
> What's worse, in if_pppoe.c, it looks like we're calling strlcpy on a packet,
> with no guarantee that the string in the packet is NUL-terminated. This could
> trigger remote DoS.
>
> I think that strlcpy has a bad design and should be replaced by the safer
> copystr.
>
> In PPPoE I think we should drop the string stuff, calling printf is already a
> bad idea anyway.
>
> Maxime