[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