[Pkg-shadow-devel] [Git][debian/adduser][master] 4 commits: test case for #1112486
Marc Haber (@zugschlus)
gitlab at salsa.debian.org
Sat Sep 13 13:41:39 BST 2025
Marc Haber pushed to branch master at Debian / adduser
Commits:
72c01705 by Marc Haber at 2025-09-01T20:07:18+02:00
test case for #1112486
Git-Dch: ignore
- - - - -
92004a07 by Marc Haber at 2025-09-01T20:08:01+02:00
replace sanitize_string with a more flexible version
This one has an optional parameter $replace. When called with
this set to != 0, any disallowed character in the input string
will be replaced by _
Git-Dch: ignore
- - - - -
43adeba0 by Marc Haber at 2025-09-01T20:08:07+02:00
use sanitize_string with replace in find_match
Closes: #112486
Thanks: Rob Browning
- - - - -
6fcfd0ef by Marc Haber at 2025-09-01T20:08:09+02:00
add another test case for a file that should be deleted
Git-Dch: ignore
- - - - -
3 changed files:
- AdduserCommon.pm
- debian/tests/f/deluser_files.t
- deluser
Changes:
=====================================
AdduserCommon.pm
=====================================
@@ -125,22 +125,42 @@ use constant {
);
sub sanitize_string {
- my ($input, $pattern) = @_;
-
- # Set a default pattern to allow alphanumeric characters,
- # spaces, and underscores.
- $pattern //= qr/[a-zA-Z0-9 _]*/;
- log_trace("sanitize_string %s against %s", $input, $pattern);
-
- # If the input matches the pattern,
- # extract and return the untainted value.
- if ($input =~ qr/^($pattern)$/ ) {
- log_trace("sanitize_string returning %s", "$1");
- return $1; # $1 is the captured, untainted portion of the string.
- } else {
- #die "invalid characters in $input";
- # this sometimes hangs the perl interpreter, see #1104726
- die "invalid characters in input string, see trace output for more details";
+ my ($input, $pattern, $replace) = @_;
+ return unless defined $input;
+
+ $pattern //= '[a-zA-Z0-9 _]+';
+ $replace //= 0;
+
+ log_trace("sanitize_string %s against %s (replace=%s)", $input, $pattern, $replace);
+
+ # Full match check
+ if ($input =~ /^($pattern)\z/) {
+ log_trace("sanitize_string returning %s", $1);
+ return $1; # Untainted
+ }
+ elsif ($replace) {
+ # Replace disallowed substrings with underscores
+ my $safe = '';
+ my $pos = 0;
+
+ while ($input =~ /$pattern/g) {
+ my $start = $-[0]; # start of match
+ my $end = $+[0]; # end of match
+ # fill in underscores for skipped portion
+ $safe .= '_' x ($start - $pos) if $start > $pos;
+ # append allowed portion
+ $safe .= substr($input, $start, $end - $start);
+ $pos = $end;
+ }
+
+ # any trailing disallowed chars
+ $safe .= '_' x (length($input) - $pos) if $pos < length($input);
+
+ log_trace("sanitize_string replaced invalid chars, returning %s", $safe);
+ return $safe;
+ }
+ else {
+ die sprintf("sanitize_string: invalid characters in '%s'", $input);
}
}
=====================================
debian/tests/f/deluser_files.t
=====================================
@@ -8,13 +8,13 @@ use warnings;
use AdduserTestsCommon;
sub create_files_in_homedir{
- my ($acct, $uid, $gid) = @_;
+ my ($acct, $uid, $gid, $acct2, $uid2, $gid2) = @_;
mkdir ("/home/$acct", 0777);
mkdir ("/home/$acct/mnt", 0777);
mkdir ("/home/$acct/dir", 0777);
mkdir ("/tmp/$acct", 0777);
unlink("/tmp/deluserfiles.txt");
- for ("/home/$acct/extra.txt", "/tmp/$acct/extra2.txt", "/tmp/deluserfiles.txt") {
+ for ("/home/$acct/extra.txt", "/tmp/$acct/extra2.txt", "/tmp/deluserfiles.txt", "/home/$acct2/not-utf-8-but-possible-\x7F", "/home/$acct/not-utf-8-but-possible-\x7F", "/home/$acct2/still-not-utf-8-but-possible-\x7F") {
open (XTRA, '>', $_) || die ("could not open file $_: $!");
print XTRA "extra file";
close (XTRA) || die ('could not close file!');
@@ -27,7 +27,10 @@ sub create_files_in_homedir{
"/home/$acct/mnt",
"/home/$acct/dir",
"/tmp/deluserfiles.txt",
- "/home/$acct/pipe");
+ "/home/$acct/pipe",
+ "/home/$acct/not-utf-8-but-possible-\x7F",
+ "/home/$acct2/still-not-utf-8-but-possible-\x7F");
+ chown ($uid2, $gid2, "/home/$acct2/not-utf-8-but-possible-\x7F");
assert_command_success('mount','-o','bind',"/tmp/$acct","/home/$acct/mnt");
}
@@ -39,8 +42,23 @@ END {
remove_tree('/tmp/deluserfiles-extra');
unlink('/tmp/deluserfiles.tar.gz');
unlink('/tmp/deluserfiles.txt');
+ assert_user_exists('deluserfiles2');
+ assert_command_success('/usr/sbin/deluser',
+ '--stdoutmsglevel=error', '--stderrmsglevel=error',
+ 'deluserfiles2');
+ assert_user_does_not_exist('deluserfiles2');
+ remove_tree('/home/deluserfiles2');
}
+assert_user_does_not_exist('deluserfiles2');
+assert_command_success('/usr/sbin/adduser',
+ '--stdoutmsglevel=error', '--stderrmsglevel=error',
+ '--home', '/home/deluserfiles2',
+ '--comment', '',
+ '--disabled-password',
+ 'deluserfiles2');
+assert_user_exists('deluserfiles2');
+
assert_user_does_not_exist('deluserfiles');
assert_command_success('/usr/sbin/adduser',
'--stdoutmsglevel=error', '--stderrmsglevel=error',
@@ -50,7 +68,8 @@ assert_command_success('/usr/sbin/adduser',
assert_user_exists('deluserfiles');
my ($login, $pass, $uid, $gid) = getpwnam('deluserfiles');
-create_files_in_homedir("deluserfiles-extra", $uid, $gid);
+my ($login2, $pass2, $uid2, $gid2) = getpwnam('deluserfiles2');
+create_files_in_homedir("deluserfiles-extra", $uid, $gid, "deluserfiles2", $uid2, $gid2);
assert_command_success('/usr/sbin/deluser',
'--stdoutmsglevel=error', '--stderrmsglevel=error',
@@ -99,7 +118,7 @@ assert_command_success('/usr/sbin/adduser',
'deluserfiles');
assert_user_exists('deluserfiles', $uid, $gid);
($login, $pass, $uid, $gid) = getpwnam('deluserfiles');
-create_files_in_homedir("deluserfiles-extra", $uid, $gid);
+create_files_in_homedir("deluserfiles-extra", $uid, $gid, "deluserfiles2", $uid2, $gid2);
assert_command_failure_silent('/usr/sbin/deluser',
'--stdoutmsglevel=error', '--stderrmsglevel=error',
'--system',
=====================================
deluser
=====================================
@@ -356,7 +356,7 @@ if($action eq "deluser") {
sub find_match {
my ($dev,$ino,$mode,$nlink,$uid,$gid) = lstat;
log_trace("find_match %s", $_);
- my $name = sanitize_string( decode($charset, $File::Find::name), pathre );
+ my $name = sanitize_string( decode($charset, $File::Find::name), pathre, 1 );
log_trace("find_match sanitized %s", $name);
foreach my $mount (@mountpoints) {
if( $name eq $mount ) {
View it on GitLab: https://salsa.debian.org/debian/adduser/-/compare/c4df5eb760b6be76c4d7ac50b7fa13243795cc34...6fcfd0efbaa61293b5f7deafc120abd4a153be51
--
View it on GitLab: https://salsa.debian.org/debian/adduser/-/compare/c4df5eb760b6be76c4d7ac50b7fa13243795cc34...6fcfd0efbaa61293b5f7deafc120abd4a153be51
You're receiving this email because of your account on salsa.debian.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-shadow-devel/attachments/20250913/aeb4c6d4/attachment-0001.htm>
More information about the Pkg-shadow-devel
mailing list