From patchwork Sat Feb 7 21:30:41 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Samuel Thibault X-Patchwork-Id: 4960 Received: (qmail 16758 invoked by alias); 7 Feb 2015 21:30:50 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 16745 invoked by uid 89); 7 Feb 2015 21:30:50 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.8 required=5.0 tests=AWL, BAYES_00, SPF_HELO_PASS autolearn=ham version=3.3.2 X-HELO: sonata.ens-lyon.org Date: Sat, 7 Feb 2015 22:30:41 +0100 From: Samuel Thibault To: Roland McGrath Cc: libc-alpha@sourceware.org, bug-hurd@gnu.org Subject: [PATCH] Fix connect/sendto/sendmsg into making sure to ignore bytes beyond sockaddr length Message-ID: <20150207213041.GT3023@type.youpi.perso.aquilenet.fr> Mail-Followup-To: Roland McGrath , libc-alpha@sourceware.org, bug-hurd@gnu.org MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.21+34 (58baf7c9f32f) (2010-12-30) 2014-03-01 Samuel Thibault Thanks Tanaka Akira for the report. * hurd/hurdsocket.h: New file, defines _hurd_sun_path_dupa which duplicates ADDR->sun_path with sockaddr LEN limitation. * sysdeps/mach/hurd/connect.c: Include (__connect): Give result of _hurd_sun_path_dupa to name lookup. * sysdeps/mach/hurd/sendmsg.c: Likewise. * sysdeps/mach/hurd/sendto.c: Likewise. * sysdeps/mach/hurd/bind.c: Call _hurd_sun_path_dupa instead of implementing it by hand. --- hurd/hurdsocket.h | 22 ++++++++++++++++++++++ sysdeps/mach/hurd/bind.c | 8 +++----- sysdeps/mach/hurd/connect.c | 4 +++- sysdeps/mach/hurd/sendmsg.c | 4 +++- sysdeps/mach/hurd/sendto.c | 4 +++- 5 files changed, 34 insertions(+), 8 deletions(-) diff --git a/hurd/hurdsocket.h b/hurd/hurdsocket.h new file mode 100644 index 0000000..fd45f34 --- /dev/null +++ b/hurd/hurdsocket.h @@ -0,0 +1,22 @@ +/* Hurd-specific socket functions + Copyright (C) 2013-2015 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include + +#define _hurd_sun_path_dupa(__addr, __len) \ + strndupa ((__addr)->sun_path, (__len) - offsetof (struct sockaddr_un, sun_path)) diff --git a/sysdeps/mach/hurd/bind.c b/sysdeps/mach/hurd/bind.c index 1704e94..908b15c 100644 --- a/sysdeps/mach/hurd/bind.c +++ b/sysdeps/mach/hurd/bind.c @@ -25,7 +25,7 @@ #include #include #include -#include +#include "hurd/hurdsocket.h" /* Give the socket FD the local address ADDR (which is LEN bytes long). */ int @@ -37,13 +37,11 @@ __bind (int fd, __CONST_SOCKADDR_ARG addrarg, socklen_t len) if (addr->sun_family == AF_LOCAL) { + char *name = _hurd_sun_path_dupa (addr, len); /* For the local domain, we must create a node in the filesystem using the ifsock translator and then fetch the address from it. */ file_t dir, node; - char name[len - offsetof (struct sockaddr_un, sun_path) + 1], *n; - - strncpy (name, addr->sun_path, sizeof name - 1); - name[sizeof name - 1] = '\0'; /* Make sure */ + char *n; dir = __file_name_split (name, &n); if (dir == MACH_PORT_NULL) diff --git a/sysdeps/mach/hurd/connect.c b/sysdeps/mach/hurd/connect.c index 60856ae..b974b06 100644 --- a/sysdeps/mach/hurd/connect.c +++ b/sysdeps/mach/hurd/connect.c @@ -22,6 +22,7 @@ #include #include #include +#include "hurd/hurdsocket.h" /* Open a connection on socket FD to peer at ADDR (which LEN bytes long). For connectionless socket types, just set the default address to send to @@ -36,9 +37,10 @@ __connect (int fd, __CONST_SOCKADDR_ARG addrarg, socklen_t len) if (addr->sun_family == AF_LOCAL) { + char *name = _hurd_sun_path_dupa (addr, len); /* For the local domain, we must look up the name as a file and talk to it with the ifsock protocol. */ - file_t file = __file_name_lookup (addr->sun_path, 0, 0); + file_t file = __file_name_lookup (name, 0, 0); if (file == MACH_PORT_NULL) return -1; err = __ifsock_getsockaddr (file, &aport); diff --git a/sysdeps/mach/hurd/sendmsg.c b/sysdeps/mach/hurd/sendmsg.c index 5a93c63..fee722c 100644 --- a/sysdeps/mach/hurd/sendmsg.c +++ b/sysdeps/mach/hurd/sendmsg.c @@ -24,6 +24,7 @@ #include #include #include +#include "hurd/hurdsocket.h" /* Send a message described MESSAGE on socket FD. Returns the number of bytes sent, or -1 for errors. */ @@ -104,9 +105,10 @@ __libc_sendmsg (int fd, const struct msghdr *message, int flags) { if (addr->sun_family == AF_LOCAL) { + char *name = _hurd_sun_path_dupa (addr, addr_len); /* For the local domain, we must look up the name as a file and talk to it with the ifsock protocol. */ - file_t file = __file_name_lookup (addr->sun_path, 0, 0); + file_t file = __file_name_lookup (name, 0, 0); if (file == MACH_PORT_NULL) { if (dealloc) diff --git a/sysdeps/mach/hurd/sendto.c b/sysdeps/mach/hurd/sendto.c index 72c1d6b..1b5654b 100644 --- a/sysdeps/mach/hurd/sendto.c +++ b/sysdeps/mach/hurd/sendto.c @@ -22,6 +22,7 @@ #include #include #include +#include "hurd/hurdsocket.h" /* Send N bytes of BUF on socket FD to peer at address ADDR (which is ADDR_LEN bytes long). Returns the number sent, or -1 for errors. */ @@ -47,9 +48,10 @@ __sendto (int fd, if (addr->sun_family == AF_LOCAL) { + char *name = _hurd_sun_path_dupa (addr, addr_len); /* For the local domain, we must look up the name as a file and talk to it with the ifsock protocol. */ - file_t file = __file_name_lookup (addr->sun_path, 0, 0); + file_t file = __file_name_lookup (name, 0, 0); if (file == MACH_PORT_NULL) return errno; err_port = __ifsock_getsockaddr (file, aport);