git: ef7d0eb9489f - main - pw: do not call system()

From: Baptiste Daroussin <bapt_at_FreeBSD.org>
Date: Mon, 15 May 2023 06:59:12 UTC
The branch main has been updated by bapt:

URL: https://cgit.FreeBSD.org/src/commit/?id=ef7d0eb9489f39169a1ae83c576fe74e40d126ad

commit ef7d0eb9489f39169a1ae83c576fe74e40d126ad
Author:     Baptiste Daroussin <bapt@FreeBSD.org>
AuthorDate: 2023-05-15 06:55:08 +0000
Commit:     Baptiste Daroussin <bapt@FreeBSD.org>
CommitDate: 2023-05-15 06:59:08 +0000

    pw: do not call system()
    
    Calling system makes pw(8) spawn a shell, which can then be abused.
    
    MFC After:      3 days
---
 usr.sbin/pw/pw_user.c | 32 ++++++++++++++++++++++++--------
 1 file changed, 24 insertions(+), 8 deletions(-)

diff --git a/usr.sbin/pw/pw_user.c b/usr.sbin/pw/pw_user.c
index 52b37eae4ff1..c0002f985bfb 100644
--- a/usr.sbin/pw/pw_user.c
+++ b/usr.sbin/pw/pw_user.c
@@ -50,6 +50,7 @@ static const char rcsid[] =
 #include <sysexits.h>
 #include <termios.h>
 #include <unistd.h>
+#include <spawn.h>
 
 #include "pw.h"
 #include "bitmap.h"
@@ -57,6 +58,7 @@ static const char rcsid[] =
 
 #define LOGNAMESIZE (MAXLOGNAME-1)
 
+extern char **environ;
 static		char locked_str[] = "*LOCKED*";
 
 static struct passwd fakeuser = {
@@ -694,11 +696,16 @@ rmat(uid_t uid)
 			    stat(e->d_name, &st) == 0 &&
 			    !S_ISDIR(st.st_mode) &&
 			    st.st_uid == uid) {
-				char            tmp[MAXPATHLEN];
-
-				snprintf(tmp, sizeof(tmp), "/usr/bin/atrm %s",
-				    e->d_name);
-				system(tmp);
+				const char *argv[] = {
+					"/usr/sbin/atrm",
+					e->d_name,
+					NULL
+				};
+				if (posix_spawn(NULL, argv[0], NULL, NULL,
+				    (char *const *) argv, environ)) {
+					warn("Failed to execute '%s %s'",
+					    argv[0], argv[1]);
+				}
 			}
 		}
 		closedir(d);
@@ -915,9 +922,18 @@ pw_user_del(int argc, char **argv, char *arg1)
 		/* Remove crontabs */
 		snprintf(file, sizeof(file), "/var/cron/tabs/%s", pwd->pw_name);
 		if (access(file, F_OK) == 0) {
-			snprintf(file, sizeof(file), "crontab -u %s -r",
-			    pwd->pw_name);
-			system(file);
+			const char *argv[] = {
+				"crontab",
+				"-u",
+				pwd->pw_name,
+				"-r",
+				NULL
+			};
+			if (posix_spawnp(NULL, argv[0], NULL, NULL,
+						(char *const *) argv, environ)) {
+				warn("Failed to execute '%s %s'",
+						argv[0], argv[1]);
+			}
 		}
 	}