]> granicus.if.org Git - strace/commitdiff
printsock: fix zero padding of sockaddr buffer
authorDmitry V. Levin <ldv@altlinux.org>
Wed, 22 Jun 2016 00:21:47 +0000 (00:21 +0000)
committerDmitry V. Levin <ldv@altlinux.org>
Wed, 22 Jun 2016 00:21:47 +0000 (00:21 +0000)
Before this change printsock used to erroneously clear the last byte
of sockaddr buffer.

* net.c (printsock): Use struct sockaddr_storage as a sockaddr buffer.
Reserve additional byte after the sockaddr buffer for zero padding.
Do not clear memory that is going to be overwritten by umoven.
Clear the tail of sockaddr buffer that was not overwritten by umoven.

net.c

diff --git a/net.c b/net.c
index 61c7ad9f0134ff55fae5b6f409f52fb8327bd2b9..51c3961a1117322186dc35e49b4d8112c5f53cd6 100644 (file)
--- a/net.c
+++ b/net.c
@@ -258,20 +258,24 @@ print_sockaddr(struct tcb *tcp, const void *const buf, const int addrlen)
 int
 printsock(struct tcb *tcp, long addr, int addrlen)
 {
-       sockaddr_buf_t addrbuf;
-
        if (addrlen < 2) {
                printaddr(addr);
                return -1;
        }
 
-       if (addrlen > (int) sizeof(addrbuf))
-               addrlen = sizeof(addrbuf);
+       union {
+               struct sockaddr sa;
+               struct sockaddr_storage storage;
+               char pad[sizeof(struct sockaddr_storage) + 1];
+       } addrbuf;
+
+       if ((unsigned) addrlen > sizeof(addrbuf.storage))
+               addrlen = sizeof(addrbuf.storage);
 
-       memset(&addrbuf, 0, sizeof(addrbuf));
        if (umoven_or_printaddr(tcp, addr, addrlen, addrbuf.pad))
                return -1;
-       addrbuf.pad[sizeof(addrbuf.pad) - 1] = '\0';
+
+       memset(&addrbuf.pad[addrlen], 0, sizeof(addrbuf.pad) - addrlen);
 
        print_sockaddr(tcp, &addrbuf, addrlen);