mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-08-27 09:50:34 +00:00
Cleanup libbase
This commit is contained in:
@@ -14,16 +14,9 @@ use crate::files::map_file_at;
|
|||||||
pub(crate) use crate::xwrap::*;
|
pub(crate) use crate::xwrap::*;
|
||||||
use crate::{
|
use crate::{
|
||||||
BufReadExt, CxxResultExt, Directory, OsResultStatic, Utf8CStr, clone_attr, cstr, fclone_attr,
|
BufReadExt, CxxResultExt, Directory, OsResultStatic, Utf8CStr, clone_attr, cstr, fclone_attr,
|
||||||
fd_path, map_fd, map_file, slice_from_ptr,
|
map_fd, map_file, slice_from_ptr,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub(crate) fn fd_path_for_cxx(fd: RawFd, buf: &mut [u8]) -> isize {
|
|
||||||
let mut buf = cstr::buf::wrap(buf);
|
|
||||||
fd_path(fd, &mut buf)
|
|
||||||
.log_cxx()
|
|
||||||
.map_or(-1_isize, |_| buf.len() as isize)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
unsafe extern "C" fn canonical_path(path: *const c_char, buf: *mut u8, bufsz: usize) -> isize {
|
unsafe extern "C" fn canonical_path(path: *const c_char, buf: *mut u8, bufsz: usize) -> isize {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@@ -8,28 +8,20 @@
|
|||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
void full_read(int fd, string &str) {
|
string full_read(int fd) {
|
||||||
|
string str;
|
||||||
char buf[4096];
|
char buf[4096];
|
||||||
for (ssize_t len; (len = xread(fd, buf, sizeof(buf))) > 0;)
|
for (ssize_t len; (len = xread(fd, buf, sizeof(buf))) > 0;)
|
||||||
str.insert(str.end(), buf, buf + len);
|
str.insert(str.end(), buf, buf + len);
|
||||||
}
|
|
||||||
|
|
||||||
void full_read(const char *filename, string &str) {
|
|
||||||
if (int fd = xopen(filename, O_RDONLY | O_CLOEXEC); fd >= 0) {
|
|
||||||
full_read(fd, str);
|
|
||||||
close(fd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
string full_read(int fd) {
|
|
||||||
string str;
|
|
||||||
full_read(fd, str);
|
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
string full_read(const char *filename) {
|
string full_read(const char *filename) {
|
||||||
string str;
|
string str;
|
||||||
full_read(filename, str);
|
if (int fd = xopen(filename, O_RDONLY | O_CLOEXEC); fd >= 0) {
|
||||||
|
str = full_read(fd);
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,24 +1,12 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <linux/fs.h>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include <linux/fs.h>
|
#include "base-rs.hpp"
|
||||||
#include "misc.hpp"
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
static inline T align_to(T v, int a) {
|
|
||||||
static_assert(std::is_integral<T>::value);
|
|
||||||
return (v + a - 1) / a * a;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
static inline T align_padding(T v, int a) {
|
|
||||||
return align_to(v, a) - v;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct mmap_data : public byte_data {
|
struct mmap_data : public byte_data {
|
||||||
static_assert((sizeof(void *) == 8 && BLKGETSIZE64 == 0x80081272) ||
|
static_assert((sizeof(void *) == 8 && BLKGETSIZE64 == 0x80081272) ||
|
||||||
@@ -45,12 +33,6 @@ bool fclone_attr(int src, int dest);
|
|||||||
|
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
|
|
||||||
static inline ssize_t realpath(
|
|
||||||
const char * __restrict__ path, char * __restrict__ buf, size_t bufsiz) {
|
|
||||||
return canonical_path(path, buf, bufsiz);
|
|
||||||
}
|
|
||||||
void full_read(int fd, std::string &str);
|
|
||||||
void full_read(const char *filename, std::string &str);
|
|
||||||
std::string full_read(int fd);
|
std::string full_read(int fd);
|
||||||
std::string full_read(const char *filename);
|
std::string full_read(const char *filename);
|
||||||
void write_zero(int fd, size_t size);
|
void write_zero(int fd, size_t size);
|
||||||
|
@@ -1,11 +1,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "../xwrap.hpp"
|
#include "../xwrap.hpp"
|
||||||
#include "../files.hpp"
|
|
||||||
#include "../misc.hpp"
|
#include "../misc.hpp"
|
||||||
#include "../logging.hpp"
|
|
||||||
#include "../base-rs.hpp"
|
#include "../base-rs.hpp"
|
||||||
|
#include "../files.hpp"
|
||||||
|
#include "../logging.hpp"
|
||||||
|
|
||||||
using rust::xpipe2;
|
using rust::xpipe2;
|
||||||
using rust::fd_path;
|
|
||||||
using kv_pairs = std::vector<std::pair<std::string, std::string>>;
|
using kv_pairs = std::vector<std::pair<std::string, std::string>>;
|
||||||
|
@@ -69,8 +69,6 @@ pub mod ffi {
|
|||||||
#[namespace = "rust"]
|
#[namespace = "rust"]
|
||||||
extern "Rust" {
|
extern "Rust" {
|
||||||
fn xpipe2(fds: &mut [i32; 2], flags: i32) -> i32;
|
fn xpipe2(fds: &mut [i32; 2], flags: i32) -> i32;
|
||||||
#[cxx_name = "fd_path"]
|
|
||||||
fn fd_path_for_cxx(fd: i32, buf: &mut [u8]) -> isize;
|
|
||||||
#[cxx_name = "map_file"]
|
#[cxx_name = "map_file"]
|
||||||
fn map_file_for_cxx(path: Utf8CStrRef, rw: bool) -> &'static mut [u8];
|
fn map_file_for_cxx(path: Utf8CStrRef, rw: bool) -> &'static mut [u8];
|
||||||
#[cxx_name = "map_file_at"]
|
#[cxx_name = "map_file_at"]
|
||||||
|
@@ -15,14 +15,8 @@ bool byte_view::contains(byte_view pattern) const {
|
|||||||
return _buf != nullptr && memmem(_buf, _sz, pattern._buf, pattern._sz) != nullptr;
|
return _buf != nullptr && memmem(_buf, _sz, pattern._buf, pattern._sz) != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool byte_view::equals(byte_view o) const {
|
bool byte_view::operator==(byte_view rhs) const {
|
||||||
return _sz == o._sz && memcmp(_buf, o._buf, _sz) == 0;
|
return _sz == rhs._sz && memcmp(_buf, rhs._buf, _sz) == 0;
|
||||||
}
|
|
||||||
|
|
||||||
heap_data byte_view::clone() const {
|
|
||||||
heap_data copy(_sz);
|
|
||||||
memcpy(copy._buf, _buf, _sz);
|
|
||||||
return copy;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void byte_data::swap(byte_data &o) {
|
void byte_data::swap(byte_data &o) {
|
||||||
@@ -30,28 +24,25 @@ void byte_data::swap(byte_data &o) {
|
|||||||
std::swap(_sz, o._sz);
|
std::swap(_sz, o._sz);
|
||||||
}
|
}
|
||||||
|
|
||||||
rust::Vec<size_t> byte_data::patch(byte_view from, byte_view to) {
|
rust::Vec<size_t> byte_data::patch(byte_view from, byte_view to) const {
|
||||||
rust::Vec<size_t> v;
|
rust::Vec<size_t> v;
|
||||||
if (_buf == nullptr)
|
if (_buf == nullptr)
|
||||||
return v;
|
return v;
|
||||||
auto p = _buf;
|
auto p = _buf;
|
||||||
auto eof = _buf + _sz;
|
auto eof = _buf + _sz;
|
||||||
while (p < eof) {
|
while (p < eof) {
|
||||||
p = static_cast<uint8_t *>(memmem(p, eof - p, from.buf(), from.sz()));
|
p = static_cast<uint8_t *>(memmem(p, eof - p, from.data(), from.size()));
|
||||||
if (p == nullptr)
|
if (p == nullptr)
|
||||||
return v;
|
return v;
|
||||||
memset(p, 0, from.sz());
|
memset(p, 0, from.size());
|
||||||
memcpy(p, to.buf(), to.sz());
|
memcpy(p, to.data(), to.size());
|
||||||
v.push_back(p - _buf);
|
v.push_back(p - _buf);
|
||||||
p += from.sz();
|
p += from.size();
|
||||||
}
|
}
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
rust::Vec<size_t> mut_u8_patch(
|
rust::Vec<size_t> mut_u8_patch(MutByteSlice buf, ByteSlice from, ByteSlice to) {
|
||||||
rust::Slice<uint8_t> buf,
|
|
||||||
rust::Slice<const uint8_t> from,
|
|
||||||
rust::Slice<const uint8_t> to) {
|
|
||||||
byte_data data(buf);
|
byte_data data(buf);
|
||||||
return data.patch(from, to);
|
return data.patch(from, to);
|
||||||
}
|
}
|
||||||
|
@@ -5,7 +5,6 @@
|
|||||||
#include <functional>
|
#include <functional>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
#include <bitset>
|
#include <bitset>
|
||||||
#include <random>
|
|
||||||
#include <cxx.h>
|
#include <cxx.h>
|
||||||
|
|
||||||
#include "xwrap.hpp"
|
#include "xwrap.hpp"
|
||||||
@@ -46,30 +45,11 @@ private:
|
|||||||
Func fn;
|
Func fn;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template<class T>
|
||||||
class reversed_container {
|
static void default_new(T *&p) { p = new T(); }
|
||||||
public:
|
|
||||||
reversed_container(T &base) : base(base) {}
|
|
||||||
decltype(std::declval<T>().rbegin()) begin() { return base.rbegin(); }
|
|
||||||
decltype(std::declval<T>().crbegin()) begin() const { return base.crbegin(); }
|
|
||||||
decltype(std::declval<T>().crbegin()) cbegin() const { return base.crbegin(); }
|
|
||||||
decltype(std::declval<T>().rend()) end() { return base.rend(); }
|
|
||||||
decltype(std::declval<T>().crend()) end() const { return base.crend(); }
|
|
||||||
decltype(std::declval<T>().crend()) cend() const { return base.crend(); }
|
|
||||||
private:
|
|
||||||
T &base;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
reversed_container<T> reversed(T &base) {
|
|
||||||
return reversed_container<T>(base);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
static inline void default_new(T *&p) { p = new T(); }
|
static void default_new(std::unique_ptr<T> &p) { p.reset(new T()); }
|
||||||
|
|
||||||
template<class T>
|
|
||||||
static inline void default_new(std::unique_ptr<T> &p) { p.reset(new T()); }
|
|
||||||
|
|
||||||
struct StringCmp {
|
struct StringCmp {
|
||||||
using is_transparent = void;
|
using is_transparent = void;
|
||||||
@@ -78,49 +58,32 @@ struct StringCmp {
|
|||||||
|
|
||||||
struct heap_data;
|
struct heap_data;
|
||||||
|
|
||||||
|
using ByteSlice = rust::Slice<const uint8_t>;
|
||||||
|
using MutByteSlice = rust::Slice<uint8_t>;
|
||||||
|
|
||||||
// Interchangeable as `&[u8]` in Rust
|
// Interchangeable as `&[u8]` in Rust
|
||||||
struct byte_view {
|
struct byte_view {
|
||||||
byte_view() : _buf(nullptr), _sz(0) {}
|
byte_view() : _buf(nullptr), _sz(0) {}
|
||||||
byte_view(const void *buf, size_t sz) : _buf((uint8_t *) buf), _sz(sz) {}
|
byte_view(const void *buf, size_t sz) : _buf((uint8_t *) buf), _sz(sz) {}
|
||||||
|
|
||||||
// byte_view, or any of its subclass, can be copied as byte_view
|
// byte_view, or any of its subclasses, can be copied as byte_view
|
||||||
byte_view(const byte_view &o) : _buf(o._buf), _sz(o._sz) {}
|
byte_view(const byte_view &o) : _buf(o._buf), _sz(o._sz) {}
|
||||||
|
|
||||||
// Bridging to Rust slice
|
// Transparent conversion to Rust slice
|
||||||
byte_view(rust::Slice<const uint8_t> o) : byte_view(o.data(), o.size()) {}
|
byte_view(const ByteSlice o) : byte_view(o.data(), o.size()) {}
|
||||||
operator rust::Slice<const uint8_t>() const { return rust::Slice<const uint8_t>(_buf, _sz); }
|
operator ByteSlice() const { return {_buf, _sz}; }
|
||||||
|
|
||||||
// String as bytes
|
// String as bytes, including null terminator
|
||||||
byte_view(const char *s, bool with_nul = true)
|
byte_view(const char *s) : byte_view(s, strlen(s) + 1) {}
|
||||||
: byte_view(std::string_view(s), with_nul, false) {}
|
|
||||||
byte_view(const std::string &s, bool with_nul = true)
|
|
||||||
: byte_view(std::string_view(s), with_nul, false) {}
|
|
||||||
byte_view(std::string_view s, bool with_nul = true)
|
|
||||||
: byte_view(s, with_nul, true /* string_view is not guaranteed to null terminate */ ) {}
|
|
||||||
|
|
||||||
// Vector as bytes
|
|
||||||
byte_view(const std::vector<uint8_t> &v) : byte_view(v.data(), v.size()) {}
|
|
||||||
|
|
||||||
const uint8_t *buf() const { return _buf; }
|
|
||||||
size_t sz() const { return _sz; }
|
|
||||||
|
|
||||||
|
const uint8_t *data() const { return _buf; }
|
||||||
|
size_t size() const { return _sz; }
|
||||||
bool contains(byte_view pattern) const;
|
bool contains(byte_view pattern) const;
|
||||||
bool equals(byte_view o) const;
|
bool operator==(byte_view rhs) const;
|
||||||
heap_data clone() const;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
uint8_t *_buf;
|
uint8_t *_buf;
|
||||||
size_t _sz;
|
size_t _sz;
|
||||||
|
|
||||||
private:
|
|
||||||
byte_view(std::string_view s, bool with_nul, bool check_nul)
|
|
||||||
: byte_view(static_cast<const void *>(s.data()), s.length()) {
|
|
||||||
if (with_nul) {
|
|
||||||
if (check_nul && s[s.length()] != '\0')
|
|
||||||
return;
|
|
||||||
++_sz;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Interchangeable as `&mut [u8]` in Rust
|
// Interchangeable as `&mut [u8]` in Rust
|
||||||
@@ -128,23 +91,18 @@ struct byte_data : public byte_view {
|
|||||||
byte_data() = default;
|
byte_data() = default;
|
||||||
byte_data(void *buf, size_t sz) : byte_view(buf, sz) {}
|
byte_data(void *buf, size_t sz) : byte_view(buf, sz) {}
|
||||||
|
|
||||||
// byte_data, or any of its subclass, can be copied as byte_data
|
// byte_data, or any of its subclasses, can be copied as byte_data
|
||||||
byte_data(const byte_data &o) : byte_data(o._buf, o._sz) {}
|
byte_data(const byte_data &o) : byte_data(o._buf, o._sz) {}
|
||||||
|
|
||||||
// Transparent conversion from common C++ types to mutable byte references
|
// Transparent conversion to Rust slice
|
||||||
byte_data(std::string &s, bool with_nul = true)
|
byte_data(const MutByteSlice o) : byte_data(o.data(), o.size()) {}
|
||||||
: byte_data(s.data(), with_nul ? s.length() + 1 : s.length()) {}
|
operator MutByteSlice() const { return {_buf, _sz}; }
|
||||||
byte_data(std::vector<uint8_t> &v) : byte_data(v.data(), v.size()) {}
|
|
||||||
|
|
||||||
// Bridging to Rust slice
|
using byte_view::data;
|
||||||
byte_data(rust::Slice<uint8_t> o) : byte_data(o.data(), o.size()) {}
|
uint8_t *data() const { return _buf; }
|
||||||
operator rust::Slice<uint8_t>() { return rust::Slice<uint8_t>(_buf, _sz); }
|
|
||||||
|
|
||||||
using byte_view::buf;
|
|
||||||
uint8_t *buf() { return _buf; }
|
|
||||||
|
|
||||||
void swap(byte_data &o);
|
void swap(byte_data &o);
|
||||||
rust::Vec<size_t> patch(byte_view from, byte_view to);
|
rust::Vec<size_t> patch(byte_view from, byte_view to) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct heap_data : public byte_data {
|
struct heap_data : public byte_data {
|
||||||
@@ -170,10 +128,7 @@ private:
|
|||||||
int fd;
|
int fd;
|
||||||
};
|
};
|
||||||
|
|
||||||
rust::Vec<size_t> mut_u8_patch(
|
rust::Vec<size_t> mut_u8_patch(MutByteSlice buf, ByteSlice from, ByteSlice to);
|
||||||
rust::Slice<uint8_t> buf,
|
|
||||||
rust::Slice<const uint8_t> from,
|
|
||||||
rust::Slice<const uint8_t> to);
|
|
||||||
|
|
||||||
uint32_t parse_uint32_hex(std::string_view s);
|
uint32_t parse_uint32_hex(std::string_view s);
|
||||||
int parse_int(std::string_view s);
|
int parse_int(std::string_view s);
|
||||||
@@ -276,9 +231,7 @@ struct Utf8CStr {
|
|||||||
|
|
||||||
Utf8CStr() : Utf8CStr("", 1) {};
|
Utf8CStr() : Utf8CStr("", 1) {};
|
||||||
Utf8CStr(const Utf8CStr &o) = default;
|
Utf8CStr(const Utf8CStr &o) = default;
|
||||||
Utf8CStr(Utf8CStr &&o) = default;
|
|
||||||
Utf8CStr(const char *s) : Utf8CStr(s, strlen(s) + 1) {};
|
Utf8CStr(const char *s) : Utf8CStr(s, strlen(s) + 1) {};
|
||||||
Utf8CStr(std::string_view s) : Utf8CStr(s.data(), s.length() + 1) {};
|
|
||||||
Utf8CStr(std::string s) : Utf8CStr(s.data(), s.length() + 1) {};
|
Utf8CStr(std::string s) : Utf8CStr(s.data(), s.length() + 1) {};
|
||||||
const char *c_str() const { return this->data(); }
|
const char *c_str() const { return this->data(); }
|
||||||
size_t size() const { return this->length(); }
|
size_t size() const { return this->length(); }
|
||||||
@@ -296,15 +249,17 @@ private:
|
|||||||
} // namespace rust
|
} // namespace rust
|
||||||
|
|
||||||
// Bindings for std::function to be callable from Rust
|
// Bindings for std::function to be callable from Rust
|
||||||
struct FnBoolStrStr : public std::function<bool(rust::Str, rust::Str)> {
|
|
||||||
using std::function<bool(rust::Str, rust::Str)>::function;
|
using CxxFnBoolStrStr = std::function<bool(rust::Str, rust::Str)>;
|
||||||
|
struct FnBoolStrStr : public CxxFnBoolStrStr {
|
||||||
|
using CxxFnBoolStrStr::function;
|
||||||
bool call(rust::Str a, rust::Str b) const {
|
bool call(rust::Str a, rust::Str b) const {
|
||||||
return operator()(a, b);
|
return operator()(a, b);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
using CxxFnBoolString = std::function<bool(rust::String&)>;
|
||||||
struct FnBoolString : public std::function<bool(rust::String&)> {
|
struct FnBoolString : public CxxFnBoolString {
|
||||||
using std::function<bool(rust::String&)>::function;
|
using CxxFnBoolString::function;
|
||||||
bool call(rust::String &s) const {
|
bool call(rust::String &s) const {
|
||||||
return operator()(s);
|
return operator()(s);
|
||||||
}
|
}
|
||||||
|
@@ -27,7 +27,6 @@ int xlisten(int sockfd, int backlog);
|
|||||||
int xaccept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags);
|
int xaccept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags);
|
||||||
int xstat(const char *pathname, struct stat *buf);
|
int xstat(const char *pathname, struct stat *buf);
|
||||||
int xfstat(int fd, struct stat *buf);
|
int xfstat(int fd, struct stat *buf);
|
||||||
int xdup(int fd);
|
|
||||||
int xdup2(int oldfd, int newfd);
|
int xdup2(int oldfd, int newfd);
|
||||||
ssize_t xreadlink(const char * __restrict__ pathname, char * __restrict__ buf, size_t bufsiz);
|
ssize_t xreadlink(const char * __restrict__ pathname, char * __restrict__ buf, size_t bufsiz);
|
||||||
ssize_t xreadlinkat(
|
ssize_t xreadlinkat(
|
||||||
@@ -42,7 +41,6 @@ int xmkdir(const char *pathname, mode_t mode);
|
|||||||
int xmkdirs(const char *pathname, mode_t mode);
|
int xmkdirs(const char *pathname, mode_t mode);
|
||||||
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(pollfd *fds, nfds_t nfds, int timeout);
|
|
||||||
ssize_t xrealpath(const char * __restrict__ path, char * __restrict__ buf, size_t bufsiz);
|
ssize_t xrealpath(const char * __restrict__ path, char * __restrict__ 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);
|
||||||
|
|
||||||
|
@@ -4,9 +4,7 @@ use crate::cxx_extern::readlinkat;
|
|||||||
use crate::{
|
use crate::{
|
||||||
BorrowedDirectory, CxxResultExt, LibcReturn, Utf8CStr, cstr, slice_from_ptr, slice_from_ptr_mut,
|
BorrowedDirectory, CxxResultExt, LibcReturn, Utf8CStr, cstr, slice_from_ptr, slice_from_ptr_mut,
|
||||||
};
|
};
|
||||||
use libc::{
|
use libc::{c_char, c_uint, c_ulong, c_void, dev_t, mode_t, off_t, sockaddr, socklen_t};
|
||||||
c_char, c_uint, c_ulong, c_void, dev_t, mode_t, nfds_t, off_t, pollfd, sockaddr, socklen_t,
|
|
||||||
};
|
|
||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{Read, Write};
|
use std::io::{Read, Write};
|
||||||
@@ -270,16 +268,6 @@ unsafe extern "C" fn xfstat(fd: RawFd, buf: *mut libc::stat) -> i32 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
|
||||||
extern "C" fn xdup(oldfd: RawFd) -> RawFd {
|
|
||||||
unsafe {
|
|
||||||
libc::dup(oldfd)
|
|
||||||
.as_os_result("dup", None, None)
|
|
||||||
.log_cxx()
|
|
||||||
.unwrap_or(-1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
extern "C" fn xdup2(oldfd: RawFd, newfd: RawFd) -> RawFd {
|
extern "C" fn xdup2(oldfd: RawFd, newfd: RawFd) -> RawFd {
|
||||||
unsafe {
|
unsafe {
|
||||||
@@ -381,16 +369,6 @@ extern "C" fn xfork() -> i32 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
|
||||||
unsafe extern "C" fn xpoll(fds: *mut pollfd, nfds: nfds_t, timeout: i32) -> i32 {
|
|
||||||
unsafe {
|
|
||||||
libc::poll(fds, nfds, timeout)
|
|
||||||
.as_os_result("poll", None, None)
|
|
||||||
.log_cxx()
|
|
||||||
.unwrap_or(-1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
unsafe extern "C" fn xmknod(pathname: *const c_char, mode: mode_t, dev: dev_t) -> i32 {
|
unsafe extern "C" fn xmknod(pathname: *const c_char, mode: mode_t, dev: dev_t) -> i32 {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@@ -189,8 +189,8 @@ void dyn_img_hdr::load_hdr_file() {
|
|||||||
boot_img::boot_img(const char *image) :
|
boot_img::boot_img(const char *image) :
|
||||||
map(image), k_fmt(FileFormat::UNKNOWN), r_fmt(FileFormat::UNKNOWN), e_fmt(FileFormat::UNKNOWN) {
|
map(image), k_fmt(FileFormat::UNKNOWN), r_fmt(FileFormat::UNKNOWN), e_fmt(FileFormat::UNKNOWN) {
|
||||||
fprintf(stderr, "Parsing boot image: [%s]\n", image);
|
fprintf(stderr, "Parsing boot image: [%s]\n", image);
|
||||||
for (const uint8_t *addr = map.buf(); addr < map.buf() + map.sz(); ++addr) {
|
for (const uint8_t *addr = map.data(); addr < map.data() + map.size(); ++addr) {
|
||||||
FileFormat fmt = check_fmt(addr, map.sz());
|
FileFormat fmt = check_fmt(addr, map.size());
|
||||||
switch (fmt) {
|
switch (fmt) {
|
||||||
case FileFormat::CHROMEOS:
|
case FileFormat::CHROMEOS:
|
||||||
// chromeos require external signing
|
// chromeos require external signing
|
||||||
@@ -367,9 +367,9 @@ pair<const uint8_t *, dyn_img_hdr *> boot_img::create_hdr(const uint8_t *addr, F
|
|||||||
|
|
||||||
auto real_hdr_sz = h->page_size - AMONET_MICROLOADER_SZ;
|
auto real_hdr_sz = h->page_size - AMONET_MICROLOADER_SZ;
|
||||||
heap_data copy(h->page_size);
|
heap_data copy(h->page_size);
|
||||||
memcpy(copy.buf(), h, real_hdr_sz);
|
memcpy(copy.data(), h, real_hdr_sz);
|
||||||
|
|
||||||
return make_pair(addr, make_hdr(copy.buf()));
|
return make_pair(addr, make_hdr(copy.data()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CMD_MATCH(NOOKHD_RL_MAGIC) ||
|
if (CMD_MATCH(NOOKHD_RL_MAGIC) ||
|
||||||
@@ -404,7 +404,7 @@ static const char *vendor_ramdisk_type(int type) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define assert_off() \
|
#define assert_off() \
|
||||||
if ((base_addr + off) > (map.buf() + map_end)) { \
|
if ((base_addr + off) > (map.data() + map_end)) { \
|
||||||
fprintf(stderr, "Corrupted boot image!\n"); \
|
fprintf(stderr, "Corrupted boot image!\n"); \
|
||||||
return false; \
|
return false; \
|
||||||
}
|
}
|
||||||
@@ -433,7 +433,7 @@ bool boot_img::parse_image(const uint8_t *p, FileFormat type) {
|
|||||||
|
|
||||||
hdr->print();
|
hdr->print();
|
||||||
|
|
||||||
size_t map_end = align_to(map.sz(), getpagesize());
|
size_t map_end = align_to(map.size(), getpagesize());
|
||||||
size_t off = hdr->hdr_space();
|
size_t off = hdr->hdr_space();
|
||||||
get_block(kernel);
|
get_block(kernel);
|
||||||
get_block(ramdisk);
|
get_block(ramdisk);
|
||||||
@@ -447,13 +447,13 @@ bool boot_img::parse_image(const uint8_t *p, FileFormat type) {
|
|||||||
|
|
||||||
payload = byte_view(base_addr, off);
|
payload = byte_view(base_addr, off);
|
||||||
auto tail_addr = base_addr + off;
|
auto tail_addr = base_addr + off;
|
||||||
tail = byte_view(tail_addr, map.buf() + map_end - tail_addr);
|
tail = byte_view(tail_addr, map.data() + map_end - tail_addr);
|
||||||
|
|
||||||
if (auto size = hdr->kernel_size()) {
|
if (auto size = hdr->kernel_size()) {
|
||||||
if (int dtb_off = find_dtb_offset(kernel, size); dtb_off > 0) {
|
if (int dtb_off = find_dtb_offset(kernel, size); dtb_off > 0) {
|
||||||
kernel_dtb = byte_view(kernel + dtb_off, size - dtb_off);
|
kernel_dtb = byte_view(kernel + dtb_off, size - dtb_off);
|
||||||
hdr->kernel_size() = dtb_off;
|
hdr->kernel_size() = dtb_off;
|
||||||
fprintf(stderr, "%-*s [%zu]\n", PADDING, "KERNEL_DTB_SZ", kernel_dtb.sz());
|
fprintf(stderr, "%-*s [%zu]\n", PADDING, "KERNEL_DTB_SZ", kernel_dtb.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
k_fmt = check_fmt_lg(kernel, hdr->kernel_size());
|
k_fmt = check_fmt_lg(kernel, hdr->kernel_size());
|
||||||
@@ -552,12 +552,12 @@ bool boot_img::parse_image(const uint8_t *p, FileFormat type) {
|
|||||||
fprintf(stderr, "%-*s [%s]\n", PADDING, "EXTRA_FMT", fmt2name(e_fmt));
|
fprintf(stderr, "%-*s [%s]\n", PADDING, "EXTRA_FMT", fmt2name(e_fmt));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tail.sz()) {
|
if (tail.size()) {
|
||||||
// Check special flags
|
// Check special flags
|
||||||
if (tail.sz() >= 16 && BUFFER_MATCH(tail.buf(), SEANDROID_MAGIC)) {
|
if (tail.size() >= 16 && BUFFER_MATCH(tail.data(), SEANDROID_MAGIC)) {
|
||||||
fprintf(stderr, "SAMSUNG_SEANDROID\n");
|
fprintf(stderr, "SAMSUNG_SEANDROID\n");
|
||||||
flags[SEANDROID_FLAG] = true;
|
flags[SEANDROID_FLAG] = true;
|
||||||
} else if (tail.sz() >= 16 && BUFFER_MATCH(tail.buf(), LG_BUMP_MAGIC)) {
|
} else if (tail.size() >= 16 && BUFFER_MATCH(tail.data(), LG_BUMP_MAGIC)) {
|
||||||
fprintf(stderr, "LG_BUMP_IMAGE\n");
|
fprintf(stderr, "LG_BUMP_IMAGE\n");
|
||||||
flags[LG_BUMP_FLAG] = true;
|
flags[LG_BUMP_FLAG] = true;
|
||||||
} else if (verify()) {
|
} else if (verify()) {
|
||||||
@@ -566,7 +566,7 @@ bool boot_img::parse_image(const uint8_t *p, FileFormat type) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Find AVB footer
|
// Find AVB footer
|
||||||
const void *footer = tail.buf() + tail.sz() - sizeof(AvbFooter);
|
const void *footer = tail.data() + tail.size() - sizeof(AvbFooter);
|
||||||
if (BUFFER_MATCH(footer, AVB_FOOTER_MAGIC)) {
|
if (BUFFER_MATCH(footer, AVB_FOOTER_MAGIC)) {
|
||||||
avb_footer = static_cast<const AvbFooter*>(footer);
|
avb_footer = static_cast<const AvbFooter*>(footer);
|
||||||
// Double check if meta header exists
|
// Double check if meta header exists
|
||||||
@@ -586,16 +586,16 @@ bool boot_img::parse_image(const uint8_t *p, FileFormat type) {
|
|||||||
int split_image_dtb(rust::Utf8CStr filename, bool skip_decomp) {
|
int split_image_dtb(rust::Utf8CStr filename, bool skip_decomp) {
|
||||||
mmap_data img(filename.data());
|
mmap_data img(filename.data());
|
||||||
|
|
||||||
if (size_t off = find_dtb_offset(img.buf(), img.sz()); off > 0) {
|
if (size_t off = find_dtb_offset(img.data(), img.size()); off > 0) {
|
||||||
FileFormat fmt = check_fmt_lg(img.buf(), img.sz());
|
FileFormat fmt = check_fmt_lg(img.data(), img.size());
|
||||||
if (!skip_decomp && fmt_compressed(fmt)) {
|
if (!skip_decomp && fmt_compressed(fmt)) {
|
||||||
int fd = creat(KERNEL_FILE, 0644);
|
int fd = creat(KERNEL_FILE, 0644);
|
||||||
decompress(fmt, fd, img.buf(), off);
|
decompress(fmt, fd, img.data(), off);
|
||||||
close(fd);
|
close(fd);
|
||||||
} else {
|
} else {
|
||||||
dump(img.buf(), off, KERNEL_FILE);
|
dump(img.data(), off, KERNEL_FILE);
|
||||||
}
|
}
|
||||||
dump(img.buf() + off, img.sz() - off, KER_DTB_FILE);
|
dump(img.data() + off, img.size() - off, KER_DTB_FILE);
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "Cannot find DTB in %s\n", filename.data());
|
fprintf(stderr, "Cannot find DTB in %s\n", filename.data());
|
||||||
@@ -621,7 +621,7 @@ int unpack(rust::Utf8CStr image, bool skip_decomp, bool hdr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Dump kernel_dtb
|
// Dump kernel_dtb
|
||||||
dump(boot.kernel_dtb.buf(), boot.kernel_dtb.sz(), KER_DTB_FILE);
|
dump(boot.kernel_dtb.data(), boot.kernel_dtb.size(), KER_DTB_FILE);
|
||||||
|
|
||||||
// Dump ramdisk
|
// Dump ramdisk
|
||||||
if (boot.hdr->vendor_ramdisk_table_size()) {
|
if (boot.hdr->vendor_ramdisk_table_size()) {
|
||||||
@@ -725,16 +725,16 @@ void repack(rust::Utf8CStr src_img, rust::Utf8CStr out_img, bool skip_comp) {
|
|||||||
// Skip DHTB header
|
// Skip DHTB header
|
||||||
write_zero(fd, sizeof(dhtb_hdr));
|
write_zero(fd, sizeof(dhtb_hdr));
|
||||||
} else if (boot.flags[BLOB_FLAG]) {
|
} else if (boot.flags[BLOB_FLAG]) {
|
||||||
xwrite(fd, boot.map.buf(), sizeof(blob_hdr));
|
xwrite(fd, boot.map.data(), sizeof(blob_hdr));
|
||||||
} else if (boot.flags[NOOKHD_FLAG]) {
|
} else if (boot.flags[NOOKHD_FLAG]) {
|
||||||
xwrite(fd, boot.map.buf(), NOOKHD_PRE_HEADER_SZ);
|
xwrite(fd, boot.map.data(), NOOKHD_PRE_HEADER_SZ);
|
||||||
} else if (boot.flags[ACCLAIM_FLAG]) {
|
} else if (boot.flags[ACCLAIM_FLAG]) {
|
||||||
xwrite(fd, boot.map.buf(), ACCLAIM_PRE_HEADER_SZ);
|
xwrite(fd, boot.map.data(), ACCLAIM_PRE_HEADER_SZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy raw header
|
// Copy raw header
|
||||||
off.header = lseek(fd, 0, SEEK_CUR);
|
off.header = lseek(fd, 0, SEEK_CUR);
|
||||||
xwrite(fd, boot.payload.buf(), hdr->hdr_space());
|
xwrite(fd, boot.payload.data(), hdr->hdr_space());
|
||||||
|
|
||||||
// kernel
|
// kernel
|
||||||
off.kernel = lseek(fd, 0, SEEK_CUR);
|
off.kernel = lseek(fd, 0, SEEK_CUR);
|
||||||
@@ -748,12 +748,12 @@ void repack(rust::Utf8CStr src_img, rust::Utf8CStr out_img, bool skip_comp) {
|
|||||||
}
|
}
|
||||||
if (access(KERNEL_FILE, R_OK) == 0) {
|
if (access(KERNEL_FILE, R_OK) == 0) {
|
||||||
mmap_data m(KERNEL_FILE);
|
mmap_data m(KERNEL_FILE);
|
||||||
if (!skip_comp && !fmt_compressed_any(check_fmt(m.buf(), m.sz())) && fmt_compressed(boot.k_fmt)) {
|
if (!skip_comp && !fmt_compressed_any(check_fmt(m.data(), m.size())) && fmt_compressed(boot.k_fmt)) {
|
||||||
// Always use zopfli for zImage compression
|
// Always use zopfli for zImage compression
|
||||||
auto fmt = (boot.flags[ZIMAGE_KERNEL] && boot.k_fmt == FileFormat::GZIP) ? FileFormat::ZOPFLI : boot.k_fmt;
|
auto fmt = (boot.flags[ZIMAGE_KERNEL] && boot.k_fmt == FileFormat::GZIP) ? FileFormat::ZOPFLI : boot.k_fmt;
|
||||||
hdr->kernel_size() = compress_len(fmt, m, fd);
|
hdr->kernel_size() = compress_len(fmt, m, fd);
|
||||||
} else {
|
} else {
|
||||||
hdr->kernel_size() = xwrite(fd, m.buf(), m.sz());
|
hdr->kernel_size() = xwrite(fd, m.data(), m.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (boot.flags[ZIMAGE_KERNEL]) {
|
if (boot.flags[ZIMAGE_KERNEL]) {
|
||||||
@@ -764,7 +764,7 @@ void repack(rust::Utf8CStr src_img, rust::Utf8CStr out_img, bool skip_comp) {
|
|||||||
} else if (!skip_comp) {
|
} else if (!skip_comp) {
|
||||||
// Pad zeros to make sure the zImage file size does not change
|
// Pad zeros to make sure the zImage file size does not change
|
||||||
// Also ensure the last 4 bytes are the uncompressed vmlinux size
|
// Also ensure the last 4 bytes are the uncompressed vmlinux size
|
||||||
uint32_t sz = m.sz();
|
uint32_t sz = m.size();
|
||||||
write_zero(fd, boot.hdr->kernel_size() - hdr->kernel_size() - sizeof(sz));
|
write_zero(fd, boot.hdr->kernel_size() - hdr->kernel_size() - sizeof(sz));
|
||||||
xwrite(fd, &sz, sizeof(sz));
|
xwrite(fd, &sz, sizeof(sz));
|
||||||
}
|
}
|
||||||
@@ -779,7 +779,7 @@ void repack(rust::Utf8CStr src_img, rust::Utf8CStr out_img, bool skip_comp) {
|
|||||||
if (boot.flags[ZIMAGE_KERNEL]) {
|
if (boot.flags[ZIMAGE_KERNEL]) {
|
||||||
// Copy zImage tail and adjust size accordingly
|
// Copy zImage tail and adjust size accordingly
|
||||||
hdr->kernel_size() += boot.z_info.hdr_sz;
|
hdr->kernel_size() += boot.z_info.hdr_sz;
|
||||||
hdr->kernel_size() += xwrite(fd, boot.z_info.tail.buf(), boot.z_info.tail.sz());
|
hdr->kernel_size() += xwrite(fd, boot.z_info.tail.data(), boot.z_info.tail.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
// kernel dtb
|
// kernel dtb
|
||||||
@@ -816,10 +816,10 @@ void repack(rust::Utf8CStr src_img, rust::Utf8CStr out_img, bool skip_comp) {
|
|||||||
mmap_data m(dirfd, file_name);
|
mmap_data m(dirfd, file_name);
|
||||||
FileFormat fmt = check_fmt_lg(boot.ramdisk + it.ramdisk_offset, it.ramdisk_size);
|
FileFormat fmt = check_fmt_lg(boot.ramdisk + it.ramdisk_offset, it.ramdisk_size);
|
||||||
it.ramdisk_offset = ramdisk_offset;
|
it.ramdisk_offset = ramdisk_offset;
|
||||||
if (!skip_comp && !fmt_compressed_any(check_fmt(m.buf(), m.sz())) && fmt_compressed(fmt)) {
|
if (!skip_comp && !fmt_compressed_any(check_fmt(m.data(), m.size())) && fmt_compressed(fmt)) {
|
||||||
it.ramdisk_size = compress_len(fmt, m, fd);
|
it.ramdisk_size = compress_len(fmt, m, fd);
|
||||||
} else {
|
} else {
|
||||||
it.ramdisk_size = xwrite(fd, m.buf(), m.sz());
|
it.ramdisk_size = xwrite(fd, m.data(), m.size());
|
||||||
}
|
}
|
||||||
ramdisk_offset += it.ramdisk_size;
|
ramdisk_offset += it.ramdisk_size;
|
||||||
}
|
}
|
||||||
@@ -836,10 +836,10 @@ void repack(rust::Utf8CStr src_img, rust::Utf8CStr out_img, bool skip_comp) {
|
|||||||
fprintf(stderr, "RAMDISK_FMT: [%s] -> [%s]\n", fmt2name(r_fmt), fmt2name(FileFormat::LZ4_LEGACY));
|
fprintf(stderr, "RAMDISK_FMT: [%s] -> [%s]\n", fmt2name(r_fmt), fmt2name(FileFormat::LZ4_LEGACY));
|
||||||
r_fmt = FileFormat::LZ4_LEGACY;
|
r_fmt = FileFormat::LZ4_LEGACY;
|
||||||
}
|
}
|
||||||
if (!skip_comp && !fmt_compressed_any(check_fmt(m.buf(), m.sz())) && fmt_compressed(r_fmt)) {
|
if (!skip_comp && !fmt_compressed_any(check_fmt(m.data(), m.size())) && fmt_compressed(r_fmt)) {
|
||||||
hdr->ramdisk_size() = compress_len(r_fmt, m, fd);
|
hdr->ramdisk_size() = compress_len(r_fmt, m, fd);
|
||||||
} else {
|
} else {
|
||||||
hdr->ramdisk_size() = xwrite(fd, m.buf(), m.sz());
|
hdr->ramdisk_size() = xwrite(fd, m.data(), m.size());
|
||||||
}
|
}
|
||||||
file_align();
|
file_align();
|
||||||
}
|
}
|
||||||
@@ -855,10 +855,10 @@ void repack(rust::Utf8CStr src_img, rust::Utf8CStr out_img, bool skip_comp) {
|
|||||||
off.extra = lseek(fd, 0, SEEK_CUR);
|
off.extra = lseek(fd, 0, SEEK_CUR);
|
||||||
if (access(EXTRA_FILE, R_OK) == 0) {
|
if (access(EXTRA_FILE, R_OK) == 0) {
|
||||||
mmap_data m(EXTRA_FILE);
|
mmap_data m(EXTRA_FILE);
|
||||||
if (!skip_comp && !fmt_compressed_any(check_fmt(m.buf(), m.sz())) && fmt_compressed(boot.e_fmt)) {
|
if (!skip_comp && !fmt_compressed_any(check_fmt(m.data(), m.size())) && fmt_compressed(boot.e_fmt)) {
|
||||||
hdr->extra_size() = compress_len(boot.e_fmt, m, fd);
|
hdr->extra_size() = compress_len(boot.e_fmt, m, fd);
|
||||||
} else {
|
} else {
|
||||||
hdr->extra_size() = xwrite(fd, m.buf(), m.sz());
|
hdr->extra_size() = xwrite(fd, m.data(), m.size());
|
||||||
}
|
}
|
||||||
file_align();
|
file_align();
|
||||||
}
|
}
|
||||||
@@ -921,8 +921,8 @@ void repack(rust::Utf8CStr src_img, rust::Utf8CStr out_img, bool skip_comp) {
|
|||||||
// Pad image to original size if not chromeos (as it requires post processing)
|
// Pad image to original size if not chromeos (as it requires post processing)
|
||||||
if (!boot.flags[CHROMEOS_FLAG]) {
|
if (!boot.flags[CHROMEOS_FLAG]) {
|
||||||
off_t current = lseek(fd, 0, SEEK_CUR);
|
off_t current = lseek(fd, 0, SEEK_CUR);
|
||||||
if (current < boot.map.sz()) {
|
if (current < boot.map.size()) {
|
||||||
write_zero(fd, boot.map.sz() - current);
|
write_zero(fd, boot.map.size() - current);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -935,12 +935,12 @@ void repack(rust::Utf8CStr src_img, rust::Utf8CStr out_img, bool skip_comp) {
|
|||||||
|
|
||||||
// MTK headers
|
// MTK headers
|
||||||
if (boot.flags[MTK_KERNEL]) {
|
if (boot.flags[MTK_KERNEL]) {
|
||||||
auto m_hdr = reinterpret_cast<mtk_hdr *>(out.buf() + off.kernel);
|
auto m_hdr = reinterpret_cast<mtk_hdr *>(out.data() + off.kernel);
|
||||||
m_hdr->size = hdr->kernel_size();
|
m_hdr->size = hdr->kernel_size();
|
||||||
hdr->kernel_size() += sizeof(mtk_hdr);
|
hdr->kernel_size() += sizeof(mtk_hdr);
|
||||||
}
|
}
|
||||||
if (boot.flags[MTK_RAMDISK]) {
|
if (boot.flags[MTK_RAMDISK]) {
|
||||||
auto m_hdr = reinterpret_cast<mtk_hdr *>(out.buf() + off.ramdisk);
|
auto m_hdr = reinterpret_cast<mtk_hdr *>(out.data() + off.ramdisk);
|
||||||
m_hdr->size = hdr->ramdisk_size();
|
m_hdr->size = hdr->ramdisk_size();
|
||||||
hdr->ramdisk_size() += sizeof(mtk_hdr);
|
hdr->ramdisk_size() += sizeof(mtk_hdr);
|
||||||
}
|
}
|
||||||
@@ -952,28 +952,28 @@ void repack(rust::Utf8CStr src_img, rust::Utf8CStr out_img, bool skip_comp) {
|
|||||||
if (char *id = hdr->id()) {
|
if (char *id = hdr->id()) {
|
||||||
auto ctx = get_sha(!boot.flags[SHA256_FLAG]);
|
auto ctx = get_sha(!boot.flags[SHA256_FLAG]);
|
||||||
uint32_t size = hdr->kernel_size();
|
uint32_t size = hdr->kernel_size();
|
||||||
ctx->update(byte_view(out.buf() + off.kernel, size));
|
ctx->update(byte_view(out.data() + off.kernel, size));
|
||||||
ctx->update(byte_view(&size, sizeof(size)));
|
ctx->update(byte_view(&size, sizeof(size)));
|
||||||
size = hdr->ramdisk_size();
|
size = hdr->ramdisk_size();
|
||||||
ctx->update(byte_view(out.buf() + off.ramdisk, size));
|
ctx->update(byte_view(out.data() + off.ramdisk, size));
|
||||||
ctx->update(byte_view(&size, sizeof(size)));
|
ctx->update(byte_view(&size, sizeof(size)));
|
||||||
size = hdr->second_size();
|
size = hdr->second_size();
|
||||||
ctx->update(byte_view(out.buf() + off.second, size));
|
ctx->update(byte_view(out.data() + off.second, size));
|
||||||
ctx->update(byte_view(&size, sizeof(size)));
|
ctx->update(byte_view(&size, sizeof(size)));
|
||||||
size = hdr->extra_size();
|
size = hdr->extra_size();
|
||||||
if (size) {
|
if (size) {
|
||||||
ctx->update(byte_view(out.buf() + off.extra, size));
|
ctx->update(byte_view(out.data() + off.extra, size));
|
||||||
ctx->update(byte_view(&size, sizeof(size)));
|
ctx->update(byte_view(&size, sizeof(size)));
|
||||||
}
|
}
|
||||||
uint32_t ver = hdr->header_version();
|
uint32_t ver = hdr->header_version();
|
||||||
if (ver == 1 || ver == 2) {
|
if (ver == 1 || ver == 2) {
|
||||||
size = hdr->recovery_dtbo_size();
|
size = hdr->recovery_dtbo_size();
|
||||||
ctx->update(byte_view(out.buf() + hdr->recovery_dtbo_offset(), size));
|
ctx->update(byte_view(out.data() + hdr->recovery_dtbo_offset(), size));
|
||||||
ctx->update(byte_view(&size, sizeof(size)));
|
ctx->update(byte_view(&size, sizeof(size)));
|
||||||
}
|
}
|
||||||
if (ver == 2) {
|
if (ver == 2) {
|
||||||
size = hdr->dtb_size();
|
size = hdr->dtb_size();
|
||||||
ctx->update(byte_view(out.buf() + off.dtb, size));
|
ctx->update(byte_view(out.data() + off.dtb, size));
|
||||||
ctx->update(byte_view(&size, sizeof(size)));
|
ctx->update(byte_view(&size, sizeof(size)));
|
||||||
}
|
}
|
||||||
memset(id, 0, BOOT_ID_SIZE);
|
memset(id, 0, BOOT_ID_SIZE);
|
||||||
@@ -986,39 +986,39 @@ void repack(rust::Utf8CStr src_img, rust::Utf8CStr out_img, bool skip_comp) {
|
|||||||
// Copy main header
|
// Copy main header
|
||||||
if (boot.flags[AMONET_FLAG]) {
|
if (boot.flags[AMONET_FLAG]) {
|
||||||
auto real_hdr_sz = std::min(hdr->hdr_space() - AMONET_MICROLOADER_SZ, hdr->hdr_size());
|
auto real_hdr_sz = std::min(hdr->hdr_space() - AMONET_MICROLOADER_SZ, hdr->hdr_size());
|
||||||
memcpy(out.buf() + off.header + AMONET_MICROLOADER_SZ, hdr->raw_hdr(), real_hdr_sz);
|
memcpy(out.data() + off.header + AMONET_MICROLOADER_SZ, hdr->raw_hdr(), real_hdr_sz);
|
||||||
} else {
|
} else {
|
||||||
memcpy(out.buf() + off.header, hdr->raw_hdr(), hdr->hdr_size());
|
memcpy(out.data() + off.header, hdr->raw_hdr(), hdr->hdr_size());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (boot.flags[AVB_FLAG]) {
|
if (boot.flags[AVB_FLAG]) {
|
||||||
// Copy and patch AVB structures
|
// Copy and patch AVB structures
|
||||||
auto footer = reinterpret_cast<AvbFooter*>(out.buf() + out.sz() - sizeof(AvbFooter));
|
auto footer = reinterpret_cast<AvbFooter*>(out.data() + out.size() - sizeof(AvbFooter));
|
||||||
memcpy(footer, boot.avb_footer, sizeof(AvbFooter));
|
memcpy(footer, boot.avb_footer, sizeof(AvbFooter));
|
||||||
footer->original_image_size = __builtin_bswap64(off.total);
|
footer->original_image_size = __builtin_bswap64(off.total);
|
||||||
footer->vbmeta_offset = __builtin_bswap64(off.vbmeta);
|
footer->vbmeta_offset = __builtin_bswap64(off.vbmeta);
|
||||||
if (check_env("PATCHVBMETAFLAG")) {
|
if (check_env("PATCHVBMETAFLAG")) {
|
||||||
auto vbmeta = reinterpret_cast<AvbVBMetaImageHeader*>(out.buf() + off.vbmeta);
|
auto vbmeta = reinterpret_cast<AvbVBMetaImageHeader*>(out.data() + off.vbmeta);
|
||||||
vbmeta->flags = __builtin_bswap32(3);
|
vbmeta->flags = __builtin_bswap32(3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (boot.flags[DHTB_FLAG]) {
|
if (boot.flags[DHTB_FLAG]) {
|
||||||
// DHTB header
|
// DHTB header
|
||||||
auto d_hdr = reinterpret_cast<dhtb_hdr *>(out.buf());
|
auto d_hdr = reinterpret_cast<dhtb_hdr *>(out.data());
|
||||||
memcpy(d_hdr, DHTB_MAGIC, 8);
|
memcpy(d_hdr, DHTB_MAGIC, 8);
|
||||||
d_hdr->size = off.total - sizeof(dhtb_hdr);
|
d_hdr->size = off.total - sizeof(dhtb_hdr);
|
||||||
sha256_hash(byte_view(out.buf() + sizeof(dhtb_hdr), d_hdr->size),
|
sha256_hash(byte_view(out.data() + sizeof(dhtb_hdr), d_hdr->size),
|
||||||
byte_data(d_hdr->checksum, 32));
|
byte_data(d_hdr->checksum, 32));
|
||||||
} else if (boot.flags[BLOB_FLAG]) {
|
} else if (boot.flags[BLOB_FLAG]) {
|
||||||
// Blob header
|
// Blob header
|
||||||
auto b_hdr = reinterpret_cast<blob_hdr *>(out.buf());
|
auto b_hdr = reinterpret_cast<blob_hdr *>(out.data());
|
||||||
b_hdr->size = off.total - sizeof(blob_hdr);
|
b_hdr->size = off.total - sizeof(blob_hdr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sign the image after we finish patching the boot image
|
// Sign the image after we finish patching the boot image
|
||||||
if (boot.flags[AVB1_SIGNED_FLAG]) {
|
if (boot.flags[AVB1_SIGNED_FLAG]) {
|
||||||
byte_view payload(out.buf() + off.header, off.total - off.header);
|
byte_view payload(out.data() + off.header, off.total - off.header);
|
||||||
auto sig = sign_payload(payload);
|
auto sig = sign_payload(payload);
|
||||||
if (!sig.empty()) {
|
if (!sig.empty()) {
|
||||||
lseek(fd, off.total, SEEK_SET);
|
lseek(fd, off.total, SEEK_SET);
|
||||||
|
@@ -345,6 +345,17 @@ struct vendor_ramdisk_table_entry_v4 {
|
|||||||
* Polymorphic Universal Header
|
* Polymorphic Universal Header
|
||||||
*******************************/
|
*******************************/
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
static T align_to(T v, int a) {
|
||||||
|
static_assert(std::is_integral_v<T>);
|
||||||
|
return (v + a - 1) / a * a;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
static T align_padding(T v, int a) {
|
||||||
|
return align_to(v, a) - v;
|
||||||
|
}
|
||||||
|
|
||||||
#define decl_val(name, len) \
|
#define decl_val(name, len) \
|
||||||
virtual uint##len##_t name() const { return 0; }
|
virtual uint##len##_t name() const { return 0; }
|
||||||
|
|
||||||
@@ -678,7 +689,7 @@ struct boot_img {
|
|||||||
rust::Slice<const uint8_t> get_payload() const { return payload; }
|
rust::Slice<const uint8_t> get_payload() const { return payload; }
|
||||||
rust::Slice<const uint8_t> get_tail() const { return tail; }
|
rust::Slice<const uint8_t> get_tail() const { return tail; }
|
||||||
bool is_signed() const { return flags[AVB1_SIGNED_FLAG]; }
|
bool is_signed() const { return flags[AVB1_SIGNED_FLAG]; }
|
||||||
uint64_t tail_off() const { return tail.buf() - map.buf(); }
|
uint64_t tail_off() const { return tail.data() - map.data(); }
|
||||||
|
|
||||||
// Implemented in Rust
|
// Implemented in Rust
|
||||||
bool verify() const noexcept;
|
bool verify() const noexcept;
|
||||||
|
@@ -446,7 +446,7 @@ void exec_root_shell(int client, int pid, SuRequest &req, MntNsMode mode) {
|
|||||||
char path[32];
|
char path[32];
|
||||||
ssprintf(path, sizeof(path), "/proc/%d/cwd", pid);
|
ssprintf(path, sizeof(path), "/proc/%d/cwd", pid);
|
||||||
char cwd[4096];
|
char cwd[4096];
|
||||||
if (realpath(path, cwd, sizeof(cwd)) > 0)
|
if (canonical_path(path, cwd, sizeof(cwd)) > 0)
|
||||||
chdir(cwd);
|
chdir(cwd);
|
||||||
ssprintf(path, sizeof(path), "/proc/%d/environ", pid);
|
ssprintf(path, sizeof(path), "/proc/%d/environ", pid);
|
||||||
auto env = full_read(path);
|
auto env = full_read(path);
|
||||||
|
@@ -147,7 +147,7 @@ void MagiskInit::patch_fissiond(const char *tmp_path) noexcept {
|
|||||||
}
|
}
|
||||||
mkdirs(ROOTOVL "/system/bin", 0755);
|
mkdirs(ROOTOVL "/system/bin", 0755);
|
||||||
if (auto target_fissiond = xopen_file(ROOTOVL "/system/bin/fissiond", "we")) {
|
if (auto target_fissiond = xopen_file(ROOTOVL "/system/bin/fissiond", "we")) {
|
||||||
fwrite(fissiond.buf(), 1, fissiond.sz(), target_fissiond.get());
|
fwrite(fissiond.data(), 1, fissiond.size(), target_fissiond.get());
|
||||||
clone_attr("/system/bin/fissiond", ROOTOVL "/system/bin/fissiond");
|
clone_attr("/system/bin/fissiond", ROOTOVL "/system/bin/fissiond");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -160,8 +160,7 @@ void MagiskInit::patch_fissiond(const char *tmp_path) noexcept {
|
|||||||
LOGD("hijacked isolated\n");
|
LOGD("hijacked isolated\n");
|
||||||
xumount2("/sys/devices/system/cpu/isolated", MNT_DETACH);
|
xumount2("/sys/devices/system/cpu/isolated", MNT_DETACH);
|
||||||
unlink(INTLROOT "/isolated");
|
unlink(INTLROOT "/isolated");
|
||||||
string content;
|
string content = full_read(fileno(hijack.get()));
|
||||||
full_read(fileno(hijack.get()), content);
|
|
||||||
{
|
{
|
||||||
string target = "/dev/cells/cell2"s + tmp_path;
|
string target = "/dev/cells/cell2"s + tmp_path;
|
||||||
xmkdirs(target.data(), 0);
|
xmkdirs(target.data(), 0);
|
||||||
@@ -299,7 +298,7 @@ void MagiskInit::patch_ro_root() noexcept {
|
|||||||
LOGD("Patch @ %08zX [android,fstab] -> [xxx]\n", off);
|
LOGD("Patch @ %08zX [android,fstab] -> [xxx]\n", off);
|
||||||
}
|
}
|
||||||
int dest = xopen(ROOTOVL "/init", O_CREAT | O_WRONLY | O_CLOEXEC, 0);
|
int dest = xopen(ROOTOVL "/init", O_CREAT | O_WRONLY | O_CLOEXEC, 0);
|
||||||
xwrite(dest, init.buf(), init.sz());
|
xwrite(dest, init.data(), init.size());
|
||||||
fclone_attr(src, dest);
|
fclone_attr(src, dest);
|
||||||
close(src);
|
close(src);
|
||||||
close(dest);
|
close(dest);
|
||||||
|
@@ -74,7 +74,7 @@ static bool check_precompiled(const char *precompiled) {
|
|||||||
|
|
||||||
static void load_cil(struct cil_db *db, const char *file) {
|
static void load_cil(struct cil_db *db, const char *file) {
|
||||||
mmap_data d(file);
|
mmap_data d(file);
|
||||||
cil_add_file(db, file, (const char *) d.buf(), d.sz());
|
cil_add_file(db, file, (const char *) d.data(), d.size());
|
||||||
LOGD("cil_add [%s]\n", file);
|
LOGD("cil_add [%s]\n", file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user