git: 2350f75acb0d - main - pw: check -M, -V and -R input to avoid dereferencing argv[2]

From: Baptiste Daroussin <bapt_at_FreeBSD.org>
Date: Fri, 04 Sep 2026 10:43:40 UTC
The branch main has been updated by bapt:

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

commit 2350f75acb0da0271ccff1fb22381f7e8c5948f8
Author:     Baptiste Daroussin <bapt@FreeBSD.org>
AuthorDate: 2026-09-04 10:40:52 +0000
Commit:     Baptiste Daroussin <bapt@FreeBSD.org>
CommitDate: 2026-09-04 10:42:30 +0000

    pw: check -M, -V and -R input to avoid dereferencing argv[2]
    
    MFC After: 1 week
---
 usr.sbin/pw/pw.c             |  8 ++++++++
 usr.sbin/pw/tests/Makefile   |  3 ++-
 usr.sbin/pw/tests/pw_test.sh | 20 ++++++++++++++++++++
 3 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/usr.sbin/pw/pw.c b/usr.sbin/pw/pw.c
index 7cb5dd160e12..fc690a246314 100644
--- a/usr.sbin/pw/pw.c
+++ b/usr.sbin/pw/pw.c
@@ -146,6 +146,10 @@ main(int argc, char *argv[])
 				relocated = true;
 				optarg = &argv[1][2];
 				if (*optarg == '\0') {
+					if (argc < 3)
+						errx(EX_USAGE,
+						    "-%c requires a directory "
+						    "argument", arg);
 					if (stat(argv[2], &st) != 0)
 						errx(EX_OSFILE,
 						    "no such directory `%s'",
@@ -173,6 +177,10 @@ main(int argc, char *argv[])
 
 				optarg = &argv[1][2];
 				if (*optarg == '\0') {
+					if (argc < 3)
+						errx(EX_USAGE,
+						    "-M requires a file "
+						    "argument");
 					optarg = argv[2];
 					++argv;
 					--argc;
diff --git a/usr.sbin/pw/tests/Makefile b/usr.sbin/pw/tests/Makefile
index b92897ab9208..a8b75b825469 100644
--- a/usr.sbin/pw/tests/Makefile
+++ b/usr.sbin/pw/tests/Makefile
@@ -13,7 +13,8 @@ SRCS.pw_unit_test=	pw_unit_test.c \
 LIBADD.pw_unit_test=	util
 CFLAGS.pw_unit_test=	-I${SRCTOP}/usr.sbin/pw
 
-ATF_TESTS_SH=	pw_etcdir_test \
+ATF_TESTS_SH=	pw_test\
+		pw_etcdir_test \
 		pw_lock_test \
 		pw_config_test \
 		pw_groupadd_test \
diff --git a/usr.sbin/pw/tests/pw_test.sh b/usr.sbin/pw/tests/pw_test.sh
new file mode 100644
index 000000000000..55bcbbbb5c98
--- /dev/null
+++ b/usr.sbin/pw/tests/pw_test.sh
@@ -0,0 +1,20 @@
+atf_test_case R_missing_dir
+R_missing_dir_body() {
+        atf_check -s exit:64 -e inline:"pw: -R requires a directory argument\n" pw -R
+}
+
+atf_test_case V_missing_dir
+V_missing_dir_body() {
+        atf_check -s exit:64 -e inline:"pw: -V requires a directory argument\n" pw -V
+}
+
+atf_test_case M_missing_file
+M_missing_file_body() {
+        atf_check -s exit:64 -e inline:"pw: -M requires a file argument\n" pw -M
+}
+
+atf_init_test_cases() {
+	atf_add_test_case R_missing_dir
+	atf_add_test_case V_missing_dir
+	atf_add_test_case M_missing_file
+}