Fix avc_has_perm() returns -1 even when SELinux is in permissive mode.

If we get an EINVAL from security_compute_av* (indicates an invalid
source or target security context, likely due to a policy reload that
removed one or the other) and we are in permissive mode, then handle it
like any other permission denial, i.e. log but do not deny it.

Reported-by: Laurent Bigonville <bigon@debian.org>
Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
This commit is contained in:
Stephen Smalley 2013-10-28 16:52:50 -04:00
parent 0ddd534a11
commit 8b114a3bf2

View File

@ -739,6 +739,16 @@ void avc_audit(security_id_t ssid, security_id_t tsid,
hidden_def(avc_audit)
static void avd_init(struct av_decision *avd)
{
avd->allowed = 0;
avd->auditallow = 0;
avd->auditdeny = 0xffffffff;
avd->seqno = avc_cache.latest_notif;
avd->flags = 0;
}
int avc_has_perm_noaudit(security_id_t ssid,
security_id_t tsid,
security_class_t tclass,
@ -751,6 +761,9 @@ int avc_has_perm_noaudit(security_id_t ssid,
access_vector_t denied;
struct avc_entry_ref ref;
if (avd)
avd_init(avd);
if (!avc_using_threads && !avc_app_main_loop) {
(void)avc_netlink_check_nb();
}
@ -783,6 +796,10 @@ int avc_has_perm_noaudit(security_id_t ssid,
rc = security_compute_av_flags_raw(ssid->ctx, tsid->ctx,
tclass, requested,
&entry.avd);
if (rc && errno == EINVAL && !avc_enforcing) {
rc = errno = 0;
goto out;
}
if (rc)
goto out;
rc = avc_insert(ssid, tsid, tclass, &entry, aeref);
@ -821,8 +838,6 @@ int avc_has_perm(security_id_t ssid, security_id_t tsid,
struct av_decision avd;
int errsave, rc;
memset(&avd, 0, sizeof(avd));
rc = avc_has_perm_noaudit(ssid, tsid, tclass, requested, aeref, &avd);
errsave = errno;
avc_audit(ssid, tsid, tclass, requested, &avd, rc, auditdata);