From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=-3.1 required=5.0 tests=DKIM_INVALID,DKIM_SIGNED, MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED,RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL autolearn=ham autolearn_force=no version=3.4.4 Received: (qmail 7620 invoked from network); 29 Dec 2020 22:55:57 -0000 Received: from mother.openwall.net (195.42.179.200) by inbox.vuxu.org with ESMTPUTF8; 29 Dec 2020 22:55:57 -0000 Received: (qmail 32256 invoked by uid 550); 29 Dec 2020 22:55:50 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Reply-To: musl@lists.openwall.com Received: (qmail 32226 invoked from network); 29 Dec 2020 22:55:50 -0000 X-Virus-Scanned: Debian amavisd-new at disroot.org From: =?UTF-8?q?=C3=89rico=20Nogueira?= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=disroot.org; s=mail; t=1609282537; bh=lvfFNVVy3JFiMFFio5epnH/+GaR6mXCfAD4BQ95PjrU=; h=From:To:Cc:Subject:Date; b=f4EFnCSEwGop5GGwwPBvdAyMHYTYlXseCaLIkrx2yPkSi6c93cVlTQUKUa1dWmJ38 2ADCUifptskb+4OpH2PFMYcb0Co6wNibwYBStbCAsJXbfWxp4+BozcDBuSJkOIwCAR UZHehPm/Xw7tfCz4devR4u6NegiAvq9ttq7u4L3/Ge4jO6Qm8/vqpfAYv1gvQNczaQ 9XjgCGMiwNmC5lPe35vJpSCLYuEwQIy2z5diLaynB5ALDvu42yRdy0PXi3X0Zq70Sf uP5VSrZ4u+9HMml2bi3Ld8Kw295xjW1CtInnH3yEN2Mny9yv6INaWlZiDRio4F9EH/ vxhaQMOMPbEfg== To: musl@lists.openwall.com Cc: =?UTF-8?q?=C3=89rico=20Rolim?= Date: Tue, 29 Dec 2020 19:55:18 -0300 Message-Id: <20201229225518.3677-1-ericonr@disroot.org> Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Subject: [musl] [PATCH] use openat syscall in open() to avoid the spurious fcntl call in modern kernels to apply O_CLOEXEC From: Érico Rolim openat appears to have been introduced after the O_CLOEXEC flag was added to the kernel, so its presence can be used as a proxy for the O_CLOEXEC flag definitely taking effect --- The commit message is unsure about the timeline between O_CLOEXEC and openat, because I couldn't find any definitive sources. It's certainly the assumption in the current openat() implementation, and glibc seems to use openat for open() since the first commit I could find (a63c7fa1856d6d4ef6573111e5700ac01b0bf6b2, from 2011). bionic also always uses openat, but I didn't look through its history. I believe this will generate a tiny amount of dead code in archs which don't have SYS_open (so __sys_open_cp already uses SYS_openat), since they should never return ENOSYS, and if they do (funky seccomp filters?) the second attempt will be useless, since it will use the exact same values. The block could be guarded by an ifdef, but I'm not sure it's desired. src/fcntl/open.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/fcntl/open.c b/src/fcntl/open.c index 1d817a2d..75c4b919 100644 --- a/src/fcntl/open.c +++ b/src/fcntl/open.c @@ -13,9 +13,12 @@ int open(const char *filename, int flags, ...) va_end(ap); } - int fd = __sys_open_cp(filename, flags, mode); - if (fd>=0 && (flags & O_CLOEXEC)) - __syscall(SYS_fcntl, fd, F_SETFD, FD_CLOEXEC); + int fd = __syscall(SYS_openat, AT_FDCWD, filename, flags|O_LARGEFILE, mode); + if (fd==-ENOSYS) { + fd = __sys_open_cp(filename, flags, mode); + if (fd>=0 && (flags & O_CLOEXEC)) + __syscall(SYS_fcntl, fd, F_SETFD, FD_CLOEXEC); + } return __syscall_ret(fd); } -- 2.29.2