libcutils: android_get_control_file uses realpath.
If the path to android_get_control_file is a symlink, the final sanity check will fail that the fd does not have the same path as the given file. We can't expect callers to readlink() because this would change the environment key. Instead, try to call realpath on both paths. Bug: 126233777 Test: lpdump Change-Id: I0df10d7dbe3e572b8335faad812e5cd80bff1733
This commit is contained in:
parent
7acb0d39e8
commit
dd6eefca30
1 changed files with 18 additions and 17 deletions
|
@ -39,6 +39,11 @@
|
|||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <android-base/file.h>
|
||||
#include <android-base/stringprintf.h>
|
||||
|
||||
#include "android_get_control_env.h"
|
||||
|
||||
int __android_get_control_from_env(const char* prefix, const char* name) {
|
||||
|
@ -72,26 +77,22 @@ int __android_get_control_from_env(const char* prefix, const char* name) {
|
|||
}
|
||||
|
||||
int android_get_control_file(const char* path) {
|
||||
int fd = __android_get_control_from_env(ANDROID_FILE_ENV_PREFIX, path);
|
||||
std::string given_path;
|
||||
if (!android::base::Realpath(path, &given_path)) return -1;
|
||||
|
||||
// Try path, then realpath(path), as keys to get the fd from env.
|
||||
auto fd = __android_get_control_from_env(ANDROID_FILE_ENV_PREFIX, path);
|
||||
if (fd < 0) {
|
||||
fd = __android_get_control_from_env(ANDROID_FILE_ENV_PREFIX, given_path.c_str());
|
||||
if (fd < 0) return fd;
|
||||
}
|
||||
|
||||
// Find file path from /proc and make sure it is correct
|
||||
char *proc = NULL;
|
||||
if (asprintf(&proc, "/proc/self/fd/%d", fd) < 0) return -1;
|
||||
if (!proc) return -1;
|
||||
auto proc = android::base::StringPrintf("/proc/self/fd/%d", fd);
|
||||
std::string fd_path;
|
||||
if (!android::base::Realpath(proc, &fd_path)) return -1;
|
||||
|
||||
size_t len = strlen(path);
|
||||
// readlink() does not guarantee a nul byte, len+2 so we catch truncation.
|
||||
char *buf = static_cast<char *>(calloc(1, len + 2));
|
||||
if (!buf) {
|
||||
free(proc);
|
||||
return -1;
|
||||
}
|
||||
ssize_t ret = TEMP_FAILURE_RETRY(readlink(proc, buf, len + 1));
|
||||
free(proc);
|
||||
int cmp = (len != static_cast<size_t>(ret)) || strcmp(buf, path);
|
||||
free(buf);
|
||||
if (ret < 0) return -1;
|
||||
if (cmp != 0) return -1;
|
||||
if (given_path != fd_path) return -1;
|
||||
// It is what we think it is
|
||||
|
||||
return fd;
|
||||
|
|
Loading…
Reference in a new issue