Linux-PAM Helper unix_chkpwd not running

Hello,

I came across a puzzling problem.
I upgraded a development system PAM package from linux-pam-1.5.2 to linux-pam-1.6.1. The LXC version running is 5.0.2. Everything was working as expected before the upgrade.

On the unit, there is a containerized process that handles login requests. Inside the non-privileged LXC container, it uses /bin/login from util-linux 2.38. The corresponding PAM stack is very simple and relies only on pam_unix.so.

I noticed that between v1.5.2 and v1.6.1 a helper program unix_chkpwd was added to check the password in /etc/shadow file. So, I added the unix_chkpwd binary to the container and made sure that it has the right owner and file permissions.

However, after the upgrade every login attempt fails. The error in the syslog says:

[73489.958595] login[141698]: pam_unix(login:auth): authentication failure; logname=LOGIN uid=0 euid=0 tty=ttyS0 ruser= rhost=  user=cli
[73491.650173] login[141698]: pam_authenticate call failed: Authentication service cannot retrieve authentication info (9)

I’ve tried all sort of permissions permutations with no success.
I ran login with strace and it boils down to this error:

[pid    21] execve("/sbin/unix_chkpwd", ["/sbin/unix_chkpwd", "cli", "nonull"], 0x7c951740e2e8 /* 0 vars */) = -1 EACCES (Permission denied)

However, I wrote a three liner C program that invokes unix_chkpwd like that and it works fine.
I’ve restored all the capabilities inside the LXC and disabled apparmor and seccomp for this tests.

I also re-built linux-pam with --enable-debug and I get this output:

[support.c:_unix_verify_password(771)] running helper binary
[support.c:_unix_run_helper_binary(610)] passwd: admin
[support.c:_unix_run_helper_binary(633)] wait for helper to complete
[support.c:_unix_run_helper_binary(553)] child == 0
[support.c:_unix_run_helper_binary(645)] WEXITSTATUS(retval): 9
[support.c:_unix_run_helper_binary(659)] returning 9

Which is consistent with the underlying “Permission denied” above.
I’m running a custom distro: Linux buildroot 6.6.71-grsec

What else could be preventing a child process to fail with “Permission denied” like that?

I have never used the grsec patches, but I know they do SELinux-like things which could deny access. Could you try booting with a normal kernel to see if that makes a difference?

Thank you for the suggestion.

It turned out that Apparmor has several profiles and some were still enforced. When I run apparmor_parser -R /etc/apparmor.d all the profiles were disabled and the command worked.

Now it is only matter to identify the audits and update the corresponding files.

Cheers!

1 Like

Glad it’s working. The thing I forgot to suggest before was to check dmesg output: blocks by apparmor and SELinux tend to get logged there.

1 Like

The answer was in /var/log/audits/audit.log where a bunch of new AVC audits showed up. With the help of the aa-logprof tool I was able to modify the apparmor profile to allow the command.