Subject: bug#79072: closed (Re: bug#79072: install -d onto readonly fs prints the wrong error)

From: [email-masked] (GNU bug Tracking System)
Date: Tue, 22 Jul 2025 19:19:02 +0000

Your bug report

#79072: install -d onto readonly fs prints the wrong error

which was filed against the coreutils package, has been closed.

The explanation is attached below, along with your original report.
If you require more details, please reply to [email-masked].

-- 
79072: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=79072
GNU Bug Tracking System
Contact [email-masked] with problems

Subject: Re: bug#79072: install -d onto readonly fs prints the wrong error
From: Paul Eggert <[email-masked]>
To: Lauri Tirkkonen <[email-masked]>
Cc: Gnulib bugs <[email-masked]>, [email-masked], Collin Funk <[email-masked]>
Date: Tue, 22 Jul 2025 12:17:56 -0700
List-Id: <debbugs-submit.debbugs.gnu.org>

Thanks for reporting that inaccurate diagnostic. Sorry about the tricky 
code; it's a tricky situation. Looks like Collin's patch is not quite right.

I installed the attached patches into Gnulib. The first one fixes the 
two cases you mentioned, the second an unlikely bug I discovered in the 
neighborhood. Please give the patches a try. As they fix the bugs for me 
I am boldly closing the Coreutils bug report; we can reopen it if I'm wrong.
From 27db579667399d9f2cae2552a6f9185ffd10ab23 Mon Sep 17 00:00:00 2001
From: Paul Eggert <[email-masked]>
Date: Tue, 22 Jul 2025 12:09:28 -0700
Subject: [PATCH 1/2] mkdir-p: better diagnostics
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Problem reported by Lauri Tirkkonen <https://bugs.gnu.org/79072>.
* lib/mkdir-p.c (make_dir_parents):
If savewd_chdir fails due to anything other than EACCES, do
not attempt to preserve permissions; instead, fail with mkdir’s
errno if nonzero, and with savewd_chdir’s errno otherwise.
---
 ChangeLog     | 9 +++++++++
 lib/mkdir-p.c | 9 ++++++++-
 2 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/ChangeLog b/ChangeLog
index 99ca126183..4841447b88 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2025-07-22  Paul Eggert  <[email-masked]>
+
+	mkdir-p: better diagnostics
+	Problem reported by Lauri Tirkkonen <https://bugs.gnu.org/79072>.
+	* lib/mkdir-p.c (make_dir_parents):
+	If savewd_chdir fails due to anything other than EACCES, do
+	not attempt to preserve permissions; instead, fail with mkdir’s
+	errno if nonzero, and with savewd_chdir’s errno otherwise.
+
 2025-07-21  Collin Funk  <[email-masked]>
 
 	sys_un-h: Make sure that the 'sys' subdirectory is created.
diff --git a/lib/mkdir-p.c b/lib/mkdir-p.c
index f5df9843e4..fffa58b4eb 100644
--- a/lib/mkdir-p.c
+++ b/lib/mkdir-p.c
@@ -172,7 +172,7 @@ make_dir_parents (char *dir,
                               savewd_chdir_options, open_result);
               if (chdir_result < -1)
                 return true;
-              else
+              else if (chdir_result == 0 || errno == EACCES)
                 {
                   bool chdir_ok = (chdir_result == 0);
                   char const *subdir = (chdir_ok ? "." : dir + prefix_len);
@@ -193,6 +193,13 @@ make_dir_parents (char *dir,
                       return false;
                     }
                 }
+              else
+                {
+                  if (mkdir_errno == 0)
+                    mkdir_errno = errno;
+                  if (0 <= open_result[0])
+                    close (open_result[0]);
+                }
             }
         }
     }
-- 
2.48.1

From 84ddfc7bd29853ed91cdd65c7ce818072959f974 Mon Sep 17 00:00:00 2001
From: Paul Eggert <[email-masked]>
Date: Tue, 22 Jul 2025 12:12:22 -0700
Subject: [PATCH 2/2] mkdir-p: ENOENT/ENOTDIR safety and consistency

* lib/mkdir-p.c (make_dir_parents): If mkdir fails with ENOENT or
ENOTDIR, do not attempt anything else since the file does not exist.
Treat ENOENT and ENOTDIR consistently later, too.
---
 ChangeLog     | 5 +++++
 lib/mkdir-p.c | 9 +++++----
 2 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 4841447b88..ac20d475da 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 2025-07-22  Paul Eggert  <[email-masked]>
 
+	mkdir-p: ENOENT/ENOTDIR safety and consistency
+	* lib/mkdir-p.c (make_dir_parents): If mkdir fails with ENOENT or
+	ENOTDIR, do not attempt anything else since the file does not exist.
+	Treat ENOENT and ENOTDIR consistently later, too.
+
 	mkdir-p: better diagnostics
 	Problem reported by Lauri Tirkkonen <https://bugs.gnu.org/79072>.
 	* lib/mkdir-p.c (make_dir_parents):
diff --git a/lib/mkdir-p.c b/lib/mkdir-p.c
index fffa58b4eb..7b764f122d 100644
--- a/lib/mkdir-p.c
+++ b/lib/mkdir-p.c
@@ -144,11 +144,13 @@ make_dir_parents (char *dir,
               mkdir_mode = -1;
             }
 
-          if (preserve_existing)
+          if (mkdir_errno == ENOENT || mkdir_errno == ENOTDIR)
+            ;
+          else if (preserve_existing)
             {
               if (mkdir_errno == 0)
                 return true;
-              if (mkdir_errno != ENOENT && make_ancestor)
+              if (make_ancestor)
                 {
                   struct stat st;
                   if (stat (dir + prefix_len, &st) == 0)
@@ -182,8 +184,7 @@ make_dir_parents (char *dir,
                     return true;
 
                   if (mkdir_errno == 0
-                      || (mkdir_errno != ENOENT && make_ancestor
-                          && errno != ENOTDIR))
+                      || (make_ancestor && errno != ENOENT && errno != ENOTDIR))
                     {
                       error (0, errno,
                              _(keep_owner
-- 
2.48.1

Subject: install -d onto readonly fs prints the wrong error
From: Lauri Tirkkonen <[email-masked]>
To: [email-masked]
Date: Tue, 22 Jul 2025 13:17:30 +0900
List-Id: <debbugs-submit.debbugs.gnu.org>

Hi,

saw this on coreutils 9.7 on Alpine Linux, but it also reproduces on
commit 027855dcad52d718927c3405bc7d605143e2a625.

	# mount -t tmpfs -o ro none /mnt
	# ./src/ginstall -d /mnt/foo
	ginstall: cannot change permissions of ‘/mnt/foo’: No such file or directory

I would expect the error to be EROFS for creating the directory, not
changing permissions of the directory that was not able to be created.
strace confirms mkdir() returns EROFS, but install tries to open() and
stat() the not-created directory afterward.

-- 
Lauri Tirkkonen | lotheac @ IRCnet