From patchwork Fri Mar 21 21:00:43 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 875266 Delivered-To: patch@linaro.org Received: by 2002:a5d:5f4c:0:b0:38f:210b:807b with SMTP id cm12csp1074933wrb; Fri, 21 Mar 2025 14:01:59 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCWpJkP8fcSHSpmY2Ov3ff4wBhx61STg6YV/q5t7ncZo/fSDiAuCGflLhjTl8TMroTtEKv5oTw==@linaro.org X-Google-Smtp-Source: AGHT+IHhaoC+2Xni2oR9/XpHkeafCkkU5O0JfkfhZGm3sQ0pZI/OqAsO6VJKZbwyUZ0mnd4NByrC X-Received: by 2002:a05:620a:4311:b0:7c5:9abe:a7a5 with SMTP id af79cd13be357-7c5b9add39amr799045785a.7.1742590919006; Fri, 21 Mar 2025 14:01:59 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1742590918; cv=pass; d=google.com; s=arc-20240605; b=J1/ABL5nMr6ZHIe1lB3go49O8jveOgo8+h+3qZJpFJ7Z9RD4XSTSGzh7Aq0AE0/fAG 1VE+xgkEMMkpE2o7czHJdESlq9HLNOjFPNLburYf3W3mrX1LKYld55PIStLYSEtaW3On 3R//2QNC7hYYWPhLtbXQXEQ3lzYE+csuKFpRzku+R0IGlHUI1Rk9XQQtyAFDTVg004nw 1rC2YkOf4OBydvAslNn5XYP+LiISZzPIKPtTdcib6KZ2Y5zKsn6lK+0xByounSCgXC0W cYo0awxdIMBxXgPFVyz03jqR2KPJOx9yLhP66MfS1SgMOpBIKSpyzLm/ZMWMy4xuRAuP 5DzA== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:message-id:date:subject:to:from:dkim-signature :dkim-filter:arc-filter:dmarc-filter:delivered-to:dkim-filter; bh=niTGKFPQk1CmgUugSBYMZ0Vj1d+CUJSMuauNPwJ8RqE=; fh=dHLBnA+MhGtNtN2B2JMAELi4oD+gmgMg7DL8H0jYbkI=; b=AkYObB0p3IZiG0G50mg2KizstXKyFr5erqmS7JC0lHsxbJ1B5J4GQ8p1i2owFbTtDJ 5X3Z1RaWn1sdxOT6GiWNlQTT+/qUkowIsVOAl+C7PuA4/UPBaU3nk6ac714m9gUFyml3 pUmQfscN1bmZxZoBXVqy7I17iAP2CzL9Y32CALReSskLzIGVpghQb38ppz+QM3owySI5 lNEYRzRnTddwLiUl8SYaHItAGLW5h6F3hJ/iUOHwKBSEdxKW03yp3Lse+dOEK5ahQ6p1 cohb0cEIjIczHsRFGmLYKRkLoIqz4d02Po3WIj4rCjy/pX80/U64PU8pVxcFvbQn2YJD Oycg==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=EYOsgSuP; arc=pass (i=1); spf=pass (google.com: domain of libc-alpha-bounces~patch=linaro.org@sourceware.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="libc-alpha-bounces~patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from server2.sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id af79cd13be357-7c5b9362419si247725085a.522.2025.03.21.14.01.58 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 21 Mar 2025 14:01:58 -0700 (PDT) Received-SPF: pass (google.com: domain of libc-alpha-bounces~patch=linaro.org@sourceware.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) client-ip=2620:52:3:1:0:246e:9693:128c; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=EYOsgSuP; arc=pass (i=1); spf=pass (google.com: domain of libc-alpha-bounces~patch=linaro.org@sourceware.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="libc-alpha-bounces~patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 80B403858D34 for ; Fri, 21 Mar 2025 21:01:58 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 80B403858D34 Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=EYOsgSuP X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pl1-x62e.google.com (mail-pl1-x62e.google.com [IPv6:2607:f8b0:4864:20::62e]) by sourceware.org (Postfix) with ESMTPS id A2714385842D for ; Fri, 21 Mar 2025 21:01:30 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org A2714385842D Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=linaro.org ARC-Filter: OpenARC Filter v1.0.0 sourceware.org A2714385842D Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::62e ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1742590890; cv=none; b=oJLjOB/BxGNZUdsghQ6mkYgxZWp+d2W9uuEZnAuqegUWj8KPGcNM5DfCnmXrAKpAAAeCcBlOvw24fnhuifYngeiGojWajwcnbWQbAMaXnQg5Gm+1MkRgXg93UIHhezzH3c5sJdECQm6OhqHKf6olbxZqbS3NdeIS8+rexgAqTIw= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1742590890; c=relaxed/simple; bh=E61UyZyzdGOAdpso/YMiEy8YGGwfkPKqwuwPTdOa+Ok=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=qJhdPtDWrZa13+MX21hKlk1/BSE0grgLds0/YDtswXYdR82c4XasAwD0tZPTAnxOpXXHqTbwCMk8mx3vmQ/pkQnRe8ykBRut/MbORQyWbAZ7tlNSBelm0R6l9nh4vEXuM6MHooxjvXPmjTr70f+sekAT1rHL5pPq3awcHq0kdUc= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org A2714385842D Received: by mail-pl1-x62e.google.com with SMTP id d9443c01a7336-2235189adaeso48057015ad.0 for ; Fri, 21 Mar 2025 14:01:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1742590889; x=1743195689; darn=sourceware.org; h=content-transfer-encoding:mime-version:message-id:date:subject:to :from:from:to:cc:subject:date:message-id:reply-to; bh=niTGKFPQk1CmgUugSBYMZ0Vj1d+CUJSMuauNPwJ8RqE=; b=EYOsgSuPl9N3N/df+V+pgiR9R59ZYdS6qXYbGJFu3ffVlyAOnCMY4TWNIbYGa2IztO shFLJLLXCLLSFQY42Od42Tozq3Qa5DUj6CXvVktuxjsOLE6NyRIu2UVItNPd4MW84CPq 4fuKA3sUyal11T0JoAze7ItGIwb8FUo1K9KEefCSJC712upbZJo6mb06ypRqPsd1SciK arV3dvjLTkvCi62GUYRHhlUXBQO+0S/o5E9aieCZs6W+z1yJnmk1dAFlPpXDCciZdK5+ KC+yviXnhmRk51bV8OlbOPsohNnSPjOuvgHriCNR9LlE5N0Ny8vpJ6gE1TAbV4GvUuFN SLJw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1742590889; x=1743195689; h=content-transfer-encoding:mime-version:message-id:date:subject:to :from:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=niTGKFPQk1CmgUugSBYMZ0Vj1d+CUJSMuauNPwJ8RqE=; b=qDlgR2njYAw1EOBx7uMHx7al1IhILCQmOmCDnVg2jhCUcees/hTtOo22M+X9YIXD4C AYpaVx+en8rq94fzGEUvWySXssnBI7HFAKObRWBaQRL+5gww+lMbW2zTjf/oOvyPYz8M NyZAgwY6etgGqs2OEy9dTlpYq9cJik7Q5FbI6P7BQ+CeZfhe7DXHSyBWCgHHsSZZLir/ l+l2mRIaEM5/u068l79z88+gIS4vpnsOP6MI/lh17k5ziOtyVXIrYnri1whopCP3NNt9 kBH+5jRhMX+D5i5MTk099iMW+cuWtNI55NMa1HPa1sed9cmunff+k5lDUI58R/4WSHg3 7QGg== X-Gm-Message-State: AOJu0YykATE0Nx0r2X/+8Fai71GX0aGasQ0i5lerR1oZfgLyejO7cTny TTDyVWndv32Yiet9xnnM975iywKGbNEbGK82hT+ZcLjPB4yjdUROT+acfqwU0N9wwZSFUloLd/W 6 X-Gm-Gg: ASbGncvlypA3ErjAQVpT1OCxnQ/rd0pmZ3vsgjKQeH2L7ghplGrMr38bi7m86/zMX3z vb7BJeSnYcrOfbsSUhqJMVpQ4JHXu6d5iG/zJTmiYa9C3rLec6EmcwqvQN3bzynSKwvJ0C1xiKx Pii37KGiWi+IBsENestkpasJtvhM7dI484nLs68rbyNjvKouUOLN/kIC2yAkTPaEN6Kai2y9Sb6 Y6QAczcO33uptGCu20J5zirzxZ4kemwtm1bBhx/ZcF8Fh4a4bRLD1RvB3KaBwsBnYgPNYWosOeh P7/PUVgVkijhFAJyG9FRbwMaM71x9morfjxceMI4ftIw17b6+lglWae/Pw== X-Received: by 2002:a17:902:ccc4:b0:223:3eed:f680 with SMTP id d9443c01a7336-2265e743eb3mr131941555ad.18.1742590888657; Fri, 21 Mar 2025 14:01:28 -0700 (PDT) Received: from mandiga.. ([2804:1b3:a7c1:aaeb:38f3:a1e8:650f:37d7]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-301bf59cd3esm6651746a91.21.2025.03.21.14.01.27 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 21 Mar 2025 14:01:28 -0700 (PDT) From: Adhemerval Zanella To: libc-alpha@sourceware.org Subject: [PATCH v3] linux: Add openat2 (BZ 31664) Date: Fri, 21 Mar 2025 18:00:43 -0300 Message-ID: <20250321210124.3688671-1-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.43.0 MIME-Version: 1.0 X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libc-alpha-bounces~patch=linaro.org@sourceware.org The openat2 syscall was added on Linux 5.6, as an extension of openat. Different than other open-like functions, the kernel only provides the LFS variant (so files larger than 4GB always succeed, as other functions with offset larger than off_t). Also, imilar to other open functions, the new symbol is a cancellable entrypoint. The test case added only stresses some of the syscalls provided functionalities and it is based on an existent kernel self-test. Since the prototype does not use variadic arguments, there is no need to add a fortify wrapper to catch wrong usages. The documentation mostly defers to the Linux manual pages. Checked on x86_64-linux-gnu. --- This patch follows the recent sched_setattr inclusion on how to handle the new kABI syscall with extensible fields, where it up to the caller to not use it where it might case ABI issues with different TU.A Changes from v2: * Rabse against master and adapt to version 2.42 --- NEWS | 4 + manual/llio.texi | 100 +++++++ sysdeps/unix/sysv/linux/Makefile | 14 + sysdeps/unix/sysv/linux/Versions | 3 + sysdeps/unix/sysv/linux/aarch64/libc.abilist | 1 + sysdeps/unix/sysv/linux/alpha/libc.abilist | 1 + sysdeps/unix/sysv/linux/arc/libc.abilist | 1 + sysdeps/unix/sysv/linux/arm/be/libc.abilist | 1 + sysdeps/unix/sysv/linux/arm/le/libc.abilist | 1 + sysdeps/unix/sysv/linux/bits/fcntl-linux.h | 22 ++ sysdeps/unix/sysv/linux/bits/openat2.h | 61 +++++ sysdeps/unix/sysv/linux/csky/libc.abilist | 1 + sysdeps/unix/sysv/linux/hppa/libc.abilist | 1 + sysdeps/unix/sysv/linux/i386/libc.abilist | 1 + .../sysv/linux/loongarch/lp64/libc.abilist | 1 + .../sysv/linux/m68k/coldfire/libc.abilist | 1 + .../unix/sysv/linux/m68k/m680x0/libc.abilist | 1 + .../sysv/linux/microblaze/be/libc.abilist | 1 + .../sysv/linux/microblaze/le/libc.abilist | 1 + .../sysv/linux/mips/mips32/fpu/libc.abilist | 1 + .../sysv/linux/mips/mips32/nofpu/libc.abilist | 1 + .../sysv/linux/mips/mips64/n32/libc.abilist | 1 + .../sysv/linux/mips/mips64/n64/libc.abilist | 1 + sysdeps/unix/sysv/linux/openat2.c | 29 ++ sysdeps/unix/sysv/linux/or1k/libc.abilist | 1 + .../linux/powerpc/powerpc32/fpu/libc.abilist | 1 + .../powerpc/powerpc32/nofpu/libc.abilist | 1 + .../linux/powerpc/powerpc64/be/libc.abilist | 1 + .../linux/powerpc/powerpc64/le/libc.abilist | 1 + .../unix/sysv/linux/riscv/rv32/libc.abilist | 1 + .../unix/sysv/linux/riscv/rv64/libc.abilist | 1 + .../unix/sysv/linux/s390/s390-32/libc.abilist | 1 + .../unix/sysv/linux/s390/s390-64/libc.abilist | 1 + sysdeps/unix/sysv/linux/sh/be/libc.abilist | 1 + sysdeps/unix/sysv/linux/sh/le/libc.abilist | 1 + .../sysv/linux/sparc/sparc32/libc.abilist | 1 + .../sysv/linux/sparc/sparc64/libc.abilist | 1 + sysdeps/unix/sysv/linux/tst-openat2-consts.py | 63 +++++ sysdeps/unix/sysv/linux/tst-openat2.c | 259 ++++++++++++++++++ .../unix/sysv/linux/x86_64/64/libc.abilist | 1 + .../unix/sysv/linux/x86_64/x32/libc.abilist | 1 + 41 files changed, 587 insertions(+) create mode 100644 sysdeps/unix/sysv/linux/bits/openat2.h create mode 100644 sysdeps/unix/sysv/linux/openat2.c create mode 100755 sysdeps/unix/sysv/linux/tst-openat2-consts.py create mode 100644 sysdeps/unix/sysv/linux/tst-openat2.c diff --git a/NEWS b/NEWS index c2a978b460..073c2a945a 100644 --- a/NEWS +++ b/NEWS @@ -18,6 +18,10 @@ Major new features: * On Linux, the pthread_gettid_np function has been added. +* On Linux, the openat2 function has been added. It is an extension of + openat and provides a superset of its functionality. It is supported only + in LFS mode and it is a cancellable entrypoint. + Deprecated and removed features, and other changes affecting compatibility: [Add deprecations, removals and changes affecting compatibility here] diff --git a/manual/llio.texi b/manual/llio.texi index b6bc7f2210..786ac5b451 100644 --- a/manual/llio.texi +++ b/manual/llio.texi @@ -218,6 +218,106 @@ new, extended API using 64 bit file sizes and offsets transparently replaces the old API. @end deftypefun +@deftp {Data Type} {struct open_how} +@standards{Linux, fcntl.h} +The @code{open_how} structure describes how to open a file using @code{openat2}. + +@strong{Portability note:} In the future, additional fields can be added +to @code{struct open_how} at the end, so that the size of this data +type changes. Do not use it in places where this matters, such as +structure fields in installed header files, where such a change could +impact the application binary interface (ABI). + +The following generic fields are available. + +@table @code +@item flags +This field specifies the file creation and file status flags to use when +opening the file. +All of the @code{O_*} flags defined for @code{openat} are valid. +Different than @code{openat}, @code{openat2} returns an error for unknown +or conflicting values. + +@item mode +This field specifies the mode for the new file, similar to @code{mode} +argument of @code{openat}. Different than @code{openat}, @code{openat2} +returns an error for invalid value (like value larger than @code{07777}). + +@item resolve +This is a bitmask of flags that modify the way in @strong{all} components +of @code{pathname}. It allows trusted programs to restrict how untrusted +paths are resolved. The following generic flags are available. + +@table @code +@item RESOLVE_NO_XDEV +Disallow traversal of mount points during path resolution (including all +bind mounts). +@item RESOLVE_NO_MAGICLINKS +Disallow all @strong{magic-link} resolution during path resolution. Magic +links are simbolic link-like objects that are found in @strong{procfs}; +for example the @code{/proc/pid/exe}. +@item RESOLVE_NO_SYMLINKS +Disallow resolution of symbolic links during path resolution. +This option implies @code{RESOLVE_NO_MAGICLINKS}. +@item RESOLVE_BENEATH +Do not permit the path resolution to succeed if any component of the +resolution is not a descendant of the directory indicated by @code{dirfd}. +@item RESOLVE_IN_ROOT +Treat the directory referred to by @code{dirfd} as the root directory +while resolving the @code{pathname}. +@item RESOLVE_CACHED +Make the open operation fail unless all path components are already +present in the kernel's lookup cache. +@end table + +@end table + +For additional information, consult the manual page @manpageurl{openat2,2}. +@xref{Linux Kernel}. +@end deftp + + +@deftypefun int openat2 (int @var{dirfd}, const char *@var{pathname}, struct open_how @var{how}, size_t @var{size}) +@standards{Linux, fcntl.h} +@safety{@mtsafe{}@assafe{}@acsafe{}} +This function is a extension of the @code{openat} and provides a superset of its +functionality. @xref{Descriptor-Relative Access}. + +The @code{size} define the expected size of @code{how} data structure. +It is recommended to initialize unused fields to zero, either using +@code{memset}, or using a structure initializer. + +On failure, @code{openat2} returns @math{-1} and sets @code{errno}. The +following errors are related the way extensibility is handled. + +@table @code +@item E2BIG +An extension that the kernel does support was specified in @code{how}, +or a larger struct was used with non-zero fields. +@item EAGAIN +@code{how.resolve} contains either RESOLVE_IN_ROOT or RESOLVE_BENEATH, and +the kernel could not ensure that @code{".."} component did not escape. Or +@code{RESOLVE_CACHED} was set, and the open operation cannot be performed +using only cached information. +@item EINVAL +And unknown flag or invalid value was used on @code{how}; or @code{mode} +is non-zero, but @code{how.flags} does not contain @code{O_CREAT} or +@code{O_TMPFILE}, or @code{size} is smaller than the ones supported +by the kernel. +@end table + +It can also return all the errors @code{openat} returns, or other errors +due new fields added by the kernel. + +Similar to @code{openat}, @code{openat2} is a cancellation point. + +@strong{NB:} Different than other open-like functions, the kernel only +provides the LFS variant. When the sources are translated with +@code{_FILE_OFFSET_BITS == 64} this function are not routed a different +symbol. +@end deftypefun + + @deftypefn {Obsolete function} int creat (const char *@var{filename}, mode_t @var{mode}) @standards{POSIX.1, fcntl.h} @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{@acsfd{}}} diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile index dcd87b295e..196b954d5e 100644 --- a/sysdeps/unix/sysv/linux/Makefile +++ b/sysdeps/unix/sysv/linux/Makefile @@ -135,6 +135,7 @@ sysdep_headers += \ bits/mman-linux.h \ bits/mman-map-flags-generic.h \ bits/mman-shared.h \ + bits/openat2.h \ bits/procfs-extra.h \ bits/procfs-id.h \ bits/procfs-prregset.h \ @@ -615,6 +616,7 @@ sysdep_routines += \ internal_statvfs \ open64_nocancel \ open_nocancel \ + openat2 \ openat64_nocancel \ openat_nocancel \ pread64_nocancel \ @@ -635,7 +637,19 @@ tests += \ tst-fallocate64 \ tst-getcwd-smallbuff \ tst-o_path-locks \ + tst-openat2 \ # tests + +tests-special += \ + $(objpfx)tst-openat2-consts.out \ + # tests-special +$(objpfx)tst-openat2-consts.out: ../sysdeps/unix/sysv/linux/tst-openat2-consts.py + $(sysdeps-linux-python) \ + ../sysdeps/unix/sysv/linux/tst-openat2-consts.py \ + $(sysdeps-linux-python-cc) \ + < /dev/null > $@ 2>&1; $(evaluate-test) +$(objpfx)tst-openat2-consts.out: $(sysdeps-linux-python-deps) + endif ifeq ($(subdir),elf) diff --git a/sysdeps/unix/sysv/linux/Versions b/sysdeps/unix/sysv/linux/Versions index 55d565545a..f921f954c1 100644 --- a/sysdeps/unix/sysv/linux/Versions +++ b/sysdeps/unix/sysv/linux/Versions @@ -332,6 +332,9 @@ libc { sched_getattr; sched_setattr; } + GLIBC_2.42 { + openat2; + } GLIBC_PRIVATE { # functions used in other libraries __syscall_rt_sigqueueinfo; diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist index afbb38fb0e..b8025fff19 100644 --- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist +++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist @@ -2751,4 +2751,5 @@ GLIBC_2.39 stdc_trailing_zeros_us F GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F GLIBC_2.42 __inet_ntop_chk F +GLIBC_2.42 openat2 F GLIBC_2.42 pthread_gettid_np F diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist index ea11409903..bbe891adb9 100644 --- a/sysdeps/unix/sysv/linux/alpha/libc.abilist +++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist @@ -3098,6 +3098,7 @@ GLIBC_2.4 wscanf F GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F GLIBC_2.42 __inet_ntop_chk F +GLIBC_2.42 openat2 F GLIBC_2.42 pthread_gettid_np F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F diff --git a/sysdeps/unix/sysv/linux/arc/libc.abilist b/sysdeps/unix/sysv/linux/arc/libc.abilist index c6edd66fe4..27d116b1f6 100644 --- a/sysdeps/unix/sysv/linux/arc/libc.abilist +++ b/sysdeps/unix/sysv/linux/arc/libc.abilist @@ -2512,4 +2512,5 @@ GLIBC_2.39 stdc_trailing_zeros_us F GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F GLIBC_2.42 __inet_ntop_chk F +GLIBC_2.42 openat2 F GLIBC_2.42 pthread_gettid_np F diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist index 00e46c2f7f..c2986f9634 100644 --- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist @@ -2804,6 +2804,7 @@ GLIBC_2.4 xprt_unregister F GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F GLIBC_2.42 __inet_ntop_chk F +GLIBC_2.42 openat2 F GLIBC_2.42 pthread_gettid_np F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist index 3a87471bfe..cb94c6ef17 100644 --- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist @@ -2801,6 +2801,7 @@ GLIBC_2.4 xprt_unregister F GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F GLIBC_2.42 __inet_ntop_chk F +GLIBC_2.42 openat2 F GLIBC_2.42 pthread_gettid_np F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F diff --git a/sysdeps/unix/sysv/linux/bits/fcntl-linux.h b/sysdeps/unix/sysv/linux/bits/fcntl-linux.h index dfc554aafc..3fab352061 100644 --- a/sysdeps/unix/sysv/linux/bits/fcntl-linux.h +++ b/sysdeps/unix/sysv/linux/bits/fcntl-linux.h @@ -453,6 +453,28 @@ extern int name_to_handle_at (int __dfd, const char *__name, extern int open_by_handle_at (int __mountdirfd, struct file_handle *__handle, int __flags); +#ifdef __has_include +# if __has_include ("linux/openat2.h") +# include "linux/openat2.h" +# define __glibc_has_open_how 1 +# endif +#endif + +#include + +/* Similar to `openat' but the arguments are packed on HOW with the size + USIZE. If flags and mode from HOW are non-zero, then openat2 operates + like openat. + + Unlike openat2, unknown or invalid flags result in an error (EINVAL), + rather than being ignored. The mode must be zero unless one O_CREAT + or O_TMPFILE are set. + + The kernel does not support legacy non-LFS interface. */ +extern int openat2 (int __dfd, const char *__filename, struct open_how *__how, + size_t __usize) + __nonnull ((2, 3)); + #endif /* use GNU */ __END_DECLS diff --git a/sysdeps/unix/sysv/linux/bits/openat2.h b/sysdeps/unix/sysv/linux/bits/openat2.h new file mode 100644 index 0000000000..6059095bc1 --- /dev/null +++ b/sysdeps/unix/sysv/linux/bits/openat2.h @@ -0,0 +1,61 @@ +/* openat2 definition. Linux specific. + Copyright (C) 2025 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 + . */ + +#ifndef _FCNTL_H +# error "Never use directly; include instead." +#endif + +#ifndef __glibc_has_open_how +/* Arguments for how openat2 should open the target path. */ +struct open_how +{ + __uint64_t flags; + __uint64_t mode; + __uint64_t resolve; +}; +#endif + +/* how->resolve flags for openat2. */ +#ifndef RESOLVE_NO_XDEV +# define RESOLVE_NO_XDEV 0x01 /* Block mount-point crossings + (includes bind-mounts). */ +#endif +#ifndef RESOLVE_NO_MAGICLINKS +# define RESOLVE_NO_MAGICLINKS 0x02 /* Block traversal through procfs-style + "magic-links". */ +#endif +#ifndef RESOLVE_NO_SYMLINKS +# define RESOLVE_NO_SYMLINKS 0x04 /* Block traversal through all symlinks + (implies OEXT_NO_MAGICLINKS). */ +#endif +#ifndef RESOLVE_BENEATH +# define RESOLVE_BENEATH 0x08 /* Block "lexical" trickery like + "..", symlinks, and absolute + paths which escape the dirfd. */ +#endif +#ifndef RESOLVE_IN_ROOT +# define RESOLVE_IN_ROOT 0x10 /* Make all jumps to "/" and ".." + be scoped inside the dirfd + (similar to chroot). */ +#endif +#ifndef RESOLVE_CACHED +# define RESOLVE_CACHED 0x20 /* Only complete if resolution can be + completed through cached lookup. May + return -EAGAIN if that's not + possible. */ +#endif diff --git a/sysdeps/unix/sysv/linux/csky/libc.abilist b/sysdeps/unix/sysv/linux/csky/libc.abilist index b819f40f50..4c2cf23899 100644 --- a/sysdeps/unix/sysv/linux/csky/libc.abilist +++ b/sysdeps/unix/sysv/linux/csky/libc.abilist @@ -2788,4 +2788,5 @@ GLIBC_2.39 stdc_trailing_zeros_us F GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F GLIBC_2.42 __inet_ntop_chk F +GLIBC_2.42 openat2 F GLIBC_2.42 pthread_gettid_np F diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist index 5cb0987348..02691d63b2 100644 --- a/sysdeps/unix/sysv/linux/hppa/libc.abilist +++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist @@ -2825,6 +2825,7 @@ GLIBC_2.41 cacheflush F GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F GLIBC_2.42 __inet_ntop_chk F +GLIBC_2.42 openat2 F GLIBC_2.42 pthread_gettid_np F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist index 1ec48127e1..62f2ce6652 100644 --- a/sysdeps/unix/sysv/linux/i386/libc.abilist +++ b/sysdeps/unix/sysv/linux/i386/libc.abilist @@ -3008,6 +3008,7 @@ GLIBC_2.4 unshare F GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F GLIBC_2.42 __inet_ntop_chk F +GLIBC_2.42 openat2 F GLIBC_2.42 pthread_gettid_np F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F diff --git a/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist b/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist index 82b6b0d196..1984c1aeee 100644 --- a/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist +++ b/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist @@ -2272,4 +2272,5 @@ GLIBC_2.39 stdc_trailing_zeros_us F GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F GLIBC_2.42 __inet_ntop_chk F +GLIBC_2.42 openat2 F GLIBC_2.42 pthread_gettid_np F diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist index 03818c428f..c0e8c68f49 100644 --- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist @@ -2784,6 +2784,7 @@ GLIBC_2.4 xprt_unregister F GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F GLIBC_2.42 __inet_ntop_chk F +GLIBC_2.42 openat2 F GLIBC_2.42 pthread_gettid_np F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist index a2b3d25f48..987322b027 100644 --- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist @@ -2951,6 +2951,7 @@ GLIBC_2.4 unshare F GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F GLIBC_2.42 __inet_ntop_chk F +GLIBC_2.42 openat2 F GLIBC_2.42 pthread_gettid_np F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist index bc00403c50..e252ec1e3d 100644 --- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist @@ -2837,4 +2837,5 @@ GLIBC_2.39 stdc_trailing_zeros_us F GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F GLIBC_2.42 __inet_ntop_chk F +GLIBC_2.42 openat2 F GLIBC_2.42 pthread_gettid_np F diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist index 5606a7027b..3552870fec 100644 --- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist @@ -2834,4 +2834,5 @@ GLIBC_2.39 stdc_trailing_zeros_us F GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F GLIBC_2.42 __inet_ntop_chk F +GLIBC_2.42 openat2 F GLIBC_2.42 pthread_gettid_np F diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist index 5fab619fd6..f688050cda 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist @@ -2912,6 +2912,7 @@ GLIBC_2.4 unshare F GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F GLIBC_2.42 __inet_ntop_chk F +GLIBC_2.42 openat2 F GLIBC_2.42 pthread_gettid_np F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist index 5ba810d096..74444db817 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist @@ -2907,6 +2907,7 @@ GLIBC_2.4 renameat F GLIBC_2.4 symlinkat F GLIBC_2.4 unlinkat F GLIBC_2.4 unshare F +GLIBC_2.41 openat2 F GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F GLIBC_2.42 __inet_ntop_chk F diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist index e1b8f13414..f21f914c5a 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist @@ -2918,6 +2918,7 @@ GLIBC_2.4 unshare F GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F GLIBC_2.42 __inet_ntop_chk F +GLIBC_2.42 openat2 F GLIBC_2.42 pthread_gettid_np F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist index c0ee223f3f..2272eed24d 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist @@ -2820,6 +2820,7 @@ GLIBC_2.4 unshare F GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F GLIBC_2.42 __inet_ntop_chk F +GLIBC_2.42 openat2 F GLIBC_2.42 pthread_gettid_np F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F diff --git a/sysdeps/unix/sysv/linux/openat2.c b/sysdeps/unix/sysv/linux/openat2.c new file mode 100644 index 0000000000..bb4f3e1f16 --- /dev/null +++ b/sysdeps/unix/sysv/linux/openat2.c @@ -0,0 +1,29 @@ +/* Linux openat2 syscall implementation. + Copyright (C) 2025 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 +#include +#include + +int +__openat2 (int dfd, const char *filename, struct open_how *how, + size_t usize) +{ + return SYSCALL_CANCEL (openat2, dfd, filename, how, usize); +} +weak_alias (__openat2, openat2) diff --git a/sysdeps/unix/sysv/linux/or1k/libc.abilist b/sysdeps/unix/sysv/linux/or1k/libc.abilist index 227746ae57..4e6a759bf8 100644 --- a/sysdeps/unix/sysv/linux/or1k/libc.abilist +++ b/sysdeps/unix/sysv/linux/or1k/libc.abilist @@ -2262,4 +2262,5 @@ GLIBC_2.40 swapcontext F GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F GLIBC_2.42 __inet_ntop_chk F +GLIBC_2.42 openat2 F GLIBC_2.42 pthread_gettid_np F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist index 46fd69dc86..601625c246 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist @@ -3141,6 +3141,7 @@ GLIBC_2.4 wscanf F GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F GLIBC_2.42 __inet_ntop_chk F +GLIBC_2.42 openat2 F GLIBC_2.42 pthread_gettid_np F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist index 9887e117d8..a8150c7b91 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist @@ -3186,6 +3186,7 @@ GLIBC_2.4 wscanf F GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F GLIBC_2.42 __inet_ntop_chk F +GLIBC_2.42 openat2 F GLIBC_2.42 pthread_gettid_np F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist index 2600dc2941..a7b264fb95 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist @@ -2895,6 +2895,7 @@ GLIBC_2.4 wscanf F GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F GLIBC_2.42 __inet_ntop_chk F +GLIBC_2.42 openat2 F GLIBC_2.42 pthread_gettid_np F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist index d803fecff8..06da32a190 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist @@ -2971,4 +2971,5 @@ GLIBC_2.39 stdc_trailing_zeros_us F GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F GLIBC_2.42 __inet_ntop_chk F +GLIBC_2.42 openat2 F GLIBC_2.42 pthread_gettid_np F diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist index a2646bde63..81e6791623 100644 --- a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist +++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist @@ -2515,4 +2515,5 @@ GLIBC_2.40 __riscv_hwprobe F GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F GLIBC_2.42 __inet_ntop_chk F +GLIBC_2.42 openat2 F GLIBC_2.42 pthread_gettid_np F diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist index ad18f29f40..68ad71f3eb 100644 --- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist +++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist @@ -2715,4 +2715,5 @@ GLIBC_2.40 __riscv_hwprobe F GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F GLIBC_2.42 __inet_ntop_chk F +GLIBC_2.42 openat2 F GLIBC_2.42 pthread_gettid_np F diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist index 2f76c27fb9..58dbe0104b 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist @@ -3139,6 +3139,7 @@ GLIBC_2.4 wscanf F GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F GLIBC_2.42 __inet_ntop_chk F +GLIBC_2.42 openat2 F GLIBC_2.42 pthread_gettid_np F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist index 4ea336999c..705c150fca 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist @@ -2932,6 +2932,7 @@ GLIBC_2.4 wscanf F GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F GLIBC_2.42 __inet_ntop_chk F +GLIBC_2.42 openat2 F GLIBC_2.42 pthread_gettid_np F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist index f245f8f755..6b71d91ffb 100644 --- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist @@ -2831,6 +2831,7 @@ GLIBC_2.4 unshare F GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F GLIBC_2.42 __inet_ntop_chk F +GLIBC_2.42 openat2 F GLIBC_2.42 pthread_gettid_np F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist index 4c654a51a3..efbd716ed8 100644 --- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist @@ -2828,6 +2828,7 @@ GLIBC_2.4 unshare F GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F GLIBC_2.42 __inet_ntop_chk F +GLIBC_2.42 openat2 F GLIBC_2.42 pthread_gettid_np F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist index d89a81edcd..ea9347c93c 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist @@ -3160,6 +3160,7 @@ GLIBC_2.4 wscanf F GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F GLIBC_2.42 __inet_ntop_chk F +GLIBC_2.42 openat2 F GLIBC_2.42 pthread_gettid_np F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist index ee7b84249c..67ca148af8 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist @@ -2796,6 +2796,7 @@ GLIBC_2.4 unshare F GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F GLIBC_2.42 __inet_ntop_chk F +GLIBC_2.42 openat2 F GLIBC_2.42 pthread_gettid_np F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F diff --git a/sysdeps/unix/sysv/linux/tst-openat2-consts.py b/sysdeps/unix/sysv/linux/tst-openat2-consts.py new file mode 100755 index 0000000000..9b65d184d7 --- /dev/null +++ b/sysdeps/unix/sysv/linux/tst-openat2-consts.py @@ -0,0 +1,63 @@ +#!/usr/bin/python3 +# Test that glibc's sys/openat2.h constants match the kernel's. +# Copyright (C) 2025 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 +# . + +import argparse +import sys + +import glibcextract +import glibcsyscalls + + +def main(): + """The main entry point.""" + parser = argparse.ArgumentParser( + description="Test that glibc's sys/openat2.h constants " + "match the kernel's.") + parser.add_argument('--cc', metavar='CC', + help='C compiler (including options) to use') + args = parser.parse_args() + + if glibcextract.compile_c_snippet( + '#include ', + args.cc).returncode != 0: + sys.exit (77) + + linux_version_headers = glibcsyscalls.linux_kernel_version(args.cc) + # Constants in glibc were updated to match Linux v6.8. When glibc + # constants are updated this value should be updated to match the + # released kernel version from which the constants were taken. + linux_version_glibc = (6, 8) + def check(cte, exclude=None): + return glibcextract.compare_macro_consts( + '#define _FCNTL_H\n' + '#include \n' + '#include \n', + '#include \n' + '#include \n', + args.cc, + cte, + exclude, + linux_version_glibc > linux_version_headers, + linux_version_headers > linux_version_glibc) + + status = check('RESOLVE.*') + sys.exit(status) + +if __name__ == '__main__': + main() diff --git a/sysdeps/unix/sysv/linux/tst-openat2.c b/sysdeps/unix/sysv/linux/tst-openat2.c new file mode 100644 index 0000000000..34b0a87ced --- /dev/null +++ b/sysdeps/unix/sysv/linux/tst-openat2.c @@ -0,0 +1,259 @@ +/* Linux openat2 tests. + Copyright (C) 2025 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 + . */ + +/* openat2 always return a file descriptor in LFS mode. */ +#define _FILE_OFFSET_BITS 64 + +#include +#include +#include +#include +#include +#include +#include + +static int dir_fd; + +static void +do_prepare (int argc, char *argv[]) +{ + char *temp_dir = support_create_temp_directory ("tst-openat2"); + dir_fd = xopen (temp_dir, O_RDONLY | O_DIRECTORY, 0); +} +#define PREPARE do_prepare + +static int +do_test_struct (void) +{ + static struct struct_test + { + struct open_how_ext + { + struct open_how inner; + int extra1; + int extra2; + int extra3; + } arg; + size_t size; + int err; + } tests[] = + { + { + /* Zero size. */ + .arg.inner.flags = O_RDONLY, + .size = 0, + .err = EINVAL, + }, + { + /* Normal struct. */ + .arg.inner.flags = O_RDONLY, + .size = sizeof (struct open_how), + }, + { + /* Larger struct, zeroed out the unused values. */ + .arg.inner.flags = O_RDONLY, + .size = sizeof (struct open_how_ext), + }, + { + /* Larger struct, non-zeroed out the unused values. */ + .arg.inner.flags = O_RDONLY, + .arg.extra1 = 0xdeadbeef, + .size = sizeof (struct open_how_ext), + .err = E2BIG, + }, + { + /* Larger struct, non-zeroed out the unused values. */ + .arg.inner.flags = O_RDONLY, + .arg.extra2 = 0xdeadbeef, + .size = sizeof (struct open_how_ext), + .err = E2BIG, + }, + }; + + for (struct struct_test *t = tests; t != array_end (tests); t++) + { + int fd = openat2 (AT_FDCWD, ".", (struct open_how *) &t->arg, t->size); + if (fd == -1 && errno == ENOSYS) + FAIL_UNSUPPORTED ("openat2 is not supported by the kernel"); + + if (t->err != 0) + { + TEST_COMPARE (fd, -1); + TEST_COMPARE (errno, t->err); + } + else + TEST_VERIFY (fd >= 0); + } + + return 0; +} + +static int +do_test_flags (void) +{ + static struct flag_test + { + struct open_how how; + int err; + } tests[] = + { + /* O_TMPFILE is incompatible with O_PATH and O_CREAT. */ + { .how.flags = O_TMPFILE | O_PATH | O_RDWR, .err = EINVAL }, + { .how.flags = O_TMPFILE | O_CREAT | O_RDWR, .err = EINVAL }, + + /* O_PATH only permits certain other flags to be set ... */ + { .how.flags = O_PATH | O_CLOEXEC }, + { .how.flags = O_PATH | O_DIRECTORY }, + { .how.flags = O_PATH | O_NOFOLLOW }, + /* ... and others are absolutely not permitted. */ + { .how.flags = O_PATH | O_RDWR, .err = EINVAL }, + { .how.flags = O_PATH | O_CREAT, .err = EINVAL }, + { .how.flags = O_PATH | O_EXCL, .err = EINVAL }, + { .how.flags = O_PATH | O_NOCTTY, .err = EINVAL }, + { .how.flags = O_PATH | O_DIRECT, .err = EINVAL }, + + /* ->mode must only be set with O_{CREAT,TMPFILE}. */ + { .how.flags = O_RDONLY, .how.mode = 0600, .err = EINVAL }, + { .how.flags = O_PATH, .how.mode = 0600, .err = EINVAL }, + { .how.flags = O_CREAT, .how.mode = 0600 }, + { .how.flags = O_TMPFILE | O_RDWR, .how.mode = 0600 }, + /* ->mode must only contain 0777 bits. */ + { .how.flags = O_CREAT, .how.mode = 0xFFFF, .err = EINVAL }, + { .how.flags = O_CREAT, .how.mode = 0xC000000000000000ULL, .err = EINVAL }, + { .how.flags = O_TMPFILE | O_RDWR, .how.mode = 0x1337, .err = EINVAL }, + { .how.flags = O_TMPFILE | O_RDWR, .how.mode = 0x0000A00000000000ULL, + .err = EINVAL }, + + /* ->resolve flags must not conflict. */ + { .how.flags = O_RDONLY, + .how.resolve = RESOLVE_BENEATH | RESOLVE_IN_ROOT, + .err = EINVAL }, + + /* ->resolve must only contain RESOLVE_* flags. */ + { .how.flags = O_RDONLY, + .how.resolve = 0x1337, .err = EINVAL }, + { .how.flags = O_CREAT, + .how.resolve = 0x1337, .err = EINVAL }, + { .how.flags = O_TMPFILE | O_RDWR, + .how.resolve = 0x1337, .err = EINVAL }, + { .how.flags = O_PATH, + .how.resolve = 0x1337, .err = EINVAL }, + + /* currently unknown upper 32 bit rejected. */ + { .how.flags = O_RDONLY | (1ULL << 63), + .how.resolve = 0, .err = EINVAL }, + }; + + for (struct flag_test *t = tests; t != array_end (tests); t++) + { + char *path; + if (t->how.flags & O_CREAT) + { + int temp_fd = create_temp_file ("tst-openat2.", &path); + TEST_VERIFY_EXIT (temp_fd != -1); + xunlink (path); + } + else + path = (char *) "."; + + int fd = openat2 (AT_FDCWD, path, &t->how, sizeof (struct open_how)); + if (fd != 0 && errno == EOPNOTSUPP) + { + /* Skip the testcase if FS does not support the operation (e.g. + valid O_TMPFILE on NFS). */ + continue; + } + + if (t->err != 0) + { + TEST_COMPARE (fd, -1); + TEST_COMPARE (errno, t->err); + } + else + TEST_VERIFY (fd >= 0); + } + + return 0; +} + +static int +do_test_basic (void) +{ + int fd; + + fd = openat2 (dir_fd, + "some-file", + &(struct open_how) + { + .flags = O_CREAT|O_RDWR|O_EXCL, + .mode = 0666, + }, + sizeof (struct open_how)); + TEST_VERIFY (fd != -1); + + xwrite (fd, "hello", 5); + + /* Before closing the file, try using this file descriptor to open + another file. This must fail. */ + { + int fd2 = openat2 (fd, + "should-not-work", + &(struct open_how) + { + .flags = O_CREAT|O_RDWR|O_EXCL, + .mode = 0666, + }, + sizeof (struct open_how)); + TEST_COMPARE (fd2, -1); + TEST_COMPARE (errno, ENOTDIR); + } + + /* Remove the created file. */ + int cwdfd = xopen (".", O_RDONLY | O_DIRECTORY, 0); + TEST_COMPARE (fchdir (dir_fd), 0); + xunlink ("some-file"); + TEST_COMPARE (fchdir (cwdfd), 0); + + xclose (dir_fd); + xclose (cwdfd); + + fd = openat2 (dir_fd, + "some-file", + &(struct open_how) + { + .flags = O_CREAT|O_RDWR|O_EXCL, + .mode = 0666, + }, + sizeof (struct open_how)); + TEST_COMPARE (fd, -1); + TEST_COMPARE (errno, EBADF); + + return 0; +} + +static int +do_test (void) +{ + do_test_struct (); + do_test_flags (); + do_test_basic (); + + return 0; +} + +#include diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist index 00155d9f3e..640c4f838d 100644 --- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist @@ -2747,6 +2747,7 @@ GLIBC_2.4 unshare F GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F GLIBC_2.42 __inet_ntop_chk F +GLIBC_2.42 openat2 F GLIBC_2.42 pthread_gettid_np F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist index 18765ec3b8..f309892e5d 100644 --- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist @@ -2766,4 +2766,5 @@ GLIBC_2.39 stdc_trailing_zeros_us F GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F GLIBC_2.42 __inet_ntop_chk F +GLIBC_2.42 openat2 F GLIBC_2.42 pthread_gettid_np F