Bug 471564

Summary: locate only opens the first database from LOCATE_PATH before dropping privs
Product: [Fedora] Fedora Reporter: Kieran Clancy <clancy.kieran+redhat>
Component: mlocateAssignee: Miloslav Trmač <mitr>
Status: CLOSED RAWHIDE QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: medium Docs Contact:
Priority: medium    
Version: 9CC: mitr
Target Milestone: ---   
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2008-11-17 18:55:26 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Kieran Clancy 2008-11-14 09:36:27 UTC
Description of problem:
I have two additional locate databases in /var/lib/mlocate, and LOCATE_PATH is set to be /var/lib/mlocate/extra1.db:/var/lib/mlocate/extra2.db.

When locate is run as a normal user, the default mlocate.db database is read first, then extra1.db is searched, but when trying to open extra2.db, it generates an error:
locate: can not open `/var/lib/mlocate/extra2.db': Permission denied

I think it must be dropping its setgid/setuid privileges between opening the first and second databases in LOCATE_PATH. If I set LOCATE_PATH to just one extra database or the other (not both), it searches the respective databases without problems.

Version-Release number of selected component (if applicable):
mlocate-0.21-1.fc9.x86_64

Steps to Reproduce:
1. updatedb -o /var/lib/mlocate/extra1.db -U /etc
2. updatedb -o /var/lib/mlocate/extra2.db -U /var/log
3. set LOCATE_PATH=/var/lib/mlocate/extra1.db:/var/lib/mlocate/extra2.db
4. locate messages
  
Actual results:
Will generate an error when trying to open extra2.db

Expected results:
Will open and search extra2.db

Comment 1 Miloslav Trmač 2008-11-14 16:10:41 UTC
Thanks for your report.

This seems to work for me fine.  Please attach the output of the following commands:
* (ls -laZ /var/lib/mlocate) run as root
* (id -a) run as the user you run locate with
* (ls -lZ /usr/bin/locate)

Also please check whether running locate as root completes without error.

Comment 2 Kieran Clancy 2008-11-14 23:14:54 UTC
Thanks for responding so quickly.

It seems that the problem only occurs when I run updatedb with -l 0.
So the first two commands to reproduce should actually be:
1. updatedb -l 0 -o /var/lib/mlocate/extra1.db -U /etc
2. updatedb -l 0 -o /var/lib/mlocate/extra2.db -U /var/log

Sorry about missing that in my original report.

Here are the listings
drwxr-x---  root slocate system_u:object_r:locate_var_lib_t:s0 .
drwxr-xr-x  root root system_u:object_r:var_lib_t:s0   ..
-rw-r--r--  root root unconfined_u:object_r:locate_var_lib_t:s0 extra1.db
-rw-r--r--  root root unconfined_u:object_r:locate_var_lib_t:s0 extra2.db
-rw-r-----  root slocate system_u:object_r:locate_var_lib_t:s0 mlocate.db

-rwx--s--x  root slocate system_u:object_r:bin_t:s0       /usr/bin/locate

uid=500(kieran) gid=500(kieran) groups=491(webadmin),500(kieran) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

Running locate as root works without errors.

I am not actually getting any AVC denials in /var/log/messages, so I don't think it's SELinux related.

I tried chgrp slocate /var/lib/mlocate/extra*, but that didn't work.

Then I tried chmod o-r /var/lib/mlocate/extra*, and then it did work! So taking away global read privileges makes it work.

I had a bit of a look at the source code, and it seems that mlocate is doing something like:
- Check if any of the databases need the setgid privileges, and order them first in the list
- While going through the list, if a database doesn't need setgid privileges, drop them

It seems that it's seeing that the file is world-readable, and not adding it to that special list of files which need setgid privileges, even though it's in a directory that does need setgid privileges to be read.

I'm guessing this is so that mlocate will not have any special privileges when it tries to read a user-specified database (which may be malformed and cause mlocate to crash). If this is the intention, it seems strange that the error only happens for the second file in LOCATE_PATH though.

Comment 3 Miloslav Trmač 2008-11-17 18:55:26 UTC
Thanks, that explains it.

locate indeed drops privileges after encountering a database that does not have the usual group and permissions for databases created with "-l 1".  Without this chech a malicious user might create a malicious mlocate database file in $dir/t/db [assuming an exploitable bug in locate, and I don't know about any such bug], and then simply (chmod ug-rwx $dir/t) to make sure locate does not drop privileges because the [sm]locate group ID is necessary to access $dir/t/db.

I have added an additional check in https://fedorahosted.org/mlocate/changeset/131%3A4bd067873b1d that rejects even the first database like this:

locate: can not open `/var/lib/mlocate/extra1.db': Permission denied
locate: can not stat () `/var/lib/mlocate/extra2.db': Permission denied

This check will be available in the next version of mlocate when it is released.