NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

bin/58577: install(1) -d issues



>Number:         58577
>Category:       bin
>Synopsis:       install(1) -d issues
>Confidential:   no
>Severity:       serious
>Priority:       low
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sun Aug 11 05:45:01 +0000 2024
>Originator:     RVP
>Release:        NetBSD/amd64 10.99.11
>Organization:
>Environment:
NetBSD/amd64 10.99.11
>Description:
install(1) -d has a couple of issues:

1. `install -d' (ie. no dir. given should error out; it doesn't:

```
$ install 2>/dev/null || echo FAIL
FAIL
$ install -d || echo FAIL
$
```

2. After creating a directory, if the chown/chmod fails, install returns
   success and writes the wrong metalog file:

```
$ whoami
rvp
$ install -M /tmp/meta.log -d -m 755 -o root -g wheel /tmp/A
install: /tmp/A: chown/chmod: Operation not permitted
$ echo $?
0
$ cat /tmp/meta.log
./tmp/A type=dir uname=root gname=wheel mode=0755
$
```
>How-To-Repeat:
As above.
>Fix:
---START patch---
diff -urN a/src/usr.bin/xinstall/xinstall.c b/src/usr.bin/xinstall/xinstall.c
--- a/src/usr.bin/xinstall/xinstall.c	2020-10-30 20:05:00.000000000 +0000
+++ b/src/usr.bin/xinstall/xinstall.c	2023-06-30 22:43:06.828747533 +0000
@@ -161,7 +161,7 @@
 static int	do_link(char *, char *);
 static void	do_symlink(char *, char *);
 static void	install(char *, char *, u_int);
-static void	install_dir(char *, u_int);
+static int	install_dir(char *, u_int);
 static void	makelink(char *, char *);
 static void	metadata_log(const char *, const char *, struct timeval *,
 	    const char *, const char *, off_t);
@@ -322,7 +322,7 @@
 		usage();
 
 	/* must have at least two arguments, except when creating directories */
-	if (argc < 2 && !dodir)
+	if (argc == 0 || (argc < 2 && !dodir))
 		usage();
 
 	if (digest) {
@@ -384,9 +384,10 @@
 		digesttype = DIGEST_NONE;
 
 	if (dodir) {
+		int rc = 0;
 		for (; *argv != NULL; ++argv)
-			install_dir(*argv, iflags);
-		exit (0);
+			rc |= install_dir(*argv, iflags);
+		exit (rc);
 	}
 
 	no_target = stat(to_name = argv[argc - 1], &to_sb);
@@ -1141,12 +1142,13 @@
  * install_dir --
  *	build directory hierarchy
  */
-static void
+static int
 install_dir(char *path, u_int flags)
 {
 	char		*p;
 	struct stat	sb;
 	int		ch;
+	int		rc = EXIT_SUCCESS;
 
 	for (p = path;; ++p)
 		if (!*p || (p != path && *p  == '/')) {
@@ -1181,8 +1183,11 @@
 	    ((flags & (HASUID | HASGID)) && chown(path, uid, gid) == -1)
 	    || chmod(path, mode) == -1 )) {
 		warn("%s: chown/chmod", path);
+		rc = EXIT_FAILURE;
 	}
-	metadata_log(path, "dir", NULL, NULL, NULL, 0);
+	if (rc == EXIT_SUCCESS)
+		metadata_log(path, "dir", NULL, NULL, NULL, 0);
+	return rc;
 }
 
 /*
---END patch---



Home | Main Index | Thread Index | Old Index