Complete Yocto mirror with license table for TQMa6UL (2038-compliance)
- 264 license table entries with exact download URLs (224/264 resolved) - Complete sources/ directory with all BitBake recipes - Build configuration: tqma6ul-multi-mba6ulx, spaetzle (musl) - Full traceability for Softwarefreigabeantrag - GCC 13.4.0, Linux 6.6.102, U-Boot 2023.04, musl 1.2.4 - License distribution: GPL-2.0 (24), MIT (23), GPL-2.0+ (18), BSD-3 (16)
This commit is contained in:
@@ -0,0 +1,187 @@
|
||||
From 592d84e1265d04c3104acee815a503856db503a1 Mon Sep 17 00:00:00 2001
|
||||
From: Olivier Bal-Petre <olivier.bal-petre@ssi.gouv.fr>
|
||||
Date: Tue, 4 Mar 2025 14:37:02 +0100
|
||||
Subject: [PATCH] pam_namespace: add flags to indicate path safety
|
||||
|
||||
Add two flags in the script to indicate if the paths to the polydir
|
||||
and the instance directories are safe (root owned and writable by
|
||||
root only).
|
||||
|
||||
Signed-off-by: Olivier Bal-Petre <olivier.bal-petre@ssi.gouv.fr>
|
||||
Signed-off-by: Dmitry V. Levin <ldv@strace.io>
|
||||
|
||||
Upstream-Status: Backport [https://github.com/linux-pam/linux-pam/commit/592d84e1265d04c3104acee815a503856db503a1]
|
||||
CVE: CVE-2025-6020
|
||||
Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
|
||||
---
|
||||
modules/pam_namespace/namespace.init | 56 ++++++++++++-------
|
||||
modules/pam_namespace/pam_namespace.c | 79 ++++++++++++++++++++++++++-
|
||||
2 files changed, 115 insertions(+), 20 deletions(-)
|
||||
|
||||
diff --git a/modules/pam_namespace/namespace.init b/modules/pam_namespace/namespace.init
|
||||
index d9053a1..8782178 100755
|
||||
--- a/modules/pam_namespace/namespace.init
|
||||
+++ b/modules/pam_namespace/namespace.init
|
||||
@@ -1,25 +1,43 @@
|
||||
#!/bin/sh
|
||||
-# It receives polydir path as $1, the instance path as $2,
|
||||
-# a flag whether the instance dir was newly created (0 - no, 1 - yes) in $3,
|
||||
-# and user name in $4.
|
||||
+# It receives as arguments:
|
||||
+# - $1 polydir path (see WARNING below)
|
||||
+# - $2 instance path (see WARNING below)
|
||||
+# - $3 flag whether the instance dir was newly created (0 - no, 1 - yes)
|
||||
+# - $4 user name
|
||||
+# - $5 flag whether the polydir path ($1) is safe (0 - unsafe, 1 -safe)
|
||||
+# - $6 flag whether the instance path ($2) is safe (0 - unsafe, 1 - safe)
|
||||
+#
|
||||
+# WARNING: This script is invoked with full root privileges. Accessing
|
||||
+# the polydir ($1) and the instance ($2) directories in this context may be
|
||||
+# extremely dangerous as those can be under user control. The flags $5 and $6
|
||||
+# are provided to let you know if all the segments part of the path (except the
|
||||
+# last one) are owned by root and are writable by root only. If the path does
|
||||
+# not meet these criteria, you expose yourself to possible symlink attacks when
|
||||
+# accessing these path.
|
||||
+# However, even if the path components are safe, the content of the
|
||||
+# directories may still be owned/writable by a user, so care must be taken!
|
||||
#
|
||||
# The following section will copy the contents of /etc/skel if this is a
|
||||
# newly created home directory.
|
||||
-if [ "$3" = 1 ]; then
|
||||
- # This line will fix the labeling on all newly created directories
|
||||
- [ -x /sbin/restorecon ] && /sbin/restorecon "$1"
|
||||
- user="$4"
|
||||
- passwd=$(getent passwd "$user")
|
||||
- homedir=$(echo "$passwd" | cut -f6 -d":")
|
||||
- if [ "$1" = "$homedir" ]; then
|
||||
- gid=$(echo "$passwd" | cut -f4 -d":")
|
||||
- cp -rT /etc/skel "$homedir"
|
||||
- chown -R "$user":"$gid" "$homedir"
|
||||
- mask=$(awk '/^UMASK/{gsub("#.*$", "", $2); print $2; exit}' /etc/login.defs)
|
||||
- mode=$(printf "%o" $((0777 & ~mask)))
|
||||
- chmod ${mode:-700} "$homedir"
|
||||
- [ -x /sbin/restorecon ] && /sbin/restorecon -R "$homedir"
|
||||
- fi
|
||||
-fi
|
||||
|
||||
+# Executes only if the polydir path is safe
|
||||
+if [ "$5" = 1 ]; then
|
||||
+
|
||||
+ if [ "$3" = 1 ]; then
|
||||
+ # This line will fix the labeling on all newly created directories
|
||||
+ [ -x /sbin/restorecon ] && /sbin/restorecon "$1"
|
||||
+ user="$4"
|
||||
+ passwd=$(getent passwd "$user")
|
||||
+ homedir=$(echo "$passwd" | cut -f6 -d":")
|
||||
+ if [ "$1" = "$homedir" ]; then
|
||||
+ gid=$(echo "$passwd" | cut -f4 -d":")
|
||||
+ cp -rT /etc/skel "$homedir"
|
||||
+ chown -R "$user":"$gid" "$homedir"
|
||||
+ mask=$(sed -E -n 's/^UMASK[[:space:]]+([^#[:space:]]+).*/\1/p' /etc/login.defs)
|
||||
+ mode=$(printf "%o" $((0777 & ~mask)))
|
||||
+ chmod ${mode:-700} "$homedir"
|
||||
+ [ -x /sbin/restorecon ] && /sbin/restorecon -R "$homedir"
|
||||
+ fi
|
||||
+ fi
|
||||
+fi
|
||||
exit 0
|
||||
diff --git a/modules/pam_namespace/pam_namespace.c b/modules/pam_namespace/pam_namespace.c
|
||||
index 9d993d4..4c8153b 100644
|
||||
--- a/modules/pam_namespace/pam_namespace.c
|
||||
+++ b/modules/pam_namespace/pam_namespace.c
|
||||
@@ -1467,6 +1467,79 @@ static int check_inst_parent(int dfd, struct instance_data *idata)
|
||||
return PAM_SUCCESS;
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Check for a given absolute path that all segments except the last one are:
|
||||
+ * 1. a directory owned by root and not writable by group or others
|
||||
+ * 2. a symlink owned by root and referencing a directory respecting 1.
|
||||
+ * Returns 0 if safe, -1 is unsafe.
|
||||
+ * If the path is not accessible (does not exist, hidden under a mount...),
|
||||
+ * returns -1 (unsafe).
|
||||
+ */
|
||||
+static int check_safe_path(const char *path, struct instance_data *idata)
|
||||
+{
|
||||
+ char *p = strdup(path);
|
||||
+ char *d;
|
||||
+ char *dir = p;
|
||||
+ struct stat st;
|
||||
+
|
||||
+ if (p == NULL)
|
||||
+ return -1;
|
||||
+
|
||||
+ /* Check path is absolute */
|
||||
+ if (p[0] != '/')
|
||||
+ goto error;
|
||||
+
|
||||
+ strip_trailing_slashes(p);
|
||||
+
|
||||
+ /* Last segment of the path may be owned by the user */
|
||||
+ if ((d = strrchr(dir, '/')) != NULL)
|
||||
+ *d = '\0';
|
||||
+
|
||||
+ while ((d=strrchr(dir, '/')) != NULL) {
|
||||
+
|
||||
+ /* Do not follow symlinks */
|
||||
+ if (lstat(dir, &st) != 0)
|
||||
+ goto error;
|
||||
+
|
||||
+ if (S_ISLNK(st.st_mode)) {
|
||||
+ if (st.st_uid != 0) {
|
||||
+ if (idata->flags & PAMNS_DEBUG)
|
||||
+ pam_syslog(idata->pamh, LOG_DEBUG,
|
||||
+ "Path deemed unsafe: Symlink %s should be owned by root", dir);
|
||||
+ goto error;
|
||||
+ }
|
||||
+
|
||||
+ /* Follow symlinks */
|
||||
+ if (stat(dir, &st) != 0)
|
||||
+ goto error;
|
||||
+ }
|
||||
+
|
||||
+ if (!S_ISDIR(st.st_mode)) {
|
||||
+ if (idata->flags & PAMNS_DEBUG)
|
||||
+ pam_syslog(idata->pamh, LOG_DEBUG,
|
||||
+ "Path deemed unsafe: %s is expected to be a directory", dir);
|
||||
+ goto error;
|
||||
+ }
|
||||
+
|
||||
+ if (st.st_uid != 0 ||
|
||||
+ ((st.st_mode & (S_IWGRP|S_IWOTH)) && !(st.st_mode & S_ISVTX))) {
|
||||
+ if (idata->flags & PAMNS_DEBUG)
|
||||
+ pam_syslog(idata->pamh, LOG_DEBUG,
|
||||
+ "Path deemed unsafe: %s should be owned by root, and not be writable by group or others", dir);
|
||||
+ goto error;
|
||||
+ }
|
||||
+
|
||||
+ *d = '\0';
|
||||
+ }
|
||||
+
|
||||
+ free(p);
|
||||
+ return 0;
|
||||
+
|
||||
+error:
|
||||
+ free(p);
|
||||
+ return -1;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Check to see if there is a namespace initialization script in
|
||||
* the /etc/security directory. If such a script exists
|
||||
@@ -1524,7 +1597,11 @@ static int inst_init(const struct polydir_s *polyptr, const char *ipath,
|
||||
close_fds_pre_exec(idata);
|
||||
|
||||
execle(init_script, init_script,
|
||||
- polyptr->dir, ipath, newdir?"1":"0", idata->user, NULL, envp);
|
||||
+ polyptr->dir, ipath,
|
||||
+ newdir ? "1":"0", idata->user,
|
||||
+ (check_safe_path(polyptr->dir, idata) == -1) ? "0":"1",
|
||||
+ (check_safe_path(ipath, idata) == -1) ? "0":"1",
|
||||
+ NULL, envp);
|
||||
_exit(1);
|
||||
} else if (pid > 0) {
|
||||
while (((rc = waitpid(pid, &status, 0)) == (pid_t)-1) &&
|
||||
--
|
||||
2.49.0
|
||||
|
||||
Reference in New Issue
Block a user