Merge changes from topic "lpdumpd"
* changes: libbase: realpath is wrapped with TEMP_FAILURE_RETRY liblp: Replace open with GetControlFileOrOpen init: expand prop in 'file' libcutils: android_get_control_file uses realpath.
This commit is contained in:
commit
f959fffc1c
8 changed files with 59 additions and 22 deletions
|
|
@ -385,7 +385,12 @@ bool Readlink(const std::string& path, std::string* result) {
|
||||||
bool Realpath(const std::string& path, std::string* result) {
|
bool Realpath(const std::string& path, std::string* result) {
|
||||||
result->clear();
|
result->clear();
|
||||||
|
|
||||||
char* realpath_buf = realpath(path.c_str(), nullptr);
|
// realpath may exit with EINTR. Retry if so.
|
||||||
|
char* realpath_buf = nullptr;
|
||||||
|
do {
|
||||||
|
realpath_buf = realpath(path.c_str(), nullptr);
|
||||||
|
} while (realpath_buf == nullptr && errno == EINTR);
|
||||||
|
|
||||||
if (realpath_buf == nullptr) {
|
if (realpath_buf == nullptr) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,11 @@ cc_library {
|
||||||
windows: {
|
windows: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
},
|
},
|
||||||
|
android: {
|
||||||
|
shared_libs: [
|
||||||
|
"libcutils",
|
||||||
|
],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
export_include_dirs: ["include"],
|
export_include_dirs: ["include"],
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,7 @@ std::unique_ptr<LpMetadata> ReadFromImageBlob(const void* data, size_t bytes) {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<LpMetadata> ReadFromImageFile(const std::string& image_file) {
|
std::unique_ptr<LpMetadata> ReadFromImageFile(const std::string& image_file) {
|
||||||
unique_fd fd(open(image_file.c_str(), O_RDONLY | O_CLOEXEC));
|
unique_fd fd = GetControlFileOrOpen(image_file.c_str(), O_RDONLY | O_CLOEXEC);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
PERROR << __PRETTY_FUNCTION__ << " open failed: " << image_file;
|
PERROR << __PRETTY_FUNCTION__ << " open failed: " << image_file;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
@ -408,7 +408,7 @@ bool SparseBuilder::CheckExtentOrdering() {
|
||||||
}
|
}
|
||||||
|
|
||||||
int SparseBuilder::OpenImageFile(const std::string& file) {
|
int SparseBuilder::OpenImageFile(const std::string& file) {
|
||||||
android::base::unique_fd source_fd(open(file.c_str(), O_RDONLY | O_CLOEXEC));
|
android::base::unique_fd source_fd = GetControlFileOrOpen(file.c_str(), O_RDONLY | O_CLOEXEC);
|
||||||
if (source_fd < 0) {
|
if (source_fd < 0) {
|
||||||
PERROR << "open image file failed: " << file;
|
PERROR << "open image file failed: " << file;
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ std::string GetPartitionAbsolutePath(const std::string& path) {
|
||||||
|
|
||||||
bool GetBlockDeviceInfo(const std::string& block_device, BlockDeviceInfo* device_info) {
|
bool GetBlockDeviceInfo(const std::string& block_device, BlockDeviceInfo* device_info) {
|
||||||
#if defined(__linux__)
|
#if defined(__linux__)
|
||||||
unique_fd fd(open(block_device.c_str(), O_RDONLY));
|
unique_fd fd = GetControlFileOrOpen(block_device.c_str(), O_RDONLY);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
PERROR << __PRETTY_FUNCTION__ << "open '" << block_device << "' failed";
|
PERROR << __PRETTY_FUNCTION__ << "open '" << block_device << "' failed";
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -85,7 +85,7 @@ bool GetBlockDeviceInfo(const std::string& block_device, BlockDeviceInfo* device
|
||||||
|
|
||||||
unique_fd PartitionOpener::Open(const std::string& partition_name, int flags) const {
|
unique_fd PartitionOpener::Open(const std::string& partition_name, int flags) const {
|
||||||
std::string path = GetPartitionAbsolutePath(partition_name);
|
std::string path = GetPartitionAbsolutePath(partition_name);
|
||||||
return unique_fd{open(path.c_str(), flags | O_CLOEXEC)};
|
return GetControlFileOrOpen(path.c_str(), flags | O_CLOEXEC);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PartitionOpener::GetInfo(const std::string& partition_name, BlockDeviceInfo* info) const {
|
bool PartitionOpener::GetInfo(const std::string& partition_name, BlockDeviceInfo* info) const {
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,10 @@
|
||||||
#include <ext4_utils/ext4_utils.h>
|
#include <ext4_utils/ext4_utils.h>
|
||||||
#include <openssl/sha.h>
|
#include <openssl/sha.h>
|
||||||
|
|
||||||
|
#ifdef __ANDROID__
|
||||||
|
#include <cutils/android_get_control_file.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "utility.h"
|
#include "utility.h"
|
||||||
|
|
||||||
namespace android {
|
namespace android {
|
||||||
|
|
@ -171,5 +175,19 @@ bool SetBlockReadonly(int fd, bool readonly) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
base::unique_fd GetControlFileOrOpen(const char* path, int flags) {
|
||||||
|
#if defined(__ANDROID__)
|
||||||
|
int fd = android_get_control_file(path);
|
||||||
|
if (fd >= 0) {
|
||||||
|
int newfd = TEMP_FAILURE_RETRY(dup(fd));
|
||||||
|
if (newfd >= 0) {
|
||||||
|
return base::unique_fd(newfd);
|
||||||
|
}
|
||||||
|
PERROR << "Cannot dup fd for already controlled file: " << path << ", reopening...";
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return base::unique_fd(open(path, flags));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace fs_mgr
|
} // namespace fs_mgr
|
||||||
} // namespace android
|
} // namespace android
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include <android-base/logging.h>
|
#include <android-base/logging.h>
|
||||||
|
#include <android-base/unique_fd.h>
|
||||||
|
|
||||||
#include "liblp/liblp.h"
|
#include "liblp/liblp.h"
|
||||||
|
|
||||||
|
|
@ -92,6 +93,8 @@ bool UpdatePartitionGroupName(LpMetadataPartitionGroup* group, const std::string
|
||||||
// Call BLKROSET ioctl on fd so that fd is readonly / read-writable.
|
// Call BLKROSET ioctl on fd so that fd is readonly / read-writable.
|
||||||
bool SetBlockReadonly(int fd, bool readonly);
|
bool SetBlockReadonly(int fd, bool readonly);
|
||||||
|
|
||||||
|
::android::base::unique_fd GetControlFileOrOpen(const char* path, int flags);
|
||||||
|
|
||||||
} // namespace fs_mgr
|
} // namespace fs_mgr
|
||||||
} // namespace android
|
} // namespace android
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -756,6 +756,11 @@ Result<Success> Service::ParseFile(std::vector<std::string>&& args) {
|
||||||
if (args[2] != "r" && args[2] != "w" && args[2] != "rw") {
|
if (args[2] != "r" && args[2] != "w" && args[2] != "rw") {
|
||||||
return Error() << "file type must be 'r', 'w' or 'rw'";
|
return Error() << "file type must be 'r', 'w' or 'rw'";
|
||||||
}
|
}
|
||||||
|
std::string expanded;
|
||||||
|
if (!expand_props(args[1], &expanded)) {
|
||||||
|
return Error() << "Could not expand property in file path '" << args[1] << "'";
|
||||||
|
}
|
||||||
|
args[1] = std::move(expanded);
|
||||||
if ((args[1][0] != '/') || (args[1].find("../") != std::string::npos)) {
|
if ((args[1][0] != '/') || (args[1].find("../") != std::string::npos)) {
|
||||||
return Error() << "file name must not be relative";
|
return Error() << "file name must not be relative";
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,11 @@
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <android-base/file.h>
|
||||||
|
#include <android-base/stringprintf.h>
|
||||||
|
|
||||||
#include "android_get_control_env.h"
|
#include "android_get_control_env.h"
|
||||||
|
|
||||||
int __android_get_control_from_env(const char* prefix, const char* name) {
|
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 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
|
// Find file path from /proc and make sure it is correct
|
||||||
char *proc = NULL;
|
auto proc = android::base::StringPrintf("/proc/self/fd/%d", fd);
|
||||||
if (asprintf(&proc, "/proc/self/fd/%d", fd) < 0) return -1;
|
std::string fd_path;
|
||||||
if (!proc) return -1;
|
if (!android::base::Realpath(proc, &fd_path)) return -1;
|
||||||
|
|
||||||
size_t len = strlen(path);
|
if (given_path != fd_path) return -1;
|
||||||
// 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;
|
|
||||||
// It is what we think it is
|
// It is what we think it is
|
||||||
|
|
||||||
return fd;
|
return fd;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue