blob: 50dacd0e5a49197fbcda740428b4d1313dadaf88 [file] [log] [blame]
Index: sys/kern/uipc_usrreq.c
===================================================================
--- sys/kern/uipc_usrreq.c (revision 225745)
+++ sys/kern/uipc_usrreq.c (working copy)
@@ -462,6 +462,8 @@
unp = sotounpcb(so);
KASSERT(unp != NULL, ("uipc_bind: unp == NULL"));
+ if (soun->sun_len > sizeof(struct sockaddr_un))
+ return (EINVAL);
namelen = soun->sun_len - offsetof(struct sockaddr_un, sun_path);
if (namelen <= 0)
return (EINVAL);
@@ -1252,6 +1254,8 @@
unp = sotounpcb(so);
KASSERT(unp != NULL, ("unp_connect: unp == NULL"));
+ if (nam->sa_len > sizeof(struct sockaddr_un))
+ return (EINVAL);
len = nam->sa_len - offsetof(struct sockaddr_un, sun_path);
if (len <= 0)
return (EINVAL);
Index: sys/compat/linux/linux_socket.c
===================================================================
--- sys/compat/linux/linux_socket.c (revision 225919)
+++ sys/compat/linux/linux_socket.c (working copy)
@@ -104,6 +104,7 @@
int oldv6size;
struct sockaddr_in6 *sin6;
#endif
+ int namelen;
if (*osalen < 2 || *osalen > UCHAR_MAX || !osa)
return (EINVAL);
@@ -166,6 +167,20 @@
}
}
+ if ((bdom == AF_LOCAL) && (*osalen > sizeof(struct sockaddr_un))) {
+ for (namelen = 0;
+ namelen < *osalen - offsetof(struct sockaddr_un, sun_path);
+ namelen++)
+ if (!((struct sockaddr_un *)kosa)->sun_path[namelen])
+ break;
+ if (namelen + offsetof(struct sockaddr_un, sun_path) >
+ sizeof(struct sockaddr_un)) {
+ error = EINVAL;
+ goto out;
+ }
+ alloclen = sizeof(struct sockaddr_un);
+ }
+
sa = (struct sockaddr *) kosa;
sa->sa_family = bdom;
sa->sa_len = alloclen;