From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2181) id 6E4C83858428; Wed, 10 Apr 2024 15:23:59 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 6E4C83858428 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1712762639; bh=tBSNb4WoHerVgu16eq3iDFcdlGUbH9I68bf1sakgSf4=; h=From:To:Subject:Date:From; b=eeYzia0Gh01tAnml4r/w7Ul+JwdBtPITdt0qgEoL1is1/gCOAZRpbWVEQlPgmxiuM ZEb4SrG/PuO6eC9H7CqgQY1cfS/siwdo1UKSn0r+qFyU0K81AD9JjiVbfl775nM1hX VFeJLyndk1QpBYQeotG+DVCW0CjgGm4mMkRTMNW4= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Jonathan Wakely To: gcc-cvs@gcc.gnu.org, libstdc++-cvs@gcc.gnu.org Subject: [gcc r14-9888] libstdc++: Handle EMLINK and EFTYPE in std::filesystem::remove_all X-Act-Checkin: gcc X-Git-Author: Jonathan Wakely X-Git-Refname: refs/heads/master X-Git-Oldrev: 4be1cc5f50578fafcdcbd09160235066d76a3f86 X-Git-Newrev: 9586d6248e89c6bc138f65ea1992de3a2f54a522 Message-Id: <20240410152359.6E4C83858428@sourceware.org> Date: Wed, 10 Apr 2024 15:23:59 +0000 (GMT) List-Id: https://gcc.gnu.org/g:9586d6248e89c6bc138f65ea1992de3a2f54a522 commit r14-9888-g9586d6248e89c6bc138f65ea1992de3a2f54a522 Author: Jonathan Wakely Date: Mon Apr 8 17:41:00 2024 +0100 libstdc++: Handle EMLINK and EFTYPE in std::filesystem::remove_all Although POSIX requires ELOOP, FreeBSD documents that openat with O_NOFOLLOW returns EMLINK if the last component of a filename is a symbolic link. Check for EMLINK as well as ELOOP, so that the TOCTTOU mitigation in remove_all works correctly. See https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=214633 or the FreeBSD man page for reference. According to its man page, DragonFlyBSD also uses EMLINK for this error, and NetBSD uses its own EFTYPE. OpenBSD follows POSIX and uses EMLINK. This fixes these failures on FreeBSD: FAIL: 27_io/filesystem/operations/remove_all.cc -std=gnu++17 execution test FAIL: experimental/filesystem/operations/remove_all.cc -std=gnu++17 execution test libstdc++-v3/ChangeLog: * src/c++17/fs_ops.cc (remove_all) [__FreeBSD__ || __DragonFly__]: Check for EMLINK as well as ELOOP. [__NetBSD__]: Check for EFTYPE as well as ELOOP. Diff: --- libstdc++-v3/src/c++17/fs_ops.cc | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/libstdc++-v3/src/c++17/fs_ops.cc b/libstdc++-v3/src/c++17/fs_ops.cc index 61df19753ef..07bc2a0fa88 100644 --- a/libstdc++-v3/src/c++17/fs_ops.cc +++ b/libstdc++-v3/src/c++17/fs_ops.cc @@ -1312,7 +1312,13 @@ fs::remove_all(const path& p) // Our work here is done. return 0; case ENOTDIR: - case ELOOP: + case ELOOP: // POSIX says openat with O_NOFOLLOW sets ELOOP for a symlink. +#if defined __FreeBSD__ || defined __DragonFly__ + case EMLINK: // Used instead of ELOOP +#endif +#if defined __NetBSD__ && defined EFTYPE + case EFTYPE: // Used instead of ELOOP +#endif // Not a directory, will remove below. break; #endif @@ -1352,7 +1358,13 @@ fs::remove_all(const path& p, error_code& ec) ec.clear(); return 0; case ENOTDIR: - case ELOOP: + case ELOOP: // POSIX says openat with O_NOFOLLOW sets ELOOP for a symlink. +#if defined __FreeBSD__ || defined __DragonFly__ + case EMLINK: // Used instead of ELOOP +#endif +#if defined __NetBSD__ && defined EFTYPE + case EFTYPE: // Used instead of ELOOP +#endif // Not a directory, will remove below. break; #endif