commit:     7a3367cb3e59695a43a7e7ae0c5c94e74646412e
Author:     Nicolas PARLANT <nicolas.parlant <AT> parhuet <DOT> fr>
AuthorDate: Mon Jul  7 11:02:18 2025 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Tue Jul  8 19:31:51 2025 +0000
URL:        https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=7a3367cb

app-containers/apptainer: backport patches for c23

export PKG_CONFIG for seccomp

Closes: https://bugs.gentoo.org/934988
Closes: https://bugs.gentoo.org/946063
Signed-off-by: Nicolas PARLANT <nicolas.parlant <AT> parhuet.fr>
Part-of: https://github.com/gentoo/gentoo/pull/42928
Signed-off-by: Sam James <sam <AT> gentoo.org>

 app-containers/apptainer/apptainer-1.3.6.ebuild    |   2 +
 .../apptainer/files/apptainer-1.3.6-fix_c23.patch  | 468 +++++++++++++++++++++
 2 files changed, 470 insertions(+)

diff --git a/app-containers/apptainer/apptainer-1.3.6.ebuild 
b/app-containers/apptainer/apptainer-1.3.6.ebuild
index 3d00ec1de151..8244ef0dc076 100644
--- a/app-containers/apptainer/apptainer-1.3.6.ebuild
+++ b/app-containers/apptainer/apptainer-1.3.6.ebuild
@@ -35,11 +35,13 @@ CONFIG_CHECK="~SQUASHFS"
 
 PATCHES=(
        "${FILESDIR}"/${PN}-1.0.2-trim_upstream_cflags.patch
+       "${FILESDIR}"/${P}-fix_c23.patch
 )
 
 DOCS=( README.md CONTRIBUTORS.md CONTRIBUTING.md )
 
 src_configure() {
+       tc-export PKG_CONFIG
        local myconfargs=(
                -c "$(tc-getBUILD_CC)" \
                -x "$(tc-getBUILD_CXX)" \

diff --git a/app-containers/apptainer/files/apptainer-1.3.6-fix_c23.patch 
b/app-containers/apptainer/files/apptainer-1.3.6-fix_c23.patch
new file mode 100644
index 000000000000..2d77883c9a41
--- /dev/null
+++ b/app-containers/apptainer/files/apptainer-1.3.6-fix_c23.patch
@@ -0,0 +1,468 @@
+backport patches from upstream for c23
+From 27a6e9a5ac6f9241779dbb3125f02c6f0efc819c Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?S=C3=B6ren=20Tempel?= <[email protected]>
+Date: Sun, 12 May 2024 17:28:54 +0200
+Subject: [PATCH] pkg/unshare: fix implicit declaration of basename function
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+POSIX requires the prototype of the basename function to be declared
+in the libgen.h header file. Therefore, this header file needs to be
+included in order to make use of this function in a POSIX environment.
+
+Some implementations, e.g. glibc, also define this function in string.h.
+However, musl (for example) only defines it in libgen.h causing it be
+implicitly declared (with an `int` return type) which is by no means
+cosmetic and can lead to severe miscompilations.
+
+Signed-off-by: Sören Tempel <[email protected]>
+---
+ pkg/unshare/unshare.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/pkg/unshare/unshare.c b/pkg/unshare/unshare.c
+index f5a7c3a259..a2800654f9 100644
+--- a/vendor/github.com/containers/storage/pkg/unshare/unshare.c
++++ b/vendor/github.com/containers/storage/pkg/unshare//unshare.c
+@@ -15,6 +15,7 @@
+ #include <termios.h>
+ #include <errno.h>
+ #include <unistd.h>
++#include <libgen.h>
+ #include <sys/vfs.h>
+ #include <sys/mount.h>
+ #include <linux/limits.h>
+From e99c9bcaa6e7b510f101ddcb6c6be9ac0b7ca072 Mon Sep 17 00:00:00 2001
+From: Dave Dykstra <[email protected]>
+Date: Wed, 22 Jan 2025 12:22:57 -0600
+Subject: [PATCH] work around c23 bool restriction
+
+Signed-off-by: Dave Dykstra <[email protected]>
+---
+ cmd/starter/c/include/starter.h               | 24 ++++----
+ cmd/starter/c/starter.c                       | 56 +++++++++----------
+ .../engine/config/starter/starter_linux.go    | 46 +++++++--------
+ 3 files changed, 63 insertions(+), 63 deletions(-)
+
+diff --git a/cmd/starter/c/include/starter.h b/cmd/starter/c/include/starter.h
+index c62274c714..5dabc49408 100644
+--- a/cmd/starter/c/include/starter.h
++++ b/cmd/starter/c/include/starter.h
+@@ -74,9 +74,9 @@ enum goexec {
+ #endif
+ 
+ typedef enum {
+-    false,
+-    true
+-} bool;
++    False,
++    True
++} Bool;
+ 
+ /* container capabilities */
+ struct capabilities {
+@@ -94,9 +94,9 @@ struct namespace {
+     /* container mount namespace propagation */
+     unsigned long mountPropagation;
+     /* namespace join only */
+-    bool joinOnly;
++    Bool joinOnly;
+     /* should bring up loopback interface with network namespace */
+-    bool bringLoopbackInterface;
++    Bool bringLoopbackInterface;
+ 
+     /* namespaces inodes paths used to join namespaces */
+     char network[MAX_PATH_SIZE];
+@@ -111,12 +111,12 @@ struct namespace {
+ /* container privileges */
+ struct privileges {
+     /* value for PR_SET_NO_NEW_PRIVS */
+-    bool noNewPrivs;
++    Bool noNewPrivs;
+ 
+     /* user namespace mappings and setgroups control */
+     char uidMap[MAX_MAP_SIZE];
+     char gidMap[MAX_MAP_SIZE];
+-    bool allowSetgroups;
++    Bool allowSetgroups;
+ 
+     /* path to external newuidmap/newgidmap binaries */
+     char newuidmapPath[MAX_PATH_SIZE];
+@@ -136,7 +136,7 @@ struct container {
+     /* container process ID */
+     pid_t pid;
+     /* is container will run as instance */
+-    bool isInstance;
++    Bool isInstance;
+ 
+     /* container privileges */
+     struct privileges privileges;
+@@ -154,14 +154,14 @@ struct starter {
+     int numfds;
+ 
+     /* is starter run as setuid */
+-    bool isSuid;
++    Bool isSuid;
+     /* master process will share a mount namespace for container mount 
propagation */
+-    bool masterPropagateMount;
++    Bool masterPropagateMount;
+     /* hybrid workflow where master process and container doesn't share user 
namespace */
+-    bool hybridWorkflow;
++    Bool hybridWorkflow;
+ 
+     /* bounding capability set will include caps needed by 
nvidia-container-cli */
+-    bool nvCCLICaps;
++    Bool nvCCLICaps;
+ };
+ 
+ /* engine configuration */
+diff --git a/cmd/starter/c/starter.c b/cmd/starter/c/starter.c
+index caf0b7c2f0..a651edd12a 100644
+--- a/cmd/starter/c/starter.c
++++ b/cmd/starter/c/starter.c
+@@ -115,7 +115,7 @@ __attribute__ ((returns_twice)) __attribute__((noinline)) 
static int fork_ns(uns
+     return clone(clone_fn, child_stack.ptr, (SIGCHLD|flags), env);
+ }
+ 
+-static void priv_escalate(bool keep_fsuid) {
++static void priv_escalate(Bool keep_fsuid) {
+     uid_t uid = getuid();
+ 
+     verbosef("Get root privileges\n");
+@@ -144,7 +144,7 @@ static void priv_escalate(bool keep_fsuid) {
+     }
+ }
+ 
+-static void priv_drop(bool permanent) {
++static void priv_drop(Bool permanent) {
+     uid_t uid = getuid();
+     gid_t gid = getgid();
+ 
+@@ -176,12 +176,12 @@ static void set_parent_death_signal(int signo) {
+ }
+ 
+ /* helper to check if namespace flag is set */
+-static inline bool is_namespace_create(struct namespace *nsconfig, unsigned 
int nsflag) {
++static inline Bool is_namespace_create(struct namespace *nsconfig, unsigned 
int nsflag) {
+     return (nsconfig->flags & nsflag) != 0;
+ }
+ 
+ /* helper to check if the corresponding namespace need to be joined */
+-static bool is_namespace_enter(const char *nspath, const char *selfns) {
++static Bool is_namespace_enter(const char *nspath, const char *selfns) {
+     if ( selfns != NULL && nspath[0] != 0 ) {
+         struct stat selfns_st;
+         struct stat ns_st;
+@@ -197,17 +197,17 @@ static bool is_namespace_enter(const char *nspath, const 
char *selfns) {
+             if ( errno != ENOENT ) {
+                 debugf("Could not stat %s: %s\n", selfns, strerror(errno));
+             }
+-            return false;
++            return False;
+         }
+         if ( stat(nspath, &ns_st) < 0 ) {
+             if ( errno != ENOENT ) {
+                 debugf("Could not stat %s: %s\n", nspath, strerror(errno));
+             }
+-            return false;
++            return False;
+         }
+         /* same namespace, don't join */
+         if ( selfns_st.st_ino == ns_st.st_ino ) {
+-            return false;
++            return False;
+         }
+     }
+     return nspath[0] != 0;
+@@ -809,7 +809,7 @@ static int cgroup_namespace_init(struct namespace 
*nsconfig) {
+     }
+ }
+ 
+-static int mount_namespace_init(struct namespace *nsconfig, bool 
masterPropagateMount) {
++static int mount_namespace_init(struct namespace *nsconfig, Bool 
masterPropagateMount) {
+     if ( is_namespace_enter(nsconfig->mount, SELF_MNT_NS) ) {
+         if ( enter_namespace(nsconfig->mount, CLONE_NEWNS) < 0 ) {
+             fatalf("Failed to enter in mount namespace: %s\n", 
strerror(errno));
+@@ -867,10 +867,10 @@ static int shared_mount_namespace_init(struct namespace 
*nsconfig) {
+ }
+ 
+ /*
+- * is_suid returns true if this binary has suid bit set or if it
++ * is_suid returns True if this binary has suid bit set or if it
+  * has additional capabilities in extended file attributes
+  */
+-static bool is_suid(void) {
++static Bool is_suid(void) {
+     unsigned long auxval;
+ 
+     errno = 0;
+@@ -954,7 +954,7 @@ static void cleanup_fd(fdlist_t *master, struct starter 
*starter) {
+     DIR *dir;
+     struct dirent *dirent;
+     int i, fd;
+-    bool found;
++    Bool found;
+ 
+     if ( ( fd_proc = open("/proc/self/fd", O_RDONLY) ) < 0 ) {
+         fatalf("Failed to open /proc/self/fd: %s\n", strerror(errno));
+@@ -973,12 +973,12 @@ static void cleanup_fd(fdlist_t *master, struct starter 
*starter) {
+             continue;
+         }
+ 
+-        found = false;
++        found = False;
+ 
+         /* check if the file descriptor was open before stage 1 execution */
+         for ( i = 0; i < master->num; i++ ) {
+             if ( master->fds[i] == fd ) {
+-                found = true;
++                found = True;
+                 break;
+             }
+         }
+@@ -986,12 +986,12 @@ static void cleanup_fd(fdlist_t *master, struct starter 
*starter) {
+             continue;
+         }
+ 
+-        found = false;
++        found = False;
+ 
+         /* check if the file descriptor need to remain opened */
+         for ( i = 0; i < starter->numfds; i++ ) {
+             if ( starter->fds[i] == fd ) {
+-                found = true;
++                found = True;
+                 /* set force close on exec */
+                 if ( fcntl(starter->fds[i], F_SETFD, FD_CLOEXEC) < 0 ) {
+                     debugf("Can't set FD_CLOEXEC on file descriptor %d: 
%s\n", starter->fds[i], strerror(errno));
+@@ -1094,7 +1094,7 @@ static void fix_userns_devfuse_fd(struct starter 
*starter) {
+     }
+ }
+ 
+-static void wait_child(const char *name, pid_t child_pid, bool noreturn) {
++static void wait_child(const char *name, pid_t child_pid, Bool noreturn) {
+     int status;
+     int exit_status = 0;
+ 
+@@ -1263,7 +1263,7 @@ __attribute__((constructor)) static void init(void) {
+ 
+     /* temporarily drop privileges while running as setuid */
+     if ( sconfig->starter.isSuid ) {
+-        priv_drop(false);
++        priv_drop(False);
+     }
+ 
+     /* retrieve engine configuration from environment variables */
+@@ -1298,7 +1298,7 @@ __attribute__((constructor)) static void init(void) {
+          */
+         if ( sconfig->starter.isSuid ) {
+             /* drop privileges permanently */
+-            priv_drop(true);
++            priv_drop(True);
+         }
+         set_parent_death_signal(SIGKILL);
+         verbosef("Spawn stage 1\n");
+@@ -1310,7 +1310,7 @@ __attribute__((constructor)) static void init(void) {
+     }
+ 
+     debugf("Wait completion of stage1\n");
+-    wait_child("stage 1", process, false);
++    wait_child("stage 1", process, False);
+ 
+     /* change current working directory if requested by stage 1 */
+     if ( sconfig->starter.workingDirectoryFd >= 0 ) {
+@@ -1369,7 +1369,7 @@ __attribute__((constructor)) static void init(void) {
+                 fatalf("Unblock signals error: %s\n", strerror(errno));
+             }
+             /* loop until master process exits with error */
+-            wait_child("instance", process, true);
++            wait_child("instance", process, True);
+ 
+             /* we should never return from the previous wait_child call */
+             exit(1);
+@@ -1412,7 +1412,7 @@ __attribute__((constructor)) static void init(void) {
+          * this will fail if starter is run without suid
+          */
+         if ( sconfig->starter.isSuid ) {
+-            priv_escalate(true);
++            priv_escalate(True);
+         } else if ( uid != 0 ) {
+             fatalf("Installation issue: starter-suid doesn't have setuid bit 
set\n");
+         }
+@@ -1489,10 +1489,10 @@ __attribute__((constructor)) static void init(void) {
+             if ( wait_event(master_socket[1]) < 0 ) {
+                 fatalf("Error while waiting event for shared mount 
namespace\n");
+             }
+-            mount_namespace_init(&sconfig->container.namespace, true);
++            mount_namespace_init(&sconfig->container.namespace, True);
+         } else {
+             send_event(master_socket[1]);
+-            mount_namespace_init(&sconfig->container.namespace, false);
++            mount_namespace_init(&sconfig->container.namespace, False);
+         }
+ 
+         if ( !sconfig->container.namespace.joinOnly ) {
+@@ -1518,7 +1518,7 @@ __attribute__((constructor)) static void init(void) {
+                 close(rpc_socket[1]);
+ 
+                 /* wait RPC server exits before running container process */
+-                wait_child("rpc server", process, false);
++                wait_child("rpc server", process, False);
+ 
+                 if ( sconfig->starter.hybridWorkflow && 
sconfig->starter.isSuid ) {
+                     /* make /proc/self readable by user to join instance 
without SUID workflow */
+@@ -1584,7 +1584,7 @@ __attribute__((constructor)) static void init(void) {
+                      * user mappings setup. User filesystem UID will be 
restored below by setresuid
+                      * call.
+                      */
+-                    priv_escalate(false);
++                    priv_escalate(False);
+                     chdir_to_proc_pid(sconfig->container.pid);
+                     setup_userns_mappings(&sconfig->container.privileges);
+                 } else {
+@@ -1611,7 +1611,7 @@ __attribute__((constructor)) static void init(void) {
+         /* wait child finish namespaces initialization */
+         if ( wait_event(master_socket[0]) < 0 ) {
+             /* child has exited before sending data */
+-            wait_child("stage 2", sconfig->container.pid, true);
++            wait_child("stage 2", sconfig->container.pid, True);
+         }
+ 
+         /* engine requested to propagate mount to container */
+@@ -1669,11 +1669,11 @@ __attribute__((constructor)) static void init(void) {
+         if ( sconfig->container.namespace.joinOnly ) {
+             /* joining container, don't execute Go runtime, just wait that 
container process exit */
+             if ( sconfig->starter.isSuid ) {
+-                priv_drop(true);
++                priv_drop(True);
+             }
+             debugf("Wait stage 2 child process\n");
+             release_memory(sconfig);
+-            wait_child("stage 2", process, true);
++            wait_child("stage 2", process, True);
+         } else {
+             /* close container end of rpc communication socket */
+             close(rpc_socket[1]);
+diff --git a/internal/pkg/runtime/engine/config/starter/starter_linux.go 
b/internal/pkg/runtime/engine/config/starter/starter_linux.go
+index 9c42c68a4e..737f7114a8 100644
+--- a/internal/pkg/runtime/engine/config/starter/starter_linux.go
++++ b/internal/pkg/runtime/engine/config/starter/starter_linux.go
+@@ -55,10 +55,10 @@ func NewConfig(config SConfig) *Config {
+       }
+ }
+ 
+-// GetIsSUID returns true if the SUID workflow is enabled.
++// GetIsSUID returns True if the SUID workflow is enabled.
+ // This field is set by starter at the very beginning of its execution.
+ func (c *Config) GetIsSUID() bool {
+-      return c.config.starter.isSuid == C.true
++      return c.config.starter.isSuid == C.True
+ }
+ 
+ // GetContainerPid returns the container PID (if any).
+@@ -68,54 +68,54 @@ func (c *Config) GetContainerPid() int {
+ }
+ 
+ // SetInstance changes starter config so that it will spawn an instance
+-// instead of a regular container if the passed value is true.
++// instead of a regular container if the passed value is True.
+ func (c *Config) SetInstance(instance bool) {
+       if instance {
+-              c.config.container.isInstance = C.true
++              c.config.container.isInstance = C.True
+       } else {
+-              c.config.container.isInstance = C.false
++              c.config.container.isInstance = C.False
+       }
+ }
+ 
+ // SetNoNewPrivs changes starter config so that it will set NO_NEW_PRIVS
+-// flag for a container before it starts up if noprivs is true.
++// flag for a container before it starts up if noprivs is True.
+ func (c *Config) SetNoNewPrivs(noprivs bool) {
+       if noprivs {
+-              c.config.container.privileges.noNewPrivs = C.true
++              c.config.container.privileges.noNewPrivs = C.True
+       } else {
+-              c.config.container.privileges.noNewPrivs = C.false
++              c.config.container.privileges.noNewPrivs = C.False
+       }
+ }
+ 
+ // SetMasterPropagateMount changes starter config so that the mount 
propagation
+ // between master (process that monitors container) and a container itself
+-// is set to MS_SHARED if propagate is true.
++// is set to MS_SHARED if propagate is True.
+ func (c *Config) SetMasterPropagateMount(propagate bool) {
+       if propagate {
+-              c.config.starter.masterPropagateMount = C.true
++              c.config.starter.masterPropagateMount = C.True
+       } else {
+-              c.config.starter.masterPropagateMount = C.false
++              c.config.starter.masterPropagateMount = C.False
+       }
+ }
+ 
+ // SetNamespaceJoinOnly changes starter config so that the created process
+ // will join an already running container (used for `apptainer shell` and
+-// `apptainer oci exec`) if join is true.
++// `apptainer oci exec`) if join is True.
+ func (c *Config) SetNamespaceJoinOnly(join bool) {
+       if join {
+-              c.config.container.namespace.joinOnly = C.true
++              c.config.container.namespace.joinOnly = C.True
+       } else {
+-              c.config.container.namespace.joinOnly = C.false
++              c.config.container.namespace.joinOnly = C.False
+       }
+ }
+ 
+ // SetBringLoopbackInterface changes starter config so that it will bring up
+-// a loopback network interface during container creation if bring is true.
++// a loopback network interface during container creation if bring is True.
+ func (c *Config) SetBringLoopbackInterface(bring bool) {
+       if bring {
+-              c.config.container.namespace.bringLoopbackInterface = C.true
++              c.config.container.namespace.bringLoopbackInterface = C.True
+       } else {
+-              c.config.container.namespace.bringLoopbackInterface = C.false
++              c.config.container.namespace.bringLoopbackInterface = C.False
+       }
+ }
+ 
+@@ -166,9 +166,9 @@ func (c *Config) KeepFileDescriptor(fd int) error {
+ // nvidia-container-cli
+ func (c *Config) SetNvCCLICaps(enabled bool) {
+       if enabled {
+-              c.config.starter.nvCCLICaps = C.true
++              c.config.starter.nvCCLICaps = C.True
+       } else {
+-              c.config.starter.nvCCLICaps = C.false
++              c.config.starter.nvCCLICaps = C.False
+       }
+ }
+ 
+@@ -179,18 +179,18 @@ func (c *Config) SetNvCCLICaps(enabled bool) {
+ // lives in its own user namespace.
+ func (c *Config) SetHybridWorkflow(hybrid bool) {
+       if hybrid {
+-              c.config.starter.hybridWorkflow = C.true
++              c.config.starter.hybridWorkflow = C.True
+       } else {
+-              c.config.starter.hybridWorkflow = C.false
++              c.config.starter.hybridWorkflow = C.False
+       }
+ }
+ 
+ // SetAllowSetgroups allows use of setgroups syscall from user namespace.
+ func (c *Config) SetAllowSetgroups(allow bool) {
+       if allow {
+-              c.config.container.privileges.allowSetgroups = C.true
++              c.config.container.privileges.allowSetgroups = C.True
+       } else {
+-              c.config.container.privileges.allowSetgroups = C.false
++              c.config.container.privileges.allowSetgroups = C.False
+       }
+ }
+ 

Reply via email to