diff --git a/usr.bin/xinstall/tests/install_test.sh b/usr.bin/xinstall/tests/install_test.sh --- a/usr.bin/xinstall/tests/install_test.sh +++ b/usr.bin/xinstall/tests/install_test.sh @@ -428,6 +428,8 @@ local cu=65532 cg=65532 local u="$(id -u)" local g="$(id -g)" + local iu="invlid_user" + local ig="invlid_group" local m=0755 cm=4444 printf "test" >testf atf_check chown "$fu:$fg" testf @@ -456,6 +458,15 @@ atf_check install -o "$cu" -g "$cg" -m "$cm" testf testc atf_check_equal "$cu:$cg:10$cm" "$(stat -f"%u:%g:%p" testc)" + + atf_check -o match:"uid=${u} gid=${g}" \ + install -M /dev/stdout -o "$u" -g "$g" testf testc + + atf_check -s not-exit:0 -e match:"unknown user ${iu}" \ + install -M /dev/stdout -o "$iu" testf testc + + atf_check -s not-exit:0 -e match:"unknown group ${ig}" \ + install -M /dev/stdout -g "$ig" testf testc } atf_test_case set_owner_group_mode_unpriv @@ -467,6 +478,8 @@ local cu=65532 cg=65532 local u="$(id -u)" local g="$(id -g)" + local iu="invalid_user" + local ig="invalid_group" local m=0755 cm=4444 cM=0444 printf "test" >testf atf_check chown "$fu:$fg" testf @@ -495,6 +508,48 @@ atf_check install -U -o "$cu" -g "$cg" -m "$cm" testf testc atf_check_equal "$u:$g:10$cM" "$(stat -f"%u:%g:%p" testc)" + + atf_check -o match:"uid=${u} gid=${g}" \ + install -U -M /dev/stdout -o "$u" -g "$g" testf testc + + atf_check -o match:"uname=${iu} gname=${ig}" \ + install -U -M /dev/stdout -o "$iu" -g "$ig" testf testc +} + +atf_test_case set_owner_group_mode_numeric_invalid +set_owner_group_mode_numeric_invalid_head() { + atf_set "require.user" "root" +} +set_owner_group_mode_numeric_invalid_body() { + local UID_MAX=$((1 << 32)) + local GID_MAX=$((1 << 32)) + local u="$(id -u)" + local g="$(id -g)" + printf "test" >testf + + atf_check -s not-exit:0 -e match:"invalid user -1" \ + install -o -1 testf testc + + atf_check -s not-exit:0 -e match:"invalid user -1" \ + install -U -o -1 testf testc + + atf_check -s not-exit:0 -e match:"invalid group -1" \ + install -g -1 testf testc + + atf_check -s not-exit:0 -e match:"invalid group -1" \ + install -U -g -1 testf testc + + atf_check -s not-exit:0 -e match:"invalid user ${UID_MAX}" \ + install -o "$UID_MAX" testf testc + + atf_check -s not-exit:0 -e match:"invalid user ${UID_MAX}" \ + install -U -o "$UID_MAX" testf testc + + atf_check -s not-exit:0 -e match:"invalid group ${GID_MAX}" \ + install -g "$GID_MAX" testf testc + + atf_check -s not-exit:0 -e match:"invalid group ${GID_MAX}" \ + install -U -g "$GID_MAX" testf testc } atf_test_case set_optional_exec @@ -556,5 +611,6 @@ atf_add_test_case mkdir_simple atf_add_test_case set_owner_group_mode atf_add_test_case set_owner_group_mode_unpriv + atf_add_test_case set_owner_group_mode_numeric_invalid atf_add_test_case set_optional_exec } diff --git a/usr.bin/xinstall/xinstall.c b/usr.bin/xinstall/xinstall.c --- a/usr.bin/xinstall/xinstall.c +++ b/usr.bin/xinstall/xinstall.c @@ -324,22 +324,32 @@ } /* get group and owner id's */ - if (group != NULL && !dounpriv) { - if (gid_from_group(group, &gid) == -1) { - id_t id; + if (group != NULL) { + id_t id; + + if (parseid(group, &id)) { + if (id < 0 || id > GID_MAX) + errx(1, "invalid group %s", group); + } + if (!dounpriv && gid_from_group(group, &gid) == -1) { if (!parseid(group, &id)) errx(1, "unknown group %s", group); - gid = id; + gid = (gid_t)id; } } else gid = (gid_t)-1; - if (owner != NULL && !dounpriv) { - if (uid_from_user(owner, &uid) == -1) { - id_t id; + if (owner != NULL) { + id_t id; + + if (parseid(owner, &id)) { + if (id < 0 || id > UID_MAX) + errx(1, "invalid user %s", owner); + } + if (!dounpriv && uid_from_user(owner, &uid) == -1) { if (!parseid(owner, &id)) errx(1, "unknown user %s", owner); - uid = id; + uid = (uid_t)id; } } else uid = (uid_t)-1;