From patchwork Mon Aug 25 12:21:57 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Samuel Thibault X-Patchwork-Id: 2525 Received: (qmail 3477 invoked by alias); 25 Aug 2014 12:22:04 -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 3408 invoked by uid 89); 25 Aug 2014 12:22:04 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.7 required=5.0 tests=AWL, BAYES_00, SPF_NEUTRAL autolearn=no version=3.3.2 X-HELO: mail3-relais-sop.national.inria.fr Date: Mon, 25 Aug 2014 14:21:57 +0200 From: Samuel Thibault To: roland@hack.frob.com Cc: libc-alpha@sourceware.org, bug-hurd@gnu.org Subject: [PATCH,Hurd] bind() fails when umask is 0000 Message-ID: <20140825122157.GC3213@type.bordeaux.inria.fr> Mail-Followup-To: roland@hack.frob.com, libc-alpha@sourceware.org, bug-hurd@gnu.org References: <53B83BBB.7060303@googlemail.com> <20140824192957.GY3053@type.youpi.perso.aquilenet.fr> <20140824200642.GD3053@type.youpi.perso.aquilenet.fr> <20140824211149.GG3053@type.youpi.perso.aquilenet.fr> <20140825120934.GB3213@type.bordeaux.inria.fr> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20140825120934.GB3213@type.bordeaux.inria.fr> User-Agent: Mutt/1.5.21+34 (58baf7c9f32f) (2010-12-30) Hello, When umask is 0000, bind()'s call to __ifsock_getsockaddr() fails with EPERM since the node was created as 0000. The following basically does the following, which looks up the translator and gets the address before fixing permissions and showing the file: bind() { ... dir_mkfile(dir, O_CREAT, 0666, &node); file_set_translator(node, ...) dir_lookup(node, "", 0, 0, ..., &ifsock); ifsock_getsockaddr(ifsock, &aport); file_chmod(node, 0666 & ~_hurd_umask); dir_link(dir, node, name, 1); ... } Samuel 2014-08-25 Samuel Thibault Fix bind when umask is e.g. 0000. * sysdeps/mach/hurd/bind.c (__bind): Pass mode 0666 to __dir_mkfile instead of final mode, so that call __ifsock_getsockaddr can always succeed, before calling __file_chmod to fix the mode according to umask, before calling __dir_link to show the file. --- sysdeps/mach/hurd/bind.c.orig 2014-08-25 14:11:11.245229537 +0200 +++ sysdeps/mach/hurd/bind.c 2014-08-25 14:11:35.892517639 +0200 @@ -40,7 +40,7 @@ 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; + file_t dir, node, ifsock; char *n; dir = __file_name_split (name, &n); @@ -48,7 +48,7 @@ return -1; /* Create a new, unlinked node in the target directory. */ - err = __dir_mkfile (dir, O_CREAT, 0666 & ~_hurd_umask, &node); + err = __dir_mkfile (dir, O_CREAT, 0666, &node); if (! err) { @@ -61,36 +61,43 @@ MACH_MSG_TYPE_COPY_SEND); if (! err) { - /* Link the node, now a socket, into the target directory. */ - err = __dir_link (dir, node, n, 1); - if (err == EEXIST) - err = EADDRINUSE; + enum retry_type doretry; + char retryname[1024]; + /* Get a port to the ifsock translator. */ + err = __dir_lookup(node, "", 0, 0, &doretry, retryname, &ifsock); + if (! err) + if (doretry != FS_RETRY_NORMAL || retryname[0] != '\0') + err = EADDRINUSE; } - __mach_port_deallocate (__mach_task_self (), node); if (! err) { - /* Get a port to the ifsock translator. */ - file_t ifsock = __file_name_lookup_under (dir, n, 0, 0); - if (ifsock == MACH_PORT_NULL) - { - err = errno; - /* If we failed, get rid of the node we created. */ - __dir_unlink (dir, n); - } - else + /* Get the address port. */ + err = __ifsock_getsockaddr (ifsock, &aport); + if (err == MIG_BAD_ID || err == EOPNOTSUPP) + /* We are not talking to /hurd/ifsock. Probably + someone came in after we linked our node, unlinked + it, and replaced it with a different node, before we + did our lookup. Treat it as if our link had failed + with EEXIST. */ + err = EADDRINUSE; + if (! err) { - /* Get the address port. */ - err = __ifsock_getsockaddr (ifsock, &aport); - if (err == MIG_BAD_ID || err == EOPNOTSUPP) - /* We are not talking to /hurd/ifsock. Probably - someone came in after we linked our node, unlinked - it, and replaced it with a different node, before we - did our lookup. Treat it as if our link had failed - with EEXIST. */ - err = EADDRINUSE; + /* Fix the access mode before showing the file. */ + err = __file_chmod (node, 0666 & ~_hurd_umask); + if (! err) + { + /* Link the node, now a socket with proper mode, into the + * target directory. */ + err = __dir_link (dir, node, n, 1); + if (err == EEXIST) + err = EADDRINUSE; + } + if (err) + __mach_port_deallocate (__mach_task_self (), aport); } __mach_port_deallocate (__mach_task_self (), ifsock); } + __mach_port_deallocate (__mach_task_self (), node); } __mach_port_deallocate (__mach_task_self (), dir);