Bug 1412838 - Running passwd changes the security context of /etc/security/opasswd
Summary: Running passwd changes the security context of /etc/security/opasswd
Keywords:
Status: CLOSED ERRATA
Alias: None
Product: Red Hat Enterprise Linux 7
Classification: Red Hat
Component: selinux-policy
Version: 7.3
Hardware: All
OS: Linux
medium
medium
Target Milestone: rc
: ---
Assignee: Lukas Vrabec
QA Contact: Milos Malik
URL:
Whiteboard:
Depends On:
Blocks: 1420851
TreeView+ depends on / blocked
 
Reported: 2017-01-12 22:58 UTC by William Skupa
Modified: 2019-04-29 09:15 UTC (History)
17 users (show)

Fixed In Version: selinux-policy-3.13.1-187.el7
Doc Type: If docs needed, set a value
Doc Text:
Clone Of:
Environment:
Last Closed: 2018-04-10 12:26:56 UTC
Target Upstream Version:


Attachments (Terms of Use)


Links
System ID Priority Status Summary Last Updated
Red Hat Product Errata RHBA-2018:0763 normal SHIPPED_LIVE selinux-policy bug fix and enhancement update 2018-04-10 12:08:10 UTC

Description William Skupa 2017-01-12 22:58:55 UTC
Description of problem:
A user with an expired password logging in through a virtual terminal is unable to change their password and receives the error: "authentication token manipulation error".  This does not affect the same user logging in through GDM.  Users without expired passwords are able to change them just fine using passwd

/var/log/auth.log shows:
login: pam_unix(login:chauthtok): can't open /etc/security/opasswd

ls -lZ /etc/security/opasswd
rw- --- --- root root system_u:object_r:shadow_t:s0

A different user changes their password using passwd

ls -lZ /etc/security/opasswd
rw- --- --- root root system_u:object_r:passwd_file_t:s0

At this point users with expired passwords can successfully change their passwords when logging in through a virtual console.  No error messages in /var/log/auth.log


Version-Release number of selected component (if applicable):
RHEL 7.3

How reproducible:
100%

Steps to Reproduce:
1.  Create user1 and expire passwd
2.  Create user2 with valid/non-expired passwd
3.  Enable password history in pam
4.  Set SELinux to enforcing
5.  Attempt to logon to a virtual console as user1.  Enter valid existing password and a new password that meets complexity requirements.  Will get an error.
6.  Login as user2.  Change user2's password.
7.  ls -lZ /etc/security/opasswd; context will have changed
8.  Attempt to logon to a virtual console as user1.  Enter valid existing password and a new password that meets complexity requirements.  user1 successfully is logged in.

Actual results:
    user1 is unable to login to the virtual console.

    SELinux context of /etc/security/opasswd is changed after a user changes their password using passwd

Expected results:
    user1 is able to login to the virtual console.

    SELinux context of /etc/security/opasswd is not changed after a user changes their password using passwd

Additional info:

Comment 3 Tomas Mraz 2017-05-25 11:12:07 UTC
The correct context of the opasswd file should be shadow_t because we want the same protection of its contents as for /etc/shadow.

1. Please use pam_pwhistory instead of adding remember option to pam_unix. There is no way to make that remember option of pam_unix properly supported with SELinux.

Example of system-auth with it:

password    requisite     pam_pwquality.so try_first_pass local_users_only retry=3 authtok_type=
password    requisite     pam_pwhistory.so use_authtok remember=3
password    sufficient    pam_unix.so sha512 shadow nullok try_first_pass use_authtok
password    required      pam_deny.so

2. SELinux policy still needs fix as my testing shows that even with pam_pwhistory there is change of the context from shadow_t to etc_t.
opasswd is changed by pwhistory_helper which has updpwd_exec_t which means it would be running with updpwd_t domain.

Reassigning to selinux-policy for further investigation.

Comment 4 Lukas Vrabec 2017-08-17 11:24:22 UTC
Right now, we have two file transitions for updpwd_t:
type_transition updpwd_t etc_t:file shadow_t "gshadow";
type_transition updpwd_t etc_t:file shadow_t "nshadow";

But we need to add following transition rule: 
type_transition updpwd_t etc_t:file shadow_t "opasswd";


Milos,
Could we test this?

Comment 6 Boyd H. Ako 2018-01-27 01:22:57 UTC
Any update on this? It's also still happening on 7.4.

Feel free to send me the PP file to test it.

Comment 7 Milos Malik 2018-01-30 13:25:48 UTC
# rpm -qa selinux\*
selinux-policy-3.13.1-166.el7_4.8.noarch
selinux-policy-targeted-3.13.1-166.el7_4.8.noarch
# restorecon -Rv /etc/
# ls -Z /etc/security/opasswd 
-rw-------. root root unconfined_u:object_r:shadow_t:s0 /etc/security/opasswd
# chage -d 0 user1
#

Now I logged via ssh as user1 to the same machine and changed my password because it was expired.

# ls -Z /etc/security/opasswd 
-rw-------. root root unconfined_u:object_r:etc_t:s0   /etc/security/opasswd
#

Comment 8 Milos Malik 2018-01-30 13:34:26 UTC
The comment above was using the latest RHEL-7.4.z selinux-policy.

This comment is using the latest RHEL-7.5 selinux-policy:

# rpm -qa selinux\* pam\*
pam-1.1.8-22.el7.x86_64
selinux-policy-targeted-3.13.1-186.el7.noarch
selinux-policy-3.13.1-186.el7.noarch
# restorecon -Rv /etc/
# ls -Z /etc/security/opasswd
-rw-------. root root unconfined_u:object_r:shadow_t:s0 /etc/security/opasswd
# chage -d 0 user1
#

Now I logged via ssh as user1 to the same machine and changed my password because it was expired.

# ls -Z /etc/security/opasswd
-rw-------. root root unconfined_u:object_r:etc_t:s0   /etc/security/opasswd
# 

From my point of view the bug is NOT fixed.

Comment 9 Milos Malik 2018-01-30 13:43:05 UTC
Following rule is present in the latest RHEL-7.5 policy, but the bug can still be reproduced.

# sesearch -s updpwd_t -t etc_t -c file -T | grep opasswd
type_transition updpwd_t etc_t : file shadow_t "opasswd"; 
#

The type_transition rule is applied if and only if the opasswd file is created. If the file is created with a different name and renamed to opasswd, the type_transition rule is NOT applied.

Can you confirm which way is the /etc/security/opasswd file created and updated?

Comment 10 Milos Malik 2018-01-30 13:52:29 UTC
Running "strace -f -o output.txt passwd" as root revealed following things:

9835  open("/etc/security/opasswd", O_RDONLY) = 3
9835  fstat(3, {st_mode=S_IFREG|0600, st_size=95, ...}) = 0
9835  getpid()                          = 9835
9835  open("/etc/security/opasswd.tmp48vH27", O_RDWR|O_CREAT|O_EXCL, 0600) = 4
9835  fchmod(4, 0100600)                = 0
9835  fchown(4, 0, 0)                   = 0
9835  fcntl(4, F_GETFL)                 = 0x8002 (flags O_RDWR|O_LARGEFILE)
9835  fstat(3, {st_mode=S_IFREG|0600, st_size=95, ...}) = 0
9835  mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) =
 0x7f5a94109000
9835  read(3, "user1:1000:2:!!,$1$zLPN4Foi$yoiN"..., 4096) = 95
9835  fstat(4, {st_mode=S_IFREG|0600, st_size=0, ...}) = 0
9835  mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) =
 0x7f5a94108000
9835  read(3, "", 4096)                 = 0
9835  close(3)                          = 0
9835  munmap(0x7f5a94109000, 4096)      = 0
9835  write(4, "user1:1000:2:!!,$1$zLPN4Foi$yoiN"..., 130) = 130
9835  fsync(4)                          = 0
9835  close(4)                          = 0
9835  munmap(0x7f5a94108000, 4096)      = 0
9835  unlink("/etc/security/opasswd.old") = 0
9835  link("/etc/security/opasswd", "/etc/security/opasswd.old") = 0
9835  rename("/etc/security/opasswd.tmp48vH27", "/etc/security/opasswd") = 0
9835  unlink("/etc/security/opasswd.tmp48vH27") = -1 ENOENT (No such file or dir
ectory)

Comment 11 Tomas Mraz 2018-01-30 14:35:35 UTC
Did you use pam_pwhistory? I suppose you did.

Comment 12 Tomas Mraz 2018-01-30 14:37:45 UTC
Can there be a type transition rule with wildcard name?

Comment 13 Milos Malik 2018-01-30 14:47:49 UTC
The only difference between the password section in comment#3 and password section in my /etc/pam.d/system-auth file was:

md5 vs. sha512 on the "password    sufficient    pam_unix.so" line.

Comment 14 Milos Malik 2018-01-30 14:52:12 UTC
Unfortunately, wildcards are not supported.

But I can test the scenario with policy which contains a type_transition rule without a specific filename:

type_transition updpwd_t etc_t : file shadow_t;

Which will apply to any file that is created by a process running as updpwd_t.

Comment 15 Tomas Mraz 2018-01-30 15:01:21 UTC
I am afraid that would break update of /etc/passwd if you are moving from password has in /etc/passwd into shadowed password in /etc/shadow.

What executables are running as updpwd_t?

We would have to create a special domain for pwhistory_helper binary which could have such type transition rule, because pwhistory_helper does not write anything else than the opasswd file.

Comment 16 Tomas Mraz 2018-01-30 15:02:49 UTC
Or could the rule be limited just to the /etc/security subdirectory?

Comment 17 Milos Malik 2018-01-30 15:08:23 UTC
If I load a special policy module, so that policy contains following rule:

# sesearch -s updpwd_t -t etc_t -T
Found 1 semantic te rules:
   type_transition updpwd_t etc_t : file shadow_t; 

...

before password change and after password change the label remains the same:

# ls -Z /etc/security/opasswd
-rw-------. root root unconfined_u:object_r:shadow_t:s0 /etc/security/opasswd
#

Also "restorecon -Rv /etc" did not find any mislabeled objects under /etc.

Comment 18 Milos Malik 2018-01-30 15:09:40 UTC
# semanage fcontext -l | grep updpwd_exec_t
/sbin/unix_update                                  regular file       system_u:object_r:updpwd_exec_t:s0 
/usr/sbin/unix_update                              regular file       system_u:object_r:updpwd_exec_t:s0 
/usr/sbin/pwhistory_helper                         regular file       system_u:object_r:updpwd_exec_t:s0 
#

Comment 19 Tomas Mraz 2018-01-30 15:10:32 UTC
But try this - put your password hash from /etc/shadow to /etc/passwd instead of the x and try to change the password. Won't it change /etc/passwd to shadow_t?

Comment 20 Milos Malik 2018-01-30 15:32:12 UTC
After connecting via SSH I executed passwd as user1 and the change of password was successful. The hash in /etc/shadow is different and the hash in /etc/passwd got replaced by "x".

Unfortunately, if I made the user1 password expired (chage -d 0 user1) and then I connected via SSH as user1, the login process didn't tell me to change my password.

Comment 21 Tomas Mraz 2018-01-30 15:36:23 UTC
But what is the context of /etc/passwd now?

Even if it is correct, I am a little bit afraid of such general rule. We certainly would have to test things around changing passwords thoroughly.

The /etc/shadow is not consulted if /etc/passwd password hash is not 'x' AFAIK.

Comment 22 Milos Malik 2018-01-30 15:38:09 UTC
In both cases the label on /etc/passwd was correct:

# ls -Z /etc/passwd
-rw-r--r--. root root system_u:object_r:passwd_file_t:s0 /etc/passwd
#

Tested before and after the password change.

Comment 23 Tomas Mraz 2018-01-30 15:39:44 UTC
OK, great. unix_update actually tries to preserve the label on the passwd and shadow files. Unfortunately pwhistory_helper does not which is the reason we need this rule.

Comment 31 Zdenek Pytela 2018-03-22 15:09:23 UTC
Please note /etc/security/nopasswd can also be used, suffering from the same problem:

#define OLD_PASSWORDS_FILE      "/etc/security/opasswd"
...
#define OPW_TMPFILE             "/etc/security/nopasswd"
...
    pwfile = fopen(OPW_TMPFILE, "w");
...
    opwfile = fopen(OLD_PASSWORDS_FILE, "r");
...
    if (!err) {
	if (rename(OPW_TMPFILE, OLD_PASSWORDS_FILE))
	    err = 1;
    }

I suppose the current change in the selinux-policy package does not cover this scenario. Does the type transition for this file need be added to the policy, too?

Comment 36 errata-xmlrpc 2018-04-10 12:26:56 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory, and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

https://access.redhat.com/errata/RHBA-2018:0763


Note You need to log in before you can comment on or make changes to this bug.