[CentOS] Unable to apply mysqld_db_t to mysql directory

Mon Oct 23 21:13:59 UTC 2017
James Hogarth <james.hogarth at gmail.com>

On 23 October 2017 at 19:18, Bernard Fay <bernard.fay at gmail.com> wrote:
> Thanks, I managed to fix /var/lib/mysql
> # ls -ldZ /var/lib/mysql
> drwxr-xr-x. mysql mysql system_u:object_r:mysqld_db_t:s0 /var/lib/mysql
> To fix it, I tried:
> semanage fcontext -d -e /var/lib/mysql
> this command returned:
> KeyError: /var/lib/mysql
> I tried restorecon anyway:
> restorecon -Rv /var/lib/mysql
> But not better:
> ls -ldZ /var/lib/mysql
> drwxr-xr-x. mysql mysql system_u:object_r:var_lib_t:s0   /var/lib/mysql
> So I did the following:
> semanage fcontext -d -t var_lib_t /var/lib/mysql
> It started to look better:
> ls -ldZ /var/lib/mysql
> drwxr-xr-x. mysql mysql system_u:object_r:var_lib_t:s0   /var/lib/mysql
> Then I ran restorecon
> restorecon -Rv /var/lib/mysql
> I got a lot of :
> restorecon reset /var/lib/mysql/...
> And then I got the proper context on /var/lib/mysql.
> I think there are still many things I do not understand about SELinux.
> I thought the equivalence thing I did with the command below was going to
> assign the context of /var/lib/mysql.old to /var/lib/mysql. Obviously not!
> semanage fcontext -a -e /var/lib/mysql.old /var/lib/mysql

I think you have a slight misconception over how labels are determined.

There's no relation between what is presently on the filesystem when
you do ls -lZ and what the policy database thinks it ought to be.

This is why you can chcon to change the label of something but a
relabelling will change it back.

When you run restorecon to relabel a path what happens is it takes the
absolute (full) path and compares it against the regexes in the
selinux policy database (see it with semanage fcontext -l for some,
but now all, context matches) ...

Then for the most specific match it will apply whatever label is in
that database.

When you do semanage fcontext -a -e /foo /bar to do an alias what you
are telling selinux is that for every time that /bar is run through
the regex replace bar with foo and check that instead.

This is why when adding custom labelling you need to do a full regex
path to match files under that directory too.

When you moved /var/lib/mysql to /var/lib/mysql.old the labels moved
with the files (this is the default unless you cross filesystems, you
can force labelling as the destination with mv -Z).

The selinux database still has /var/lib/mysql(/.*)? as being type
mysqldb_db_t even if that directory doesn't exist.

When the directory is created and put in place then it will get what
policy says is right for that path.

The point of using equivalence is when you move a default location -
such as /home to /data/home or /var/lib/mysql to /data/mysql

In that situation the default selinux policy doesn't know anything
about /data or the contents of it so it'll end up with a default_t
label ... not very useful.

Now you could semanage fcontext -a -t mysqldb_db_t /data/mysql(/.*)?
but quite often the 'story' of a directory tree isn't about just one
label and it'd be tedious trying to match them all ...

For the craziness that is $HOME for instance...

CentOS7: cat /etc/selinux/targeted/contexts/files/file_contexts.homedirs
Fedora: cat /usr/share/selinux/targeted/default/active/homedir_template

There's a lot of different contexts depending on the file in that tree
... trying to mimic them all to move /home to /data/home would be a
nightmare ...

But this is made trivial with semanage fcontext -a -e /home /data/home
to ensure ~/.ssh and ~/.gpg and ~/public_html and so on all get the
right contexts.

So based on that I hope you understand why the equivalence lines you
have left are effectively meaningless - they are not absolute paths
and so can't match a tree to do the labelling replacement.

Does that help make things a bit clearer on your file contexts?

TL:DR; there was no need to "assign" as you were still using the
default mysql DB path, just a restorecon would have solved it.