** Summary changed:

- PAM_TTY is wrongly computed by sudo-rs
+ [SRU] PAM_TTY is wrongly computed by sudo-rs

** Also affects: rust-sudo-rs (Ubuntu Resolute)
   Importance: Undecided
       Status: New

** Also affects: rust-sudo-rs (Ubuntu Stonking)
   Importance: High
     Assignee: Marco Trevisan (Treviño) (3v1n0)
       Status: In Progress

** Changed in: rust-sudo-rs (Ubuntu Resolute)
     Assignee: (unassigned) => Simon Johnsson (bamf0)

** Changed in: rust-sudo-rs (Ubuntu Resolute)
       Status: New => In Progress

** Changed in: rust-sudo-rs (Ubuntu Resolute)
    Milestone: None => ubuntu-26.04.1

** Changed in: rust-sudo-rs (Ubuntu Stonking)
    Milestone: ubuntu-26.04.1 => None

** Changed in: rust-sudo-rs (Ubuntu Resolute)
   Importance: Undecided => Critical

** Description changed:

- PAM_TTY is not properly computed by sudo-rs when input redirection or IO
- streams are unset or closed.
+ [ Impact ]
+ 
+ sudo-rs does not properly calculate PAM_TTY when input redirection or IO
+ streams are unset or closed. As a consequence, PAM modules may not properly
+ handle authentication through sudo
+ (see authd bug: https://github.com/canonical/authd/issues/901).
+ This is a considerable issue for an LTS where sudo-rs is meant to be the
+ default sudo provider.
+ 
+ The root cause is that sudo-rs's implementation of setting PAM_TTY
+ (current_tty_name()) does not work for redirections of stdin. The fix is to
+ use a different resolution strategy:
+ 
+ 1. Get the kernel-reported TTY device id for the current process
+    (Process::tty_device_id).
+ 2. Check /dev/console against that device id.
+ 3. Check the ttyname reported by stdin/stdout/stderr.
+ 4. Scan /dev/pts/ for a matching device.
+ 5. Fall back to scanning all of /dev/
+ 
+ Should this fail, it will fallback to the old implementation.
+ 
+ [ Test Plan ]
+ 
+ > The bug can be reproduced by minimally mimicking what sshuttle does:
+ 
+ * Modify /etc/pam.d/sudo to contain:
+ 
+   auth optional pam_exec.so stdout /usr/bin/env
+ 
+ * Change to a user in the sudo group
+ * Assert that sudo-rs is the current sudo provider:
+ 
+ $ sudo --version
+ 
+ # Output:
+ sudo-rs 0.2.13-0ubuntu1
+ ~~~~~~~
+ 
+ * Reset any previous authentications:
+ 
+ $ sudo -k
+ 
+ * Pipe a command to sudo:
+ 
+ $ echo Hello | sudo cat
+ 
+ # Output:
+ [sudo] PAM_SERVICE=sudo
+ [sudo] PAM_USER=john
+ [sudo] PAM_RUSER=john
+ [sudo] PAM_TYPE=auth
+ [sudo: authenticate] Password:
+ 
+ * Observe that PAM_TTY is missing
+ 
+ > Testing proposed:
+ 
+ * Install the proposed sudo-rs:
+ 
+ $ sudo apt install -t resolute-proposed rust-sudo-rs
+ 
+ * Reset any previous authentication:
+ 
+ $ sudo -k
+ 
+ * Pipe a command to sudo:
+ 
+ $ echo World | sudo cat
+ 
+ # Output
+ PAM_SERVICE=sudo
+ PAM_USER=john
+ PAM_TTY=/dev/pts/0
+ ~~~~~~~~~~~~~~~~~~
+ PAM_RUSER=john
+ PAM_TYPE=auth
+ [sudo: authenticate] Password:
+ 
+ * Observe that PAM_TTY is set
+ 
+ (Test for regressions)
+ 
+ > Verify that PAM_TTY is correctly set when *not* using input
+ redirection:
+ 
+ * Reset any previous authentication:
+ 
+ $ sudo -k
+ 
+ * Run a trivial command with sudo:
+ 
+ $ sudo true
+ 
+ # Output:
+ [sudo] PAM_SERVICE=sudo
+ [sudo] PAM_USER=john
+ [sudo] PAM_TTY=/dev/pts/0
+        ~~~~~~~~~~~~~~~~~~
+ [sudo] PAM_RUSER=john
+ [sudo] PAM_TYPE=auth
+ [sudo: authenticate] Password:
+ 
+ * Observe that PAM_TTY is set
+ 
+ > Verify that PAM_TTY is equal to the output of `tty`:
+ 
+ * Check current tty:
+ 
+ $ tty
+ 
+ # Output:
+ /dev/pts/0
+ ~~~~~~~~~~
+ 
+ * Test all steps for both (1.) w/ and (2.) w/o input redirection:
+ 
+     * Reset any previous authentication:
+ 
+     $ sudo -k
+ 
+     (1. w/  input redirection) || (2. w/o input redirection) 
+     $ echo Hello | sudo cat       $ sudo true
+ 
+     # Output:
+     [sudo] PAM_SERVICE=sudo
+     [sudo] PAM_USER=john
+     [sudo] PAM_TTY=/dev/pts/0
+            ~~~~~~~~~~~~~~~~~~
+     [sudo] PAM_RUSER=john
+     [sudo] PAM_TYPE=auth
+     [sudo: authenticate] Password:
+ 
+     * Assert PAM_TTY is equal to the output of `tty`
+ 
+ 
+ [ Where problems could occur ]
+ 
+ The most apparent risk of regression in this upload is if PAM_TTY were to be
+ incorrectly calculated in the normal non-redirected case. This has the risk of
+ impacting other packages making use of the `pam_securetty` module by rejecting
+ valid tty devices, as PAM is not able to infer what tty device is used.
+ 
+ In contrast, there is also a risk that this change would set PAM_TTY to a
+ false value, leading to scenarios where PAM modules might accept a device that
+ otherwise should have been rejected.
+ 
+ 
+ [ Other Info ]
+ 
+ * This SRU is part of a larger merge proposal for 26.04.1
+ 
+ * The fix is also natively part of the 0.2.14-1 upload to Stonking, currently
+   in proposed-migration
+ 
+ 
+ [ Original Description ]
+ PAM_TTY is not properly computed by sudo-rs when input redirection or IO 
streams are unset or closed.
  
  With this minimal reproducer (that simulates what sshuttle does):
  
  ```
  #!/usr/bin/env python3
  
  import shutil
  import socket
  import subprocess
  import sys
  
  def main() -> int:
      sudo = shutil.which("sudo") or "sudo"
      #sudo = "/usr/lib/cargo/bin/sudo"
      #sudo = "/usr/bin/sudo.ws"
      cmd = [sudo, "-p", "[local sudo] Password: ", "id"]
  
      s1, s2 = socket.socketpair()
  
      def setup() -> None:
          s2.close()
  
      # Match sshuttle default behavior: do not pass stdin, inherit it.
      #proc = subprocess.Popen(cmd, stdout=s1, preexec_fn=setup)
      proc = subprocess.Popen(cmd, stdin=subprocess.DEVNULL, stdout=s1, 
preexec_fn=setup)
      s1.close()
  
      output = s2.makefile("rb").read()
      if output:
          sys.stdout.buffer.write(output)
  
      rc = proc.wait()
      s2.close()
      return rc
  
  if __name__ == "__main__":
      raise SystemExit(main())
  ```
  
  Modify /etc/pam.d/sudo so that it contains:
  
    auth optional pam_exec.so stdout /usr/bin/env
  
  When using sudo.ws:
  
  PAM_SERVICE=sudo
  PAM_USER=user-sudo
  PAM_TTY=/dev/pts/1
  PAM_RUSER=user-sudo
  PAM_TYPE=auth
  
  When using sudo-rs:
  
  PAM_SERVICE=sudo
  PAM_USER=user-sudo
  PAM_RUSER=user-sudo
  PAM_TYPE=auth
  
  So PAM_TTY is missing, even though we are in a terminal. This may make
  PAM modules not to properly handle things in the right way, and in
  particular authd will not run the right client for the conversation.
  
  See also https://github.com/canonical/authd/issues/901

-- 
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.
https://bugs.launchpad.net/bugs/2153817

Title:
  [SRU] PAM_TTY is wrongly computed by sudo-rs

To manage notifications about this bug go to:
https://bugs.launchpad.net/sudo-rs/+bug/2153817/+subscriptions


-- 
ubuntu-bugs mailing list
[email protected]
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs

Reply via email to