[MDEV-19882] pam v2: auth_pam_tool truncates passwords that are not null-terminated Created: 2019-06-27  Updated: 2021-02-12  Resolved: 2019-10-28

Status: Closed
Project: MariaDB Server
Component/s: Plugin - pam
Affects Version/s: 10.4.6, 10.4.8
Fix Version/s: 10.4.9

Type: Bug Priority: Major
Reporter: Geoff Montee (Inactive) Assignee: Sergei Golubchik
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Blocks
Duplicate
is duplicated by MDEV-20571 pam_auth_v2 still doesn't work in 10.4.8 Closed
Problem/Incident
is caused by MDEV-7032 new pam plugin with a suid wrapper Closed
is caused by MDEV-15473 Isolate/sandbox PAM modules, so that ... Closed
Relates
relates to MDEV-19876 pam v2: auth_pam_tool_dir and auth_pa... Closed
relates to MDEV-19877 pam v2: auth_pam_tool input format is... Open
relates to MDEV-19878 pam v2: pam password authentication d... Closed
relates to MDEV-19879 server can send empty error message t... Closed
relates to MDEV-19880 pam v1: pam password authentication d... Closed
relates to MDEV-19881 pam plugin from MariaDB 10.3 doesn't ... Open
relates to MDEV-19898 PAM plugin testing Stalled

 Description   

In MariaDB 10.4, version 2 of the pam plugin is provided. This plugin forks a new process and executes the auth_pam_tool utility that is now bundled with the server.

Unfortunately, it seems to truncate passwords that are not null-terminated, because it always seems to assume that the last character is the NULL terminator.

This is a problem because some implementations of mysql_clear_password don't seem to null-terminate passwords.

The problem is fairly easy to reproduce.

Configuring PAM

We can configure PAM using the steps from MDEV-19877.

Create a Unix user account and set a password for the user:

sudo useradd alice
sudo passwd alice

Create the PAM service configuration:

sudo tee /etc/pam.d/mariadb <<EOF
auth required pam_unix.so audit
account required pam_unix.so audit
EOF

And then you might need to execute some commands to work around MDEV-19876:

sudo chmod 0755 /usr/lib64/mysql/plugin/auth_pam_tool_dir/
sudo chmod 4755 /usr/lib64/mysql/plugin/auth_pam_tool_dir/auth_pam_tool

Configuring MariaDB

We can configure PAM to use PAM authentication for this user account using the steps from MDEV-19877.

Let's install the pam plugin:

INSTALL SONAME 'auth_pam';

And let's create the relevant user:

CREATE USER 'alice'@'localhost' IDENTIFIED VIA pam USING 'mariadb'

Constructing the Input

We can construct the input for the auth_pam_tool tool using the information from MDEV-19877.

Let's assume that the alice user's password is uGBXHxID3dJRALw2.

Let's create input with a null-terminated password:

echo -n -e '0\0\x05alice\0\x07mariadb\0\x11uGBXHxID3dJRALw2\0' > good_input.txt

And let's also create input with a password that is not null-terminated:

echo -n -e '0\0\x05alice\0\x07mariadb\0\x10uGBXHxID3dJRALw2' > bad_input.txt

And then confirm the contents of each file:

$ hexdump -c good_input.txt
0000000   0  \0 005   a   l   i   c   e  \0  \a   m   a   r   i   a   d
0000010   b  \0 021   u   G   B   X   H   x   I   D   3   d   J   R   A
0000020   L   w   2  \0
0000024
$ hexdump -c bad_input.txt
0000000   0  \0 005   a   l   i   c   e  \0  \a   m   a   r   i   a   d
0000010   b  \0 020   u   G   B   X   H   x   I   D   3   d   J   R   A
0000020   L   w   2
0000023

Running the Tool

Next, we can run the auth_pam_tool tool and redirect the tool's stdin to the input files that we constructed.

We can also attach strace to the process, so we can passwords the tool is reading and writing.

First, run the tool with the good input:

cat good_input.txt | sudo strace -o strace_good_input.out -f -ff /usr/lib64/mysql/plugin/auth_pam_tool_dir/auth_pam_tool

The null-terminated password is properly read and passed to PAM:

write(1, "C", 1)                        = 1
write(1, "\0\v", 2)                     = 2
write(1, "\4Password: ", 11)            = 11
read(0, "\0\21", 2)                     = 2
read(0, "uGBXHxID3dJRALw2\0", 17)       = 17
...
write(4, "uGBXHxID3dJRALw2", 16)        = 16
write(4, "\0", 1)                       = 1

Next, run the tool with the bad input:

cat bad_input.txt | sudo strace -o strace_bad_input.out -f -ff /usr/lib64/mysql/plugin/auth_pam_tool_dir/auth_pam_tool

The non-null-terminated password is properly read, but its last character is truncated when it is passed to PAM:

write(1, "C", 1)                        = 1
write(1, "\0\v", 2)                     = 2
write(1, "\4Password: ", 11)            = 11
read(0, "\0\20", 2)                     = 2
read(0, "uGBXHxID3dJRALw2", 16)         = 16
...
write(4, "uGBXHxID3dJRALw", 15)         = 15
write(4, "\0", 1)                       = 1

Checking Syslog

The syslog (i.e. /var/log/secure on RHEL or /var/log/auth.log on Debian/Ubuntu) also shows an authentication failure, since the auth_pam_tool
tool provided a truncated password to PAM:

Oct 16 02:24:14 ip-172-30-0-123 unix_chkpwd[11398]: password check failed for user (alice)
Oct 16 02:24:14 ip-172-30-0-123 auth_pam_tool: pam_unix(mariadb:auth): authentication failure; logname= uid=0 euid=0 tty= ruser= rhost=  user=alice



 Comments   
Comment by Sergei Golubchik [ 2019-06-30 ]

I didn't try to repeat all these steps with strace, but I tried a 64-character password and it worked.
(after fixing MDEV-19876 and MDEV-19878)

Comment by Geoff Montee (Inactive) [ 2019-10-15 ]

This bug is still present. See MDEV-20571.

Comment by Daniel Black [ 2021-02-12 ]

Upstream php-7.4+ fix approved - https://github.com/php/php-src/pull/6667

Generated at Thu Feb 08 08:55:05 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.