Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/kern - add diagnostic check for sa_len
details: https://anonhg.NetBSD.org/src/rev/929a5e186567
branches: trunk
changeset: 334704:929a5e186567
user: christos <christos%NetBSD.org@localhost>
date: Tue Dec 02 19:45:58 2014 +0000
description:
- add diagnostic check for sa_len
- use new socket pretty printers to format sockaddr's
diffstat:
sys/kern/uipc_domain.c | 138 ++++++++++++++++++++++++++++++++----------------
1 files changed, 91 insertions(+), 47 deletions(-)
diffs (200 lines):
diff -r bcaf559c05a3 -r 929a5e186567 sys/kern/uipc_domain.c
--- a/sys/kern/uipc_domain.c Tue Dec 02 19:38:16 2014 +0000
+++ b/sys/kern/uipc_domain.c Tue Dec 02 19:45:58 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: uipc_domain.c,v 1.95 2014/09/05 09:20:59 matt Exp $ */
+/* $NetBSD: uipc_domain.c,v 1.96 2014/12/02 19:45:58 christos Exp $ */
/*
* Copyright (c) 1982, 1986, 1993
@@ -32,7 +32,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uipc_domain.c,v 1.95 2014/09/05 09:20:59 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uipc_domain.c,v 1.96 2014/12/02 19:45:58 christos Exp $");
#include <sys/param.h>
#include <sys/socket.h>
@@ -52,6 +52,9 @@
#include <sys/file.h>
#include <sys/filedesc.h>
#include <sys/kauth.h>
+
+#include <netatalk/at.h>
+#include <net/if_dl.h>
#include <netinet/in.h>
MALLOC_DECLARE(M_SOCKADDR);
@@ -252,6 +255,47 @@
return sockaddr_const_addr(any, slenp);
}
+#ifdef DIAGNOSTIC
+static void
+sockaddr_checklen(const struct sockaddr *sa)
+{
+ socklen_t len = 0;
+ switch (sa->sa_family) {
+ case AF_INET:
+ len = sizeof(struct sockaddr_in);
+ break;
+ case AF_INET6:
+ len = sizeof(struct sockaddr_in6);
+ break;
+ case AF_UNIX:
+ len = sizeof(struct sockaddr_un);
+ break;
+ case AF_LINK:
+ len = sizeof(struct sockaddr_dl);
+ // As long as it is not 0...
+ if (sa->sa_len != 0)
+ return;
+ break;
+ case AF_APPLETALK:
+ len = sizeof(struct sockaddr_at);
+ break;
+ default:
+ printf("%s: Unhandled af=%hhu socklen=%hhu\n", __func__,
+ sa->sa_family, sa->sa_len);
+ return;
+ }
+ if (len != sa->sa_len) {
+ char buf[512];
+ sockaddr_format(sa, buf, sizeof(buf));
+ printf("%s: %p bad len af=%hhu socklen=%hhu len=%u [%s]\n",
+ __func__, sa, sa->sa_family, sa->sa_len,
+ (unsigned)len, buf);
+ }
+}
+#else
+#define sockaddr_checklen(sa) ((void)0)
+#endif
+
struct sockaddr *
sockaddr_alloc(sa_family_t af, socklen_t socklen, int flags)
{
@@ -263,6 +307,7 @@
sa->sa_family = af;
sa->sa_len = reallen;
+ sockaddr_checklen(sa);
return sa;
}
@@ -274,6 +319,7 @@
panic("%s: source too long, %d < %d bytes", __func__, socklen,
src->sa_len);
}
+ sockaddr_checklen(src);
return memcpy(dst, src, src->sa_len);
}
@@ -340,64 +386,62 @@
free(sa, M_SOCKADDR);
}
-void
+static int
+sun_print(char *buf, size_t len, const void *v)
+{
+ const struct sockaddr_un *sun = v;
+ return snprintf(buf, len, "%s", sun->sun_path);
+}
+
+int
sockaddr_format(const struct sockaddr *sa, char *buf, size_t len)
{
- const struct sockaddr_un *sun = (const struct sockaddr_un *)sa;
- const struct sockaddr_in *sin = (const struct sockaddr_in *)sa;
- const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)sa;
- const uint8_t *data;
- size_t data_len;
+ size_t plen = 0;
- if (sa == NULL) {
- strlcpy(buf, "(null)", len);
- return;
- }
+ if (sa == NULL)
+ return strlcpy(buf, "(null)", len);
switch (sa->sa_family) {
- default:
- snprintf(buf, len, "(unknown socket family %d)",
- (int)sa->sa_family);
- return;
case AF_LOCAL:
- strlcpy(buf, "unix:", len);
- strlcat(buf, sun->sun_path, len);
- return;
+ plen = strlcpy(buf, "unix: ", len);
+ break;
case AF_INET:
- strlcpy(buf, "inet:", len);
- if (len < 6)
- return;
- buf += 5;
- len -= 5;
- data = (const uint8_t *)&sin->sin_addr;
- data_len = sizeof(sin->sin_addr);
+ plen = strlcpy(buf, "inet: ", len);
break;
case AF_INET6:
- strlcpy(buf, "inet6:", len);
- if (len < 7)
- return;
- buf += 6;
- len -= 6;
- data = (const uint8_t *)&sin6->sin6_addr;
- data_len = sizeof(sin6->sin6_addr);
+ plen = strlcpy(buf, "inet6: ", len);
+ break;
+ case AF_LINK:
+ plen = strlcpy(buf, "link: ", len);
break;
+ case AF_APPLETALK:
+ plen = strlcpy(buf, "atalk: ", len);
+ break;
+ default:
+ return snprintf(buf, len, "(unknown socket family %d)",
+ (int)sa->sa_family);
}
- for (;;) {
- if (--len == 0)
- break;
- uint8_t hi = *data >> 4;
- uint8_t lo = *data & 15;
- --data_len;
- ++data;
- *buf++ = hi + (hi >= 10 ? 'a' - 10 : '0');
- if (--len == 0)
- break;
- *buf++ = lo + (lo >= 10 ? 'a' - 10 : '0');
- if (data_len == 0)
- break;
+ buf += plen;
+ if (plen > len)
+ len = 0;
+ else
+ len -= plen;
+
+ switch (sa->sa_family) {
+ case AF_LOCAL:
+ return sun_print(buf, len, sa);
+ case AF_INET:
+ return sin_print(buf, len, sa);
+ case AF_INET6:
+ return sin6_print(buf, len, sa);
+ case AF_LINK:
+ return sdl_print(buf, len, sa);
+ case AF_APPLETALK:
+ return sat_print(buf, len, sa);
+ default:
+ panic("bad family %hhu", sa->sa_family);
}
- *buf = 0;
}
/*
Home |
Main Index |
Thread Index |
Old Index