libselinux: selinux_file_context_verify function returns wrong value.

selinux_file_context_verify(3) should now return the correct codes and
matchpathcon(8) has been modified to handle them.

The selinux_file_context_verify(3)and selinux_file_context_cmp(3) man pages
have also been updated (re-written really) to correct return codes.

I found that selabel_open left errno set to ENOENT because a
file_contexts.subs file did not exist on my system, but left selabel_open
alone and set errno = 0 before calling selinux_filecontext_cmp.

[fix uninitialize init variable in matchpathcon.c::main - eparis]
Signed-off-by: Eric Paris <eparis@redhat.com>
Acked-by: Dan Walsh <dwalsh@redhat.com>
This commit is contained in:
Richard Haines 2011-03-09 16:34:08 +00:00 committed by Eric Paris
parent 7df397d3d9
commit bc1a8e2a4a
5 changed files with 177 additions and 21 deletions

View File

@ -566,7 +566,7 @@ extern int selinux_file_context_cmp(const security_context_t a,
/*
* Verify the context of the file 'path' against policy.
* Return 0 if correct.
* Return 1 if match, 0 if not and -1 on error.
*/
extern int selinux_file_context_verify(const char *path, mode_t mode);

View File

@ -1,25 +1,75 @@
.TH "selinux_file_context_cmp" "3" "21 November 2009" "sds@tycho.nsa.gov" "SELinux API documentation"
.TH "selinux_file_context_cmp" "3" "08 March 2011" "SELinux API documentation"
.SH "NAME"
selinux_file_context_cmp, selinux_file_context_verify \- comparison of two file contexts.
selinux_file_context_cmp \- Compare two SELinux security contexts excluding the 'user' component.
.SH "SYNOPSIS"
.B #include <selinux/selinux.h>
.sp
.BI "int selinux_file_context_cmp(const security_context_t " a ", const security_context_t " b ");"
.BI "int selinux_file_context_verify(const char *" path ", mode_t " mode ");"
.BI "int selinux_file_context_cmp(const security_context_t " a ", "
.RS
.BI "const security_context_t " b ");"
.RE
.SH "DESCRIPTION"
.B selinux_file_context_cmp
compares two file contexts to see if their differences are "significant", the function runs the strcmp function ignoring the user componant of the file context.
.sp
.B selinux_file_context_verify
compares the file context on disk to the system default.
compares two context strings excluding the user component with
.B strcmp(3)
as shown in the
.B EXAMPLE
section.
.sp
This is useful as for most object contexts, the user component is not relevant.
.SH "RETURN VALUE"
Returns zero on success or \-1 otherwise.
The return values follow the
.B strcmp(3)
function, where:
.RS
0 if they are equal.
.RE
.RS
1 if
.I a
is greater than
.I b
.RE
.RS
\-1 if
.I a
is less than
.I b
.RE
.SH "ERRORS"
None.
.SH "NOTES"
The contexts being compared do not specifically need to be file contexts.
.SH "EXAMPLE"
If context
.I a
is:
.RS
user_u:user_r:user_t:s0
.RE
.sp
and context
.I b
is:
.RS
root:user_r:user_t:s0
.RE
.sp
then the actual strings compared are:
.RS
:user_r:user_t:s0 and :user_r:user_t:s0
.RE
.sp
Therefore they will match and
.B selinux_file_context_cmp
will return zero.
.SH "SEE ALSO"
.BR selinux "(8), " selinux_lsetfilecon "(3), " matchpathcon "(3), " freecon "(3), " setfilecon "(3), " setfscreatecon "(3)"
.BR selinux "(8)"

View File

@ -1 +1,98 @@
.so man3/selinux_file_context_cmp.3
.TH "selinux_file_context_verify" "3" "08 March 2011" "SELinux API documentation"
.SH "NAME"
selinux_file_context_verify \- Compare the SELinux security context on disk to the default security context required by the policy file contexts file.
.SH "SYNOPSIS"
.B #include <selinux/selinux.h>
.sp
.BI "int selinux_file_context_verify(const char *" path ", mode_t " mode ");"
.SH "DESCRIPTION"
.B selinux_file_context_verify
compares the context of the specified
.I path
that is held on disk (in the extended attribute), to the system default entry held in the file contexts series of files.
.sp
The
.I mode
may be zero.
.sp
Note that the two contexts are compared for "significant" differences (i.e. the user component of the contexts are ignored) as shown in the
.B EXAMPLE
section.
.SH "RETURN VALUE"
If the contexts significantly match, 1 (one) is returned.
.sp
If the contexts do not match 0 (zero) is returned and
.I errno
is set to either
.B ENOENT
or
.B EINVAL
for the reasons listed in the
.B ERRORS
section, or if
.I errno
= 0 then the contexts did not match.
.sp
On failure \-1 is returned and
.I errno
set appropriately.
.SH "ERRORS"
.TP
.B ENOTSUP
if extended attributes are not supported by the file system.
.TP
.B ENOENT
if there is no entry in the file contexts series of files or
.I path
does not exist.
.TP
.B EINVAL
if the entry in the file contexts series of files or
.I path
are invalid, or the returned context fails validation.
.TP
.B ENOMEM
if attempt to allocate memory failed.
.SH "FILES"
The following configuration files (the file contexts series of files) supporting the active policy will be used (should they exist) to determine the
.I path
default context:
.sp
.RS
contexts/files/file_contexts - This file must exist.
.sp
contexts/files/file_contexts.local - If exists has local customizations.
.sp
contexts/files/file_contexts.homedirs - If exists has users home directory customizations.
.sp
contexts/files/file_contexts.subs - If exists has substitutions that are then applied to the 'in memory' version of the file contexts files.
.RE
.SH "EXAMPLE"
If the files context is:
.RS
unconfined_u:object_r:admin_home_t:s0
.RE
.sp
and the default context defined in the file contexts file is:
.RS
system_u:object_r:admin_home_t:s0
.RE
.sp
then the actual strings compared are:
.RS
:object_r:admin_home_t:s0 and :object_r:admin_home_t:s0
.RE
.sp
Therefore they will match and
.B selinux_file_context_verify
will return 1.
.SH "SEE ALSO"
.BR selinux "(8)"

View File

@ -463,7 +463,7 @@ int selinux_file_context_verify(const char *path, mode_t mode)
rc = lgetfilecon_raw(path, &con);
if (rc == -1) {
if (errno != ENOTSUP)
return 1;
return -1;
else
return 0;
}
@ -473,11 +473,18 @@ int selinux_file_context_verify(const char *path, mode_t mode)
if (selabel_lookup_raw(hnd, &fcontext, path, mode) != 0) {
if (errno != ENOENT)
rc = 1;
rc = -1;
else
rc = 0;
} else
} else {
/*
* Need to set errno to 0 as it can be set to ENOENT if the
* file_contexts.subs file does not exist (see selabel_open in
* label.c), thus causing confusion if errno is checked on return.
*/
errno = 0;
rc = (selinux_file_context_cmp(fcontext, con) == 0);
}
freecon(con);
freecon(fcontext);

View File

@ -45,7 +45,7 @@ int printmatchpathcon(char *path, int header, int mode)
int main(int argc, char **argv)
{
int i, init = 0;
int i, init = 0, rc = 0;
int header = 1, opt;
int verify = 0;
int notrans = 0;
@ -121,17 +121,19 @@ int main(int argc, char **argv)
rc = selinux_file_context_verify(path, mode);
if (quiet) {
if (rc)
if (rc == 1)
continue;
else
exit(1);
}
if (rc) {
if (rc == -1) {
printf("%s error: %s\n", path, strerror(errno));
exit(1);
} else if (rc == 1) {
printf("%s verified.\n", path);
} else {
security_context_t con;
int rc;
error = 1;
if (notrans)
rc = lgetfilecon_raw(path, &con);