The branch main has been updated by bapt:

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

commit ef7d0eb9489f39169a1ae83c576fe74e40d126ad
Author:     Baptiste Daroussin <b...@freebsd.org>
AuthorDate: 2023-05-15 06:55:08 +0000
Commit:     Baptiste Daroussin <b...@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]);
+                       }
                }
        }
 

Reply via email to