Call realpath(3) only when the path is accessible for read

Suppress the SELinux denial log spam by not calling realpath(3) when the
path does not exist or is not accessible for read, and then not auditing
access(2) failure.

Bug: 120996057
Test: copy ping to /data/local/tmp, run it, verify no errors
Test: run bionic-unit-tests, the tests pass
Change-Id: Ie6058bfc9524a9b5c50fc7183fdddea6a8fb9200
This commit is contained in:
Jiyong Park 2019-01-25 18:18:01 +09:00
parent 3ce06c7b0a
commit 42e81985b1

View file

@ -41,6 +41,7 @@
#include <limits.h>
#include <stdlib.h>
#include <unistd.h>
#include <string>
#include <unordered_map>
@ -238,9 +239,17 @@ static bool parse_config_file(const char* ld_config_file_path,
// If the path can be resolved, resolve it
char buf[PATH_MAX];
std::string resolved_path;
if (realpath(value.c_str(), buf)) {
if (access(value.c_str(), R_OK) != 0) {
if (errno == ENOENT) {
// no need to test for non-existing path. skip.
continue;
}
// If not accessible, don't call realpath as it will just cause
// SELinux denial spam. Use the path unresolved.
resolved_path = value;
} else if (realpath(value.c_str(), buf)) {
resolved_path = buf;
} else if (errno != ENOENT) {
} else {
// realpath is expected to fail with EPERM in some situations, so log
// the failure with INFO rather than DL_WARN. e.g. A binary in
// /data/local/tmp may attempt to stat /postinstall. See
@ -251,9 +260,6 @@ static bool parse_config_file(const char* ld_config_file_path,
value.c_str(),
strerror(errno));
resolved_path = value;
} else {
// ENOENT: no need to test if binary is under the path
continue;
}
if (file_is_under_dir(binary_realpath, resolved_path)) {