mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-12-26 01:27:48 +00:00
Move all xwrap to Rust
This commit is contained in:
parent
66a7ef5615
commit
c6646efe68
7
native/src/Cargo.lock
generated
7
native/src/Cargo.lock
generated
@ -6,6 +6,7 @@ version = 3
|
|||||||
name = "base"
|
name = "base"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
"cxx",
|
"cxx",
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
@ -16,6 +17,12 @@ version = "1.0.73"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
|
checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg-if"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cxx"
|
name = "cxx"
|
||||||
version = "1.0.72"
|
version = "1.0.72"
|
||||||
|
@ -14,7 +14,6 @@ LOCAL_SRC_FILES := \
|
|||||||
misc.cpp \
|
misc.cpp \
|
||||||
selinux.cpp \
|
selinux.cpp \
|
||||||
logging.cpp \
|
logging.cpp \
|
||||||
xwrap.cpp \
|
|
||||||
stream.cpp \
|
stream.cpp \
|
||||||
../external/cxx-rs/src/cxx.cc
|
../external/cxx-rs/src/cxx.cc
|
||||||
include $(BUILD_STATIC_LIBRARY)
|
include $(BUILD_STATIC_LIBRARY)
|
||||||
|
@ -9,3 +9,4 @@ path = "lib.rs"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
cxx = { path = "../external/cxx-rs" }
|
cxx = { path = "../external/cxx-rs" }
|
||||||
libc = "0.2"
|
libc = "0.2"
|
||||||
|
cfg-if = "1.0"
|
||||||
|
@ -9,38 +9,12 @@
|
|||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
ssize_t fd_path(int fd, char *path, size_t size) {
|
|
||||||
ssprintf(path, size, "/proc/self/fd/%d", fd);
|
|
||||||
return xreadlink(path, path, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
int fd_pathat(int dirfd, const char *name, char *path, size_t size) {
|
int fd_pathat(int dirfd, const char *name, char *path, size_t size) {
|
||||||
if (fd_path(dirfd, path, size) < 0)
|
if (fd_path(dirfd, byte_slice(path, size)) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
auto len = strlen(path);
|
auto len = strlen(path);
|
||||||
path[len] = '/';
|
path[len] = '/';
|
||||||
strlcpy(path + len + 1, name, size - len - 1);
|
strscpy(path + len + 1, name, size - len - 1);
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int mkdirs(const char *path, mode_t mode) {
|
|
||||||
char buf[4096];
|
|
||||||
strlcpy(buf, path, sizeof(buf));
|
|
||||||
errno = 0;
|
|
||||||
for (char *p = &buf[1]; *p; ++p) {
|
|
||||||
if (*p == '/') {
|
|
||||||
*p = '\0';
|
|
||||||
if (mkdir(buf, mode) == -1) {
|
|
||||||
if (errno != EEXIST)
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
*p = '/';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (mkdir(buf, mode) == -1) {
|
|
||||||
if (errno != EEXIST)
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -410,14 +384,14 @@ void parse_mnt(const char *file, const function<bool(mntent*)> &fn) {
|
|||||||
|
|
||||||
void backup_folder(const char *dir, vector<raw_file> &files) {
|
void backup_folder(const char *dir, vector<raw_file> &files) {
|
||||||
char path[PATH_MAX];
|
char path[PATH_MAX];
|
||||||
xrealpath(dir, path);
|
xcanonical_path(dir, path, sizeof(path));
|
||||||
int len = strlen(path);
|
int len = strlen(path);
|
||||||
pre_order_walk(xopen(dir, O_RDONLY), [&](int dfd, dirent *entry) -> walk_result {
|
pre_order_walk(xopen(dir, O_RDONLY), [&](int dfd, dirent *entry) -> walk_result {
|
||||||
int fd = xopenat(dfd, entry->d_name, O_RDONLY);
|
int fd = xopenat(dfd, entry->d_name, O_RDONLY);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return SKIP;
|
return SKIP;
|
||||||
run_finally f([&]{ close(fd); });
|
run_finally f([&]{ close(fd); });
|
||||||
if (fd_path(fd, path, sizeof(path)) < 0)
|
if (fd_path(fd, byte_slice(path, sizeof(path))) < 0)
|
||||||
return SKIP;
|
return SKIP;
|
||||||
raw_file file;
|
raw_file file;
|
||||||
file.path = path + len + 1;
|
file.path = path + len + 1;
|
||||||
|
@ -58,9 +58,16 @@ struct mmap_data : public byte_data {
|
|||||||
mmap_data& operator=(mmap_data &&other) { swap(other); return *this; }
|
mmap_data& operator=(mmap_data &&other) { swap(other); return *this; }
|
||||||
};
|
};
|
||||||
|
|
||||||
ssize_t fd_path(int fd, char *path, size_t size);
|
extern "C" {
|
||||||
int fd_pathat(int dirfd, const char *name, char *path, size_t size);
|
|
||||||
int mkdirs(const char *path, mode_t mode);
|
int mkdirs(const char *path, mode_t mode);
|
||||||
|
ssize_t canonical_path(const char *path, char *buf, size_t bufsiz);
|
||||||
|
ssize_t read_link(const char *pathname, char *buf, size_t bufsiz);
|
||||||
|
|
||||||
|
} // extern "C"
|
||||||
|
|
||||||
|
using rust::fd_path;
|
||||||
|
int fd_pathat(int dirfd, const char *name, char *path, size_t size);
|
||||||
void rm_rf(const char *path);
|
void rm_rf(const char *path);
|
||||||
void mv_path(const char *src, const char *dest);
|
void mv_path(const char *src, const char *dest);
|
||||||
void mv_dir(int src, int dest);
|
void mv_dir(int src, int dest);
|
||||||
|
112
native/src/base/files.rs
Normal file
112
native/src/base/files.rs
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
use std::ffi::CStr;
|
||||||
|
use std::os::unix::io::{AsRawFd, FromRawFd, OwnedFd, RawFd};
|
||||||
|
|
||||||
|
use libc::{c_char, mode_t, EEXIST, ENOENT, O_CLOEXEC, O_PATH};
|
||||||
|
|
||||||
|
use crate::{bfmt_cstr, errno, xopen};
|
||||||
|
|
||||||
|
mod unsafe_impl {
|
||||||
|
use std::ffi::CStr;
|
||||||
|
use std::slice;
|
||||||
|
|
||||||
|
use libc::c_char;
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn read_link(path: *const c_char, buf: *mut u8, bufsz: usize) -> isize {
|
||||||
|
let r = libc::readlink(path, buf.cast(), bufsz - 1);
|
||||||
|
if r >= 0 {
|
||||||
|
*buf.offset(r) = b'\0';
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
unsafe extern "C" fn canonical_path(path: *const c_char, buf: *mut u8, bufsz: usize) -> isize {
|
||||||
|
super::canonical_path(CStr::from_ptr(path), slice::from_raw_parts_mut(buf, bufsz))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn __open_fd_impl(path: &CStr, flags: i32, mode: mode_t) -> Option<OwnedFd> {
|
||||||
|
let fd = xopen(path.as_ptr(), flags, mode);
|
||||||
|
if fd >= 0 {
|
||||||
|
unsafe { Some(OwnedFd::from_raw_fd(fd)) }
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! open_fd {
|
||||||
|
($path:expr, $flags:expr) => {
|
||||||
|
crate::__open_fd_impl($path, $flags, 0)
|
||||||
|
};
|
||||||
|
($path:expr, $flags:expr, $mode:expr) => {
|
||||||
|
crate::__open_fd_impl($path, $flags, $mode)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn readlink(path: &CStr, data: &mut [u8]) -> isize {
|
||||||
|
unsafe { unsafe_impl::read_link(path.as_ptr(), data.as_mut_ptr(), data.len()) }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn fd_path(fd: RawFd, buf: &mut [u8]) -> isize {
|
||||||
|
let mut fd_buf: [u8; 40] = [0; 40];
|
||||||
|
let fd_path = bfmt_cstr!(&mut fd_buf, "/proc/self/fd/{}", fd);
|
||||||
|
readlink(fd_path, buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inspired by https://android.googlesource.com/platform/bionic/+/master/libc/bionic/realpath.cpp
|
||||||
|
pub fn canonical_path(path: &CStr, buf: &mut [u8]) -> isize {
|
||||||
|
if let Some(fd) = open_fd!(path, O_PATH | O_CLOEXEC) {
|
||||||
|
let mut st1: libc::stat;
|
||||||
|
let mut st2: libc::stat;
|
||||||
|
unsafe {
|
||||||
|
st1 = std::mem::zeroed();
|
||||||
|
if libc::fstat(fd.as_raw_fd(), &mut st1) < 0 {
|
||||||
|
*errno() = ENOENT;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let len = fd_path(fd.as_raw_fd(), buf);
|
||||||
|
unsafe {
|
||||||
|
st2 = std::mem::zeroed();
|
||||||
|
if libc::stat(buf.as_ptr().cast(), &mut st2) < 0
|
||||||
|
|| st2.st_dev != st1.st_dev
|
||||||
|
|| st2.st_ino != st1.st_ino
|
||||||
|
{
|
||||||
|
*errno() = ENOENT;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return len;
|
||||||
|
} else {
|
||||||
|
*errno() = ENOENT;
|
||||||
|
-1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
fn strscpy(dst: *mut c_char, src: *const c_char, size: usize) -> usize;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn mkdirs(path: *const c_char, mode: mode_t) -> i32 {
|
||||||
|
unsafe {
|
||||||
|
let mut buf = [0 as u8; 4096];
|
||||||
|
let ptr: *mut c_char = buf.as_mut_ptr().cast();
|
||||||
|
let len = strscpy(ptr, path, buf.len());
|
||||||
|
let mut curr = &mut buf[1..len];
|
||||||
|
while let Some(p) = curr.iter().position(|c| *c == b'/') {
|
||||||
|
curr[p] = b'\0';
|
||||||
|
if libc::mkdir(ptr, mode) < 0 && *errno() != EEXIST {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
curr[p] = b'/';
|
||||||
|
curr = &mut curr[(p + 1)..];
|
||||||
|
}
|
||||||
|
if libc::mkdir(ptr, mode) < 0 && *errno() != EEXIST {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
0
|
||||||
|
}
|
||||||
|
}
|
@ -2,10 +2,12 @@
|
|||||||
|
|
||||||
pub use libc;
|
pub use libc;
|
||||||
|
|
||||||
|
pub use files::*;
|
||||||
pub use logging::*;
|
pub use logging::*;
|
||||||
pub use misc::*;
|
pub use misc::*;
|
||||||
pub use xwrap::*;
|
pub use xwrap::*;
|
||||||
|
|
||||||
|
mod files;
|
||||||
mod logging;
|
mod logging;
|
||||||
mod misc;
|
mod misc;
|
||||||
mod xwrap;
|
mod xwrap;
|
||||||
@ -31,9 +33,7 @@ pub mod ffi {
|
|||||||
#[cxx::bridge(namespace = "rust")]
|
#[cxx::bridge(namespace = "rust")]
|
||||||
pub mod ffi2 {
|
pub mod ffi2 {
|
||||||
extern "Rust" {
|
extern "Rust" {
|
||||||
fn xwrite(fd: i32, data: &[u8]) -> isize;
|
|
||||||
fn xread(fd: i32, data: &mut [u8]) -> isize;
|
|
||||||
fn xxread(fd: i32, data: &mut [u8]) -> isize;
|
|
||||||
fn xpipe2(fds: &mut [i32; 2], flags: i32) -> i32;
|
fn xpipe2(fds: &mut [i32; 2], flags: i32) -> i32;
|
||||||
|
fn fd_path(fd: i32, buf: &mut [u8]) -> isize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ extern "C" int magisk_log_print(int prio, const char *tag, const char *fmt, ...)
|
|||||||
}
|
}
|
||||||
|
|
||||||
char fmt_buf[4096];
|
char fmt_buf[4096];
|
||||||
auto len = strlcpy(fmt_buf, tag, sizeof(fmt_buf) - 1);
|
auto len = strscpy(fmt_buf, tag, sizeof(fmt_buf) - 1);
|
||||||
// Prevent format specifications in the tag
|
// Prevent format specifications in the tag
|
||||||
std::replace(fmt_buf, fmt_buf + len, '%', '_');
|
std::replace(fmt_buf, fmt_buf + len, '%', '_');
|
||||||
len = ssprintf(fmt_buf + len, sizeof(fmt_buf) - len - 1, ": %s", fmt) + len;
|
len = ssprintf(fmt_buf + len, sizeof(fmt_buf) - len - 1, ": %s", fmt) + len;
|
||||||
|
@ -130,7 +130,7 @@ void init_argv0(int argc, char **argv) {
|
|||||||
|
|
||||||
void set_nice_name(const char *name) {
|
void set_nice_name(const char *name) {
|
||||||
memset(argv0, 0, name_len);
|
memset(argv0, 0, name_len);
|
||||||
strlcpy(argv0, name, name_len);
|
strscpy(argv0, name, name_len);
|
||||||
prctl(PR_SET_NAME, name);
|
prctl(PR_SET_NAME, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -224,3 +224,8 @@ int ssprintf(char *dest, size_t size, const char *fmt, ...) {
|
|||||||
va_end(va);
|
va_end(va);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#undef strlcpy
|
||||||
|
size_t strscpy(char *dest, const char *src, size_t size) {
|
||||||
|
return std::min(strlcpy(dest, src, size), size - 1);
|
||||||
|
}
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
#include <string_view>
|
#include <string_view>
|
||||||
#include <bitset>
|
#include <bitset>
|
||||||
|
|
||||||
|
#include <base-rs.hpp>
|
||||||
|
|
||||||
#define DISALLOW_COPY_AND_MOVE(clazz) \
|
#define DISALLOW_COPY_AND_MOVE(clazz) \
|
||||||
clazz(const clazz &) = delete; \
|
clazz(const clazz &) = delete; \
|
||||||
clazz(clazz &&) = delete;
|
clazz(clazz &&) = delete;
|
||||||
@ -118,6 +120,11 @@ struct StringCmp {
|
|||||||
bool operator()(std::string_view a, std::string_view b) const { return a < b; }
|
bool operator()(std::string_view a, std::string_view b) const { return a < b; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
rust::Slice<uint8_t> byte_slice(T *buf, size_t sz) {
|
||||||
|
return rust::Slice(reinterpret_cast<uint8_t *>(buf), sz);
|
||||||
|
}
|
||||||
|
|
||||||
int parse_int(std::string_view s);
|
int parse_int(std::string_view s);
|
||||||
|
|
||||||
using thread_entry = void *(*)(void *);
|
using thread_entry = void *(*)(void *);
|
||||||
@ -160,10 +167,14 @@ std::vector<std::string_view> split_ro(std::string_view, std::string_view delims
|
|||||||
int vssprintf(char *dest, size_t size, const char *fmt, va_list ap);
|
int vssprintf(char *dest, size_t size, const char *fmt, va_list ap);
|
||||||
// Similar to snprintf, but the return value is the written number of bytes
|
// Similar to snprintf, but the return value is the written number of bytes
|
||||||
int ssprintf(char *dest, size_t size, const char *fmt, ...);
|
int ssprintf(char *dest, size_t size, const char *fmt, ...);
|
||||||
|
// This is not actually the strscpy from the Linux kernel.
|
||||||
|
// Silently truncates, and returns the number of bytes written.
|
||||||
|
extern "C" size_t strscpy(char *dest, const char *src, size_t size);
|
||||||
|
|
||||||
// Ban usage of unsafe cstring functions
|
// Ban usage of unsafe cstring functions
|
||||||
#define vsnprintf __use_vssprintf_instead__
|
#define vsnprintf __use_vssprintf_instead__
|
||||||
#define snprintf __use_ssprintf_instead__
|
#define snprintf __use_ssprintf_instead__
|
||||||
|
#define strlcpy __use_strscpy_instead__
|
||||||
|
|
||||||
struct exec_t {
|
struct exec_t {
|
||||||
bool err = false;
|
bool err = false;
|
||||||
|
@ -41,6 +41,21 @@ pub fn fmt_to_buf(buf: &mut [u8], args: Arguments) -> usize {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! bfmt {
|
||||||
|
($buf:expr, $($args:tt)*) => {
|
||||||
|
$crate::fmt_to_buf($buf, format_args!($($args)*));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! bfmt_cstr {
|
||||||
|
($buf:expr, $($args:tt)*) => {{
|
||||||
|
let len = $crate::fmt_to_buf($buf, format_args!($($args)*));
|
||||||
|
unsafe { std::ffi::CStr::from_bytes_with_nul_unchecked(&$buf[..(len + 1)]) }
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
// The cstr! macro is inspired by https://github.com/Nugine/const-str
|
// The cstr! macro is inspired by https://github.com/Nugine/const-str
|
||||||
|
|
||||||
macro_rules! const_assert {
|
macro_rules! const_assert {
|
||||||
@ -88,19 +103,12 @@ macro_rules! cstr {
|
|||||||
($s:literal) => {{
|
($s:literal) => {{
|
||||||
const LEN: usize = $crate::ToCStr($s).eval_len();
|
const LEN: usize = $crate::ToCStr($s).eval_len();
|
||||||
const BUF: [u8; LEN] = $crate::ToCStr($s).eval_bytes();
|
const BUF: [u8; LEN] = $crate::ToCStr($s).eval_bytes();
|
||||||
unsafe { CStr::from_bytes_with_nul_unchecked(&BUF) }
|
unsafe { std::ffi::CStr::from_bytes_with_nul_unchecked(&BUF) }
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
pub fn ptr_to_str<'a, T>(ptr: *const T) -> &'a str {
|
||||||
macro_rules! r_cstr {
|
unsafe { CStr::from_ptr(ptr.cast()) }.to_str().unwrap_or("")
|
||||||
($s:literal) => {
|
|
||||||
cstr!($s).as_ptr()
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
pub unsafe fn ptr_to_str<'a, T>(ptr: *const T) -> &'a str {
|
|
||||||
CStr::from_ptr(ptr.cast()).to_str().unwrap_or("")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn errno() -> &'static mut i32 {
|
pub fn errno() -> &'static mut i32 {
|
||||||
|
@ -1,119 +0,0 @@
|
|||||||
#include <sched.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <pthread.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/mount.h>
|
|
||||||
#include <sys/mman.h>
|
|
||||||
#include <sys/sendfile.h>
|
|
||||||
#include <sys/ptrace.h>
|
|
||||||
#include <sys/inotify.h>
|
|
||||||
|
|
||||||
#include <base.hpp>
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
ssize_t xwrite(int fd, const void *buf, size_t count) {
|
|
||||||
return rust::xwrite(fd, rust::Slice(static_cast<const uint8_t *>(buf), count));
|
|
||||||
}
|
|
||||||
|
|
||||||
ssize_t xread(int fd, void *buf, size_t count) {
|
|
||||||
return rust::xread(fd, rust::Slice(static_cast<uint8_t *>(buf), count));
|
|
||||||
}
|
|
||||||
|
|
||||||
ssize_t xxread(int fd, void *buf, size_t count) {
|
|
||||||
return rust::xxread(fd, rust::Slice(static_cast<uint8_t *>(buf), count));
|
|
||||||
}
|
|
||||||
|
|
||||||
dirent *xreaddir(DIR *dirp) {
|
|
||||||
errno = 0;
|
|
||||||
for (dirent *e;;) {
|
|
||||||
e = readdir(dirp);
|
|
||||||
if (e == nullptr) {
|
|
||||||
if (errno)
|
|
||||||
PLOGE("readdir");
|
|
||||||
return nullptr;
|
|
||||||
} else if (e->d_name == "."sv || e->d_name == ".."sv) {
|
|
||||||
// Filter . and .. for users
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ssize_t xreadlink(const char *pathname, char *buf, size_t bufsiz) {
|
|
||||||
ssize_t ret = readlink(pathname, buf, bufsiz);
|
|
||||||
if (ret < 0) {
|
|
||||||
PLOGE("readlink %s", pathname);
|
|
||||||
} else {
|
|
||||||
buf[ret] = '\0';
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
ssize_t xreadlinkat(int dirfd, const char *pathname, char *buf, size_t bufsiz) {
|
|
||||||
// readlinkat() may fail on x86 platform, returning random value
|
|
||||||
// instead of number of bytes placed in buf (length of link)
|
|
||||||
#if defined(__i386__) || defined(__x86_64__)
|
|
||||||
memset(buf, 0, bufsiz);
|
|
||||||
ssize_t ret = readlinkat(dirfd, pathname, buf, bufsiz);
|
|
||||||
if (ret < 0) {
|
|
||||||
PLOGE("readlinkat %s", pathname);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
#else
|
|
||||||
ssize_t ret = readlinkat(dirfd, pathname, buf, bufsiz);
|
|
||||||
if (ret < 0) {
|
|
||||||
PLOGE("readlinkat %s", pathname);
|
|
||||||
} else {
|
|
||||||
buf[ret] = '\0';
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
int xmkdirs(const char *pathname, mode_t mode) {
|
|
||||||
int ret = mkdirs(pathname, mode);
|
|
||||||
if (ret < 0) {
|
|
||||||
PLOGE("mkdirs %s", pathname);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *xmmap(void *addr, size_t length, int prot, int flags,
|
|
||||||
int fd, off_t offset) {
|
|
||||||
void *ret = mmap(addr, length, prot, flags, fd, offset);
|
|
||||||
if (ret == MAP_FAILED) {
|
|
||||||
PLOGE("mmap");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
ssize_t xsendfile(int out_fd, int in_fd, off_t *offset, size_t count) {
|
|
||||||
ssize_t ret = sendfile(out_fd, in_fd, offset, count);
|
|
||||||
if (ret < 0) {
|
|
||||||
PLOGE("sendfile");
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int xpoll(struct pollfd *fds, nfds_t nfds, int timeout) {
|
|
||||||
int ret = poll(fds, nfds, timeout);
|
|
||||||
if (ret < 0) {
|
|
||||||
PLOGE("poll");
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *xrealpath(const char *path, char *resolved_path) {
|
|
||||||
char buf[PATH_MAX];
|
|
||||||
char *ret = realpath(path, buf);
|
|
||||||
if (ret == nullptr) {
|
|
||||||
PLOGE("xrealpath");
|
|
||||||
} else {
|
|
||||||
strcpy(resolved_path, buf);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
@ -57,8 +57,8 @@ int xmkdirat(int dirfd, const char *pathname, mode_t mode);
|
|||||||
void *xmmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
|
void *xmmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
|
||||||
ssize_t xsendfile(int out_fd, int in_fd, off_t *offset, size_t count);
|
ssize_t xsendfile(int out_fd, int in_fd, off_t *offset, size_t count);
|
||||||
pid_t xfork();
|
pid_t xfork();
|
||||||
int xpoll(struct pollfd *fds, nfds_t nfds, int timeout);
|
int xpoll(pollfd *fds, nfds_t nfds, int timeout);
|
||||||
char *xrealpath(const char *path, char *resolved_path);
|
ssize_t xcanonical_path(const char *path, char *buf, size_t bufsiz);
|
||||||
int xmknod(const char *pathname, mode_t mode, dev_t dev);
|
int xmknod(const char *pathname, mode_t mode, dev_t dev);
|
||||||
|
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
|
@ -1,11 +1,100 @@
|
|||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
use std::os::unix::io::RawFd;
|
use std::os::unix::io::RawFd;
|
||||||
|
use std::ptr;
|
||||||
|
|
||||||
use libc::{
|
use libc::{
|
||||||
c_char, c_uint, c_ulong, c_void, dev_t, mode_t, sockaddr, socklen_t, ssize_t, SYS_dup3,
|
c_char, c_uint, c_ulong, c_void, dev_t, mode_t, nfds_t, off_t, pollfd, sockaddr, socklen_t,
|
||||||
|
ssize_t, SYS_dup3,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{errno, error, perror, ptr_to_str};
|
use crate::{canonical_path, cstr, errno, error, mkdirs, perror, ptr_to_str, readlink};
|
||||||
|
|
||||||
|
mod unsafe_impl {
|
||||||
|
use std::ffi::CStr;
|
||||||
|
use std::os::unix::io::RawFd;
|
||||||
|
use std::slice;
|
||||||
|
|
||||||
|
use cfg_if::cfg_if;
|
||||||
|
use libc::{c_char, nfds_t, off_t, pollfd};
|
||||||
|
|
||||||
|
use crate::{perror, ptr_to_str};
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
unsafe extern "C" fn xwrite(fd: RawFd, buf: *const u8, bufsz: usize) -> isize {
|
||||||
|
super::xwrite(fd, slice::from_raw_parts(buf, bufsz))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
unsafe extern "C" fn xread(fd: RawFd, buf: *mut u8, bufsz: usize) -> isize {
|
||||||
|
super::xread(fd, slice::from_raw_parts_mut(buf, bufsz))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
unsafe extern "C" fn xxread(fd: RawFd, buf: *mut u8, bufsz: usize) -> isize {
|
||||||
|
super::xxread(fd, slice::from_raw_parts_mut(buf, bufsz))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
unsafe extern "C" fn xcanonical_path(path: *const c_char, buf: *mut u8, bufsz: usize) -> isize {
|
||||||
|
super::xcanonical_path(CStr::from_ptr(path), slice::from_raw_parts_mut(buf, bufsz))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
unsafe extern "C" fn xreadlink(path: *const c_char, buf: *mut u8, bufsz: usize) -> isize {
|
||||||
|
super::xreadlink(CStr::from_ptr(path), slice::from_raw_parts_mut(buf, bufsz))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn xreadlinkat(
|
||||||
|
dirfd: RawFd,
|
||||||
|
path: *const c_char,
|
||||||
|
buf: *mut u8,
|
||||||
|
bufsz: usize,
|
||||||
|
) -> isize {
|
||||||
|
// readlinkat() may fail on x86 platform, returning random value
|
||||||
|
// instead of number of bytes placed in buf (length of link)
|
||||||
|
cfg_if! {
|
||||||
|
if #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] {
|
||||||
|
libc::memset(buf.cast(), 0, bufsz);
|
||||||
|
let r = libc::readlinkat(dirfd, path, buf.cast(), bufsz - 1);
|
||||||
|
if r < 0 {
|
||||||
|
perror!("readlinkat {}", ptr_to_str(path))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let r = libc::readlinkat(dirfd, path, buf.cast(), bufsz - 1);
|
||||||
|
if r < 0 {
|
||||||
|
perror!("readlinkat {}", ptr_to_str(path))
|
||||||
|
} else {
|
||||||
|
*buf.offset(r) = b'\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn xpoll(fds: *mut pollfd, nfds: nfds_t, timeout: i32) -> i32 {
|
||||||
|
let r = libc::poll(fds, nfds, timeout);
|
||||||
|
if r < 0 {
|
||||||
|
perror!("poll");
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn xsendfile(
|
||||||
|
out_fd: RawFd,
|
||||||
|
in_fd: RawFd,
|
||||||
|
offset: *mut off_t,
|
||||||
|
count: usize,
|
||||||
|
) -> isize {
|
||||||
|
let r = libc::sendfile(out_fd, in_fd, offset, count);
|
||||||
|
if r < 0 {
|
||||||
|
perror!("sendfile");
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn xfopen(path: *const c_char, mode: *const c_char) -> *mut libc::FILE {
|
pub extern "C" fn xfopen(path: *const c_char, mode: *const c_char) -> *mut libc::FILE {
|
||||||
@ -194,6 +283,29 @@ pub extern "C" fn xfdopendir(fd: RawFd) -> *mut libc::DIR {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn xreaddir(dirp: *mut libc::DIR) -> *mut libc::dirent {
|
||||||
|
#[allow(unused_unsafe)]
|
||||||
|
unsafe {
|
||||||
|
*errno() = 0;
|
||||||
|
loop {
|
||||||
|
let e = libc::readdir(dirp);
|
||||||
|
if e.is_null() {
|
||||||
|
if *errno() != 0 {
|
||||||
|
perror!("readdir")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Filter out . and ..
|
||||||
|
let s = CStr::from_ptr((*e).d_name.as_ptr());
|
||||||
|
if s == cstr!(".") || s == cstr!("..") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn xsetsid() -> i32 {
|
pub extern "C" fn xsetsid() -> i32 {
|
||||||
unsafe {
|
unsafe {
|
||||||
@ -386,21 +498,15 @@ pub extern "C" fn xdup3(oldfd: RawFd, newfd: RawFd, flags: i32) -> RawFd {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn xreadlink(path: &CStr, data: &mut [u8]) -> isize {
|
pub fn xreadlink(path: &CStr, data: &mut [u8]) -> isize {
|
||||||
mod e {
|
let r = readlink(path, data);
|
||||||
extern "C" {
|
if r < 0 {
|
||||||
pub fn xreadlink(path: *const u8, buf: *mut u8, bufsz: usize) -> isize;
|
perror!("readlink {}", path.to_str().unwrap_or(""))
|
||||||
}
|
}
|
||||||
}
|
return r;
|
||||||
unsafe { e::xreadlink(path.as_ptr().cast(), data.as_mut_ptr(), data.len()) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn xreadlinkat(dirfd: RawFd, path: &CStr, data: &mut [u8]) -> isize {
|
pub fn xreadlinkat(dirfd: RawFd, path: &CStr, data: &mut [u8]) -> isize {
|
||||||
mod e {
|
unsafe { unsafe_impl::xreadlinkat(dirfd, path.as_ptr(), data.as_mut_ptr(), data.len()) }
|
||||||
extern "C" {
|
|
||||||
pub fn xreadlinkat(dirfd: i32, path: *const u8, buf: *mut u8, bufsz: usize) -> isize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
unsafe { e::xreadlinkat(dirfd, path.as_ptr().cast(), data.as_mut_ptr(), data.len()) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
@ -507,6 +613,15 @@ pub extern "C" fn xmkdir(path: *const c_char, mode: mode_t) -> i32 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn xmkdirs(path: *const c_char, mode: mode_t) -> i32 {
|
||||||
|
let r = mkdirs(path, mode);
|
||||||
|
if r < 0 {
|
||||||
|
perror!("mkdirs {}", ptr_to_str(path));
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn xmkdirat(dirfd: RawFd, path: *const c_char, mode: mode_t) -> i32 {
|
pub extern "C" fn xmkdirat(dirfd: RawFd, path: *const c_char, mode: mode_t) -> i32 {
|
||||||
unsafe {
|
unsafe {
|
||||||
@ -518,6 +633,32 @@ pub extern "C" fn xmkdirat(dirfd: RawFd, path: *const c_char, mode: mode_t) -> i
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn xsendfile(out_fd: RawFd, in_fd: RawFd, offset: Option<&mut off_t>, count: usize) -> isize {
|
||||||
|
unsafe {
|
||||||
|
let p = offset.map_or(ptr::null_mut(), |it| it);
|
||||||
|
unsafe_impl::xsendfile(out_fd, in_fd, p, count)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn xmmap(
|
||||||
|
addr: *mut c_void,
|
||||||
|
len: usize,
|
||||||
|
prot: i32,
|
||||||
|
flags: i32,
|
||||||
|
fd: RawFd,
|
||||||
|
offset: off_t,
|
||||||
|
) -> *mut c_void {
|
||||||
|
unsafe {
|
||||||
|
let r = libc::mmap(addr, len, prot, flags, fd, offset);
|
||||||
|
if r == libc::MAP_FAILED {
|
||||||
|
perror!("mmap");
|
||||||
|
return ptr::null_mut();
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn xfork() -> i32 {
|
pub extern "C" fn xfork() -> i32 {
|
||||||
unsafe {
|
unsafe {
|
||||||
@ -529,6 +670,18 @@ pub extern "C" fn xfork() -> i32 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn xpoll(fds: &mut [pollfd], timeout: i32) -> i32 {
|
||||||
|
unsafe { unsafe_impl::xpoll(fds.as_mut_ptr(), fds.len() as nfds_t, timeout) }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn xcanonical_path(path: &CStr, buf: &mut [u8]) -> isize {
|
||||||
|
let r = canonical_path(path, buf);
|
||||||
|
if r < 0 {
|
||||||
|
perror!("canonical_path {}", path.to_str().unwrap_or(""))
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn xmknod(pathname: *const c_char, mode: mode_t, dev: dev_t) -> i32 {
|
pub extern "C" fn xmknod(pathname: *const c_char, mode: mode_t, dev: dev_t) -> i32 {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -124,7 +124,7 @@ extern "C" void klog_write(const char *msg, int len) {
|
|||||||
|
|
||||||
static int klog_with_rs(LogLevel level, const char *fmt, va_list ap) {
|
static int klog_with_rs(LogLevel level, const char *fmt, va_list ap) {
|
||||||
char buf[4096];
|
char buf[4096];
|
||||||
strlcpy(buf, "magiskinit: ", sizeof(buf));
|
strscpy(buf, "magiskinit: ", sizeof(buf));
|
||||||
int len = vssprintf(buf + 12, sizeof(buf) - 12, fmt, ap) + 12;
|
int len = vssprintf(buf + 12, sizeof(buf) - 12, fmt, ap) + 12;
|
||||||
log_with_rs(level, rust::Str(buf, len));
|
log_with_rs(level, rust::Str(buf, len));
|
||||||
return len;
|
return len;
|
||||||
@ -174,10 +174,10 @@ void BootConfig::set(const kv_pairs &kv) {
|
|||||||
LOGW("Skip invalid androidboot.slot_suffix=[normal]\n");
|
LOGW("Skip invalid androidboot.slot_suffix=[normal]\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
strlcpy(slot, value.data(), sizeof(slot));
|
strscpy(slot, value.data(), sizeof(slot));
|
||||||
} else if (key == "androidboot.slot") {
|
} else if (key == "androidboot.slot") {
|
||||||
slot[0] = '_';
|
slot[0] = '_';
|
||||||
strlcpy(slot + 1, value.data(), sizeof(slot) - 1);
|
strscpy(slot + 1, value.data(), sizeof(slot) - 1);
|
||||||
} else if (key == "skip_initramfs") {
|
} else if (key == "skip_initramfs") {
|
||||||
skip_initramfs = true;
|
skip_initramfs = true;
|
||||||
} else if (key == "androidboot.force_normal_boot") {
|
} else if (key == "androidboot.force_normal_boot") {
|
||||||
@ -185,13 +185,13 @@ void BootConfig::set(const kv_pairs &kv) {
|
|||||||
} else if (key == "rootwait") {
|
} else if (key == "rootwait") {
|
||||||
rootwait = true;
|
rootwait = true;
|
||||||
} else if (key == "androidboot.android_dt_dir") {
|
} else if (key == "androidboot.android_dt_dir") {
|
||||||
strlcpy(dt_dir, value.data(), sizeof(dt_dir));
|
strscpy(dt_dir, value.data(), sizeof(dt_dir));
|
||||||
} else if (key == "androidboot.hardware") {
|
} else if (key == "androidboot.hardware") {
|
||||||
strlcpy(hardware, value.data(), sizeof(hardware));
|
strscpy(hardware, value.data(), sizeof(hardware));
|
||||||
} else if (key == "androidboot.hardware.platform") {
|
} else if (key == "androidboot.hardware.platform") {
|
||||||
strlcpy(hardware_plat, value.data(), sizeof(hardware_plat));
|
strscpy(hardware_plat, value.data(), sizeof(hardware_plat));
|
||||||
} else if (key == "androidboot.fstab_suffix") {
|
} else if (key == "androidboot.fstab_suffix") {
|
||||||
strlcpy(fstab_suffix, value.data(), sizeof(fstab_suffix));
|
strscpy(fstab_suffix, value.data(), sizeof(fstab_suffix));
|
||||||
} else if (key == "qemu") {
|
} else if (key == "qemu") {
|
||||||
emulator = true;
|
emulator = true;
|
||||||
}
|
}
|
||||||
@ -216,7 +216,7 @@ if (access(file_name, R_OK) == 0) { \
|
|||||||
string data = full_read(file_name); \
|
string data = full_read(file_name); \
|
||||||
if (!data.empty()) { \
|
if (!data.empty()) { \
|
||||||
data.pop_back(); \
|
data.pop_back(); \
|
||||||
strlcpy(config->key, data.data(), sizeof(config->key)); \
|
strscpy(config->key, data.data(), sizeof(config->key)); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -245,7 +245,7 @@ void load_kernel_info(BootConfig *config) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (config->dt_dir[0] == '\0')
|
if (config->dt_dir[0] == '\0')
|
||||||
strlcpy(config->dt_dir, DEFAULT_DT_DIR, sizeof(config->dt_dir));
|
strscpy(config->dt_dir, DEFAULT_DT_DIR, sizeof(config->dt_dir));
|
||||||
|
|
||||||
char file_name[128];
|
char file_name[128];
|
||||||
read_dt("fstab_suffix", fstab_suffix)
|
read_dt("fstab_suffix", fstab_suffix)
|
||||||
|
@ -118,8 +118,8 @@ static void switch_root(const string &path) {
|
|||||||
|
|
||||||
void MagiskInit::mount_rules_dir() {
|
void MagiskInit::mount_rules_dir() {
|
||||||
char path[128];
|
char path[128];
|
||||||
xrealpath(BLOCKDIR, blk_info.block_dev);
|
xcanonical_path(BLOCKDIR, blk_info.block_dev, sizeof(blk_info.block_dev));
|
||||||
xrealpath(MIRRDIR, path);
|
xcanonical_path(MIRRDIR, path, sizeof(path));
|
||||||
char *b = blk_info.block_dev + strlen(blk_info.block_dev);
|
char *b = blk_info.block_dev + strlen(blk_info.block_dev);
|
||||||
char *p = path + strlen(path);
|
char *p = path + strlen(path);
|
||||||
|
|
||||||
@ -206,7 +206,7 @@ success:
|
|||||||
// Create symlink with relative path
|
// Create symlink with relative path
|
||||||
char s[128];
|
char s[128];
|
||||||
s[0] = '.';
|
s[0] = '.';
|
||||||
strlcpy(s + 1, rel + sizeof(MIRRDIR) - 1, sizeof(s) - 1);
|
strscpy(s + 1, rel + sizeof(MIRRDIR) - 1, sizeof(s) - 1);
|
||||||
xsymlink(s, path);
|
xsymlink(s, path);
|
||||||
} else {
|
} else {
|
||||||
xsymlink(custom_rules_dir.data(), path);
|
xsymlink(custom_rules_dir.data(), path);
|
||||||
|
@ -123,7 +123,7 @@ static void exec_cmd(const char *action, vector<Extra> &data,
|
|||||||
ssprintf(exe, sizeof(exe), "/proc/self/fd/%d", app_process_32);
|
ssprintf(exe, sizeof(exe), "/proc/self/fd/%d", app_process_32);
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
strlcpy(exe, "/system/bin/app_process", sizeof(exe));
|
strscpy(exe, "/system/bin/app_process", sizeof(exe));
|
||||||
}
|
}
|
||||||
|
|
||||||
// First try content provider call method
|
// First try content provider call method
|
||||||
@ -158,7 +158,7 @@ static void exec_cmd(const char *action, vector<Extra> &data,
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Then try start activity without package name
|
// Then try start activity without package name
|
||||||
strlcpy(target, info->mgr_pkg.data(), sizeof(target));
|
strscpy(target, info->mgr_pkg.data(), sizeof(target));
|
||||||
exec_command_sync(exec);
|
exec_command_sync(exec);
|
||||||
if (check_no_error(exec.fd))
|
if (check_no_error(exec.fd))
|
||||||
return;
|
return;
|
||||||
|
@ -142,7 +142,7 @@ void prune_su_access() {
|
|||||||
vector<bool> app_no_list = get_app_no_list();
|
vector<bool> app_no_list = get_app_no_list();
|
||||||
vector<int> rm_uids;
|
vector<int> rm_uids;
|
||||||
char query[256], *err;
|
char query[256], *err;
|
||||||
strlcpy(query, "SELECT uid FROM policies", sizeof(query));
|
strscpy(query, "SELECT uid FROM policies", sizeof(query));
|
||||||
err = db_exec(query, [&](db_row &row) -> bool {
|
err = db_exec(query, [&](db_row &row) -> bool {
|
||||||
int uid = parse_int(row["uid"]);
|
int uid = parse_int(row["uid"]);
|
||||||
int app_id = to_app_id(uid);
|
int app_id = to_app_id(uid);
|
||||||
@ -412,7 +412,7 @@ void su_daemon_handler(int client, const sock_cred *cred) {
|
|||||||
char path[32];
|
char path[32];
|
||||||
ssprintf(path, sizeof(path), "/proc/%d/cwd", ctx.pid);
|
ssprintf(path, sizeof(path), "/proc/%d/cwd", ctx.pid);
|
||||||
char cwd[PATH_MAX];
|
char cwd[PATH_MAX];
|
||||||
if (realpath(path, cwd))
|
if (canonical_path(path, cwd, sizeof(cwd)))
|
||||||
chdir(cwd);
|
chdir(cwd);
|
||||||
ssprintf(path, sizeof(path), "/proc/%d/environ", ctx.pid);
|
ssprintf(path, sizeof(path), "/proc/%d/environ", ctx.pid);
|
||||||
auto env = full_read(path);
|
auto env = full_read(path);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user