Support mapping prop_area as rw

This commit is contained in:
topjohnwu 2023-05-17 00:44:08 -07:00
parent d9fc183fa8
commit 45a1be038c
8 changed files with 31 additions and 12 deletions

View File

@ -53,7 +53,7 @@ bool ContextNode::Open(bool access_rw, bool* fsetxattr_failed) {
if (access_rw) {
pa_ = prop_area::map_prop_area_rw(filename.c_str(), context_, fsetxattr_failed);
} else {
pa_ = prop_area::map_prop_area(filename.c_str());
pa_ = prop_area::map_prop_area(filename.c_str(), nullptr);
}
lock_.unlock();
return pa_;

View File

@ -70,7 +70,7 @@ bool ContextsSerialized::MapSerialPropertyArea(bool access_rw, bool* fsetxattr_f
serial_prop_area_ = prop_area::map_prop_area_rw(
serial_filename_.c_str(), "u:object_r:properties_serial:s0", fsetxattr_failed);
} else {
serial_prop_area_ = prop_area::map_prop_area(serial_filename_.c_str());
serial_prop_area_ = prop_area::map_prop_area(serial_filename_.c_str(), &rw_);
}
return serial_prop_area_;
}

View File

@ -197,7 +197,7 @@ bool ContextsSplit::MapSerialPropertyArea(bool access_rw, bool* fsetxattr_failed
serial_prop_area_ = prop_area::map_prop_area_rw(
filename.c_str(), "u:object_r:properties_serial:s0", fsetxattr_failed);
} else {
serial_prop_area_ = prop_area::map_prop_area(filename.c_str());
serial_prop_area_ = prop_area::map_prop_area(filename.c_str(), &rw_);
}
return serial_prop_area_;
}

View File

@ -43,4 +43,5 @@ class Contexts {
virtual void ForEach(void (*propfn)(const prop_info* pi, void* cookie), void* cookie) = 0;
virtual void ResetAccess() = 0;
virtual void FreeAndUnmap() = 0;
bool rw_ = false;
};

View File

@ -39,7 +39,7 @@ class ContextsPreSplit : public Contexts {
// We'll never initialize this legacy option as writable, so don't even check the arg.
virtual bool Initialize(bool, const char* filename, bool*, bool) override {
pre_split_prop_area_ = prop_area::map_prop_area(filename);
pre_split_prop_area_ = prop_area::map_prop_area(filename, &rw_);
return pre_split_prop_area_ != nullptr;
}

View File

@ -93,7 +93,7 @@ class prop_area {
public:
static prop_area* map_prop_area_rw(const char* filename, const char* context,
bool* fsetxattr_failed);
static prop_area* map_prop_area(const char* filename);
static prop_area* map_prop_area(const char* filename, bool *is_rw);
static void unmap_prop_area(prop_area** pa) {
if (*pa) {
munmap(*pa, pa_size_);
@ -139,7 +139,7 @@ class prop_area {
char* dirty_backup_area() { return data_ + sizeof(prop_trie_node); }
private:
static prop_area* map_fd_ro(const int fd);
static prop_area* map_fd_ro(const int fd, bool rw);
void* allocate_obj(const size_t size, uint_least32_t* const off);
prop_trie_node* new_prop_trie_node(const char* name, uint32_t namelen, uint_least32_t* const off);

View File

@ -104,7 +104,7 @@ prop_area* prop_area::map_prop_area_rw(const char* filename, const char* context
return pa;
}
prop_area* prop_area::map_fd_ro(const int fd) {
prop_area* prop_area::map_fd_ro(const int fd, bool rw) {
struct stat fd_stat;
if (fstat(fd, &fd_stat) < 0) {
return nullptr;
@ -119,7 +119,8 @@ prop_area* prop_area::map_fd_ro(const int fd) {
pa_size_ = fd_stat.st_size;
pa_data_size_ = pa_size_ - sizeof(prop_area);
void* const map_result = mmap(nullptr, pa_size_, PROT_READ, MAP_SHARED, fd, 0);
int prot = rw ? PROT_READ | PROT_WRITE : PROT_READ;
void* const map_result = mmap(nullptr, pa_size_, prot, MAP_SHARED, fd, 0);
if (map_result == MAP_FAILED) {
return nullptr;
}
@ -133,13 +134,22 @@ prop_area* prop_area::map_fd_ro(const int fd) {
return pa;
}
prop_area* prop_area::map_prop_area(const char* filename) {
int fd = open(filename, O_CLOEXEC | O_NOFOLLOW | O_RDONLY);
if (fd == -1) return nullptr;
prop_area* prop_area::map_prop_area(const char* filename, bool *is_rw) {
bool rw = false;
int fd = open(filename, O_CLOEXEC | O_NOFOLLOW | O_RDWR);
if (fd == -1) {
fd = open(filename, O_CLOEXEC | O_NOFOLLOW | O_RDONLY);
if (fd == -1) {
return nullptr;
}
} else {
rw = true;
}
prop_area* map_result = map_fd_ro(fd);
prop_area* map_result = map_fd_ro(fd, rw);
close(fd);
if (is_rw) *is_rw = rw;
return map_result;
}

View File

@ -276,6 +276,10 @@ int SystemProperties::Update(prop_info* pi, const char* value, unsigned int len)
}
bool have_override = appcompat_override_contexts_ != nullptr;
if (!contexts_->rw_) {
return -1;
}
prop_area* serial_pa = contexts_->GetSerialPropArea();
prop_area* override_serial_pa =
have_override ? appcompat_override_contexts_->GetSerialPropArea() : nullptr;
@ -355,6 +359,10 @@ int SystemProperties::Add(const char* name, unsigned int namelen, const char* va
return -1;
}
if (!contexts_->rw_) {
return -1;
}
prop_area* serial_pa = contexts_->GetSerialPropArea();
if (serial_pa == nullptr) {
async_safe_format_log(ANDROID_LOG_ERROR, "libc",