Package: debianutils
Version: 5.20-0deepin1
Severity: normal
File: /usr/bin/ischroot
Tags: patch
X-Debbugs-Cc: wangzhao...@uniontech.com

Dear Maintainer,

I would like to report an issue with the ischroot utility from debianutils
where it incorrectly returns 0 when executed
inside an unshared mount namespace, which causes issues with hibernation and
wake-up functionality when generating initrd in an unshare environment.

Steps to Reproduce:
$ sudo unshare --mount bash
$ ischroot; echo $?
Observe that the exit code is 0, which indicates that ischroot incorrectly
detects the environment as a chroot.

Expected Behavior:
ischroot should return a non-zero value unless the process is actually inside a
chroot. Simply creating a new mount namespace using unshare does not constitute
a chroot environment.


-- System Information:
Distributor ID: Deepin
Description:    Deepin 23
Release:        23
Codename:       beige
Architecture: x86_64

Kernel: Linux 6.6.40-amd64-desktop-hwe (SMP w/16 CPU threads; PREEMPT)
Kernel taint flags: TAINT_OOT_MODULE, TAINT_UNSIGNED_MODULE
Locale: LANG=zh_CN.UTF-8, LC_CTYPE=zh_CN.UTF-8 (charmap=UTF-8), LANGUAGE=zh_CN
Shell: /bin/sh linked to /usr/bin/dash
Init: systemd (via /run/systemd/system)

Versions of packages debianutils depends on:
ii  libc6  2.38-6deepin7

debianutils recommends no packages.

debianutils suggests no packages.

-- no debconf information
diff --git a/ischroot.c b/ischroot.c
index 7318e7f..4fdc975 100644
--- a/ischroot.c
+++ b/ischroot.c
@@ -16,6 +16,7 @@
 #include <sys/types.h>
 #include <fcntl.h>
 #include <unistd.h>
+#include <errno.h>
 #ifdef HAVE_GETOPT_H
 #include <getopt.h>
 #endif /* HAVE_GETOPT_H */
@@ -135,13 +136,13 @@ static int ischroot()
   struct stat st1, st2;
   int ret;
 
-  ret = ischroot_mountinfo();
-  if (ret >= 0)
-    return ret;
-
   if (stat("/", &st1))
     return 2;
   if (stat("/proc/1/root", &st2)) {
+    /* If we get permission denied, try checking mountinfo instead,
+     * which can resolve mountinfo inconsistency issues in unshare 
environments */
+    if (errno == EACCES)
+      goto check_mountinfo;
     /* Does /proc/1/root exist at all? */
     if (lstat("/proc/1/root" , &st2))
       return 2;
@@ -154,6 +155,13 @@ static int ischroot()
     return 1;
   else
     return 0;
+
+check_mountinfo:
+  ret = ischroot_mountinfo();
+  if (ret >= 0)
+    return ret;
+
+  return 0;
 }
 
 #elif defined (__FreeBSD_kernel__) || defined (__FreeBSD__)

Reply via email to