diff --git a/native/src/base/compat/compat.cpp b/native/src/base/compat/compat.cpp deleted file mode 100644 index ce5187506..000000000 --- a/native/src/base/compat/compat.cpp +++ /dev/null @@ -1,144 +0,0 @@ -// This file implements all missing symbols that should exist in normal API 23 -// libc.a but missing in our extremely lean libc.a replacements. - -#include -#include -#include -#include -#include -#include -#include - -extern "C" { - -#if !defined(__LP64__) - -// Add "hacky" libc.a missing symbols back -// All symbols in this file are weak, so a vanilla NDK should still link properly - -#include "fortify.hpp" - -// Original source: https://github.com/freebsd/freebsd/blob/master/contrib/file/src/getline.c -// License: BSD, full copyright notice please check original source - -[[gnu::weak]] -ssize_t getdelim(char **buf, size_t *bufsiz, int delimiter, FILE *fp) { - char *ptr, *eptr; - - if (*buf == nullptr || *bufsiz == 0) { - *bufsiz = BUFSIZ; - if ((*buf = (char *) malloc(*bufsiz)) == nullptr) - return -1; - } - - for (ptr = *buf, eptr = *buf + *bufsiz;;) { - int c = fgetc(fp); - if (c == -1) { - if (feof(fp)) - return ptr == *buf ? -1 : ptr - *buf; - else - return -1; - } - *ptr++ = c; - if (c == delimiter) { - *ptr = '\0'; - return ptr - *buf; - } - if (ptr + 2 >= eptr) { - char *nbuf; - size_t nbufsiz = *bufsiz * 2; - ssize_t d = ptr - *buf; - if ((nbuf = (char *) realloc(*buf, nbufsiz)) == nullptr) - return -1; - *buf = nbuf; - *bufsiz = nbufsiz; - eptr = nbuf + nbufsiz; - ptr = nbuf + d; - } - } -} - -[[gnu::weak]] -ssize_t getline(char **buf, size_t *bufsiz, FILE *fp) { - return getdelim(buf, bufsiz, '\n', fp); -} - -// Missing system call wrappers - -[[gnu::weak]] -ssize_t readlinkat(int dirfd, const char *pathname, char *buf, size_t bufsiz) { - return syscall(__NR_readlinkat, dirfd, pathname, buf, bufsiz); -} - -[[gnu::weak]] -int symlinkat(const char *target, int newdirfd, const char *linkpath) { - return syscall(__NR_symlinkat, target, newdirfd, linkpath); -} - -[[gnu::weak]] -int linkat(int olddirfd, const char *oldpath, - int newdirfd, const char *newpath, int flags) { - return syscall(__NR_linkat, olddirfd, oldpath, newdirfd, newpath, flags); -} - -[[gnu::weak]] -int faccessat(int dirfd, const char *pathname, int mode, int flags) { - return syscall(__NR_faccessat, dirfd, pathname, mode, flags); -} - -[[gnu::weak]] -int mkfifo(const char *path, mode_t mode) { - return mknod(path, (mode & ~S_IFMT) | S_IFIFO, 0); -} - -[[gnu::weak]] -int fsetxattr(int fd, const char *name, const void *value, size_t size, int flags) { - return syscall(__NR_fsetxattr, fd, name, value, size, flags); -} - -[[gnu::weak]] -int lsetxattr(const char *path, const char *name, const void *value, size_t size, int flags) { - return syscall(__NR_lsetxattr, path, name, value, size, flags); -} - -#define SPLIT_64(v) (unsigned)((v) & 0xFFFFFFFF), (unsigned)((v) >> 32) - -#if defined(__arm__) -// Why the additional 0 is required: https://man7.org/linux/man-pages/man2/syscall.2.html -[[gnu::weak]] -int ftruncate64(int fd, off64_t length) { - return syscall(__NR_ftruncate64, fd, 0, SPLIT_64(length)); -} -#elif defined(__i386__) -[[gnu::weak]] -int ftruncate64(int fd, off64_t length) { - return syscall(__NR_ftruncate64, fd, SPLIT_64(length)); -} -#endif - -[[gnu::weak]] -void android_set_abort_message(const char *) {} - -extern FILE __sF[]; - -[[gnu::weak]] FILE* stdin = &__sF[0]; -[[gnu::weak]] FILE* stdout = &__sF[1]; -[[gnu::weak]] FILE* stderr = &__sF[2]; - -#endif // !defined(__LP64__) - -[[maybe_unused]] -int __wrap_renameat(int old_dir_fd, const char *old_path, int new_dir_fd, const char *new_path) { - long out = syscall(__NR_renameat, old_dir_fd, old_path, new_dir_fd, new_path); - if (out == -1 && errno == ENOSYS) { - out = syscall(__NR_renameat2, old_dir_fd, old_path, new_dir_fd, new_path, 0); - } - return static_cast(out); -} - -[[maybe_unused]] -int __wrap_rename(const char *old_path, const char *new_path) { - return __wrap_renameat(AT_FDCWD, old_path, AT_FDCWD, new_path); -} - -} // extern "C" diff --git a/native/src/base/compat/fortify.hpp b/native/src/base/compat/fortify.hpp deleted file mode 100644 index 7ff879bd0..000000000 --- a/native/src/base/compat/fortify.hpp +++ /dev/null @@ -1,144 +0,0 @@ -// Original source: https://android.googlesource.com/platform/bionic/+/master/libc/bionic/fortify.cpp -// License: AOSP, full copyright notice please check original source - -#include -#include - -#undef _FORTIFY_SOURCE - -extern void __vloge(const char* fmt, va_list ap); - -static inline __noreturn __printflike(1, 2) void __fortify_fatal(const char* fmt, ...) { - va_list args; - va_start(args, fmt); - __vloge(fmt, args); - va_end(args); - abort(); -} -static inline void __check_count(const char* fn, const char* identifier, size_t value) { - if (__predict_false(value > SSIZE_MAX)) { - __fortify_fatal("%s: %s %zu > SSIZE_MAX", fn, identifier, value); - } -} -static inline void __check_buffer_access(const char* fn, const char* action, - size_t claim, size_t actual) { - if (__predict_false(claim > actual)) { - __fortify_fatal("%s: prevented %zu-byte %s %zu-byte buffer", fn, claim, action, actual); - } -} - -[[gnu::weak]] -void* __memcpy_chk(void* dst, const void* src, size_t count, size_t dst_len) { - __check_count("memcpy", "count", count); - __check_buffer_access("memcpy", "write into", count, dst_len); - return __call_bypassing_fortify(memcpy)(dst, src, count); -} - -[[gnu::weak]] -char* __strcpy_chk(char* dst, const char* src, size_t dst_len) { - // TODO: optimize so we don't scan src twice. - size_t src_len = __builtin_strlen(src) + 1; - __check_buffer_access("strcpy", "write into", src_len, dst_len); - return __builtin_strcpy(dst, src); -} - -[[gnu::weak]] -size_t __strlcpy_chk(char* dst, const char* src, - size_t supplied_size, size_t dst_len_from_compiler) { - __check_buffer_access("strlcpy", "write into", supplied_size, dst_len_from_compiler); - return __call_bypassing_fortify(strlcpy)(dst, src, supplied_size); -} - -[[gnu::weak]] -char* __strchr_chk(const char* p, int ch, size_t s_len) { - for (;; ++p, s_len--) { - if (__predict_false(s_len == 0)) { - __fortify_fatal("strchr: prevented read past end of buffer"); - } - if (*p == static_cast(ch)) { - return const_cast(p); - } - if (*p == '\0') { - return nullptr; - } - } -} - -[[gnu::weak]] -char* __strcat_chk(char* dst, const char* src, size_t dst_buf_size) { - char* save = dst; - size_t dst_len = __strlen_chk(dst, dst_buf_size); - dst += dst_len; - dst_buf_size -= dst_len; - while ((*dst++ = *src++) != '\0') { - dst_buf_size--; - if (__predict_false(dst_buf_size == 0)) { - __fortify_fatal("strcat: prevented write past end of %zu-byte buffer", dst_buf_size); - } - } - return save; -} - -[[gnu::weak]] -size_t __strlen_chk(const char* s, size_t s_len) { - // TODO: "prevented" here would be a lie because this strlen can run off the end. - // strlen is too important to be expensive, so we wanted to be able to call the optimized - // implementation, but I think we need to implement optimized assembler __strlen_chk routines. - size_t ret = __builtin_strlen(s); - if (__predict_false(ret >= s_len)) { - __fortify_fatal("strlen: detected read past end of buffer"); - } - return ret; -} - -[[gnu::weak]] -int __vsprintf_chk(char* dst, int /*flags*/, - size_t dst_len_from_compiler, const char* format, va_list va) { - // The compiler uses SIZE_MAX to mean "no idea", but our vsnprintf rejects sizes that large. - int result = __call_bypassing_fortify(vsnprintf)(dst, - dst_len_from_compiler == SIZE_MAX ? SSIZE_MAX : dst_len_from_compiler, - format, va); - // Try to catch failures after the fact... - __check_buffer_access("vsprintf", "write into", result + 1, dst_len_from_compiler); - return result; -} - -[[gnu::weak]] -mode_t __umask_chk(mode_t mode) { - if (__predict_false((mode & 0777) != mode)) { - __fortify_fatal("umask: called with invalid mask %o", mode); - } - return __umask_real(mode); -} - -[[gnu::weak]] -ssize_t __read_chk(int fd, void* buf, size_t count, size_t buf_size) { - __check_count("read", "count", count); - __check_buffer_access("read", "write into", count, buf_size); - return __call_bypassing_fortify(read)(fd, buf, count); -} -static inline bool needs_mode(int flags) { - return ((flags & O_CREAT) == O_CREAT) || ((flags & O_TMPFILE) == O_TMPFILE); -} -static inline int force_O_LARGEFILE(int flags) { - return flags | O_LARGEFILE; -} - -[[gnu::weak]] -int __open_2(const char* pathname, int flags) { - if (needs_mode(flags)) __fortify_fatal("open: called with O_CREAT/O_TMPFILE but no mode"); - return __openat_real(AT_FDCWD, pathname, force_O_LARGEFILE(flags), 0); -} - -[[gnu::weak]] -int __openat_2(int fd, const char* pathname, int flags) { - if (needs_mode(flags)) __fortify_fatal("open: called with O_CREAT/O_TMPFILE but no mode"); - return __openat_real(fd, pathname, force_O_LARGEFILE(flags), 0); -} - -[[gnu::weak]] -int __vsnprintf_chk(char* dst, size_t supplied_size, int /*flags*/, - size_t dst_len_from_compiler, const char* format, va_list va) { - __check_buffer_access("vsnprintf", "write into", supplied_size, dst_len_from_compiler); - return __call_bypassing_fortify(vsnprintf)(dst, supplied_size, format, va); -} diff --git a/native/src/base/files.cpp b/native/src/base/files.cpp index 95181618d..8b0c31231 100644 --- a/native/src/base/files.cpp +++ b/native/src/base/files.cpp @@ -101,86 +101,6 @@ void parse_prop_file(const char *file, const function parse_mount_info(const char *pid) { - char buf[PATH_MAX] = {}; - ssprintf(buf, sizeof(buf), "/proc/%s/mountinfo", pid); - std::vector result; - - file_readline(buf, [&result](string_view line) -> bool { - int root_start = 0, root_end = 0; - int target_start = 0, target_end = 0; - int vfs_option_start = 0, vfs_option_end = 0; - int type_start = 0, type_end = 0; - int source_start = 0, source_end = 0; - int fs_option_start = 0, fs_option_end = 0; - int optional_start = 0, optional_end = 0; - unsigned int id, parent, maj, min; - sscanf(line.data(), - "%u " // (1) id - "%u " // (2) parent - "%u:%u " // (3) maj:min - "%n%*s%n " // (4) mountroot - "%n%*s%n " // (5) target - "%n%*s%n" // (6) vfs options (fs-independent) - "%n%*[^-]%n - " // (7) optional fields - "%n%*s%n " // (8) FS type - "%n%*s%n " // (9) source - "%n%*s%n", // (10) fs options (fs specific) - &id, &parent, &maj, &min, &root_start, &root_end, &target_start, - &target_end, &vfs_option_start, &vfs_option_end, - &optional_start, &optional_end, &type_start, &type_end, - &source_start, &source_end, &fs_option_start, &fs_option_end); - - auto root = line.substr(root_start, root_end - root_start); - auto target = line.substr(target_start, target_end - target_start); - auto vfs_option = - line.substr(vfs_option_start, vfs_option_end - vfs_option_start); - ++optional_start; - --optional_end; - auto optional = line.substr( - optional_start, - optional_end - optional_start > 0 ? optional_end - optional_start : 0); - - auto type = line.substr(type_start, type_end - type_start); - auto source = line.substr(source_start, source_end - source_start); - auto fs_option = - line.substr(fs_option_start, fs_option_end - fs_option_start); - - unsigned int shared = 0; - unsigned int master = 0; - unsigned int propagate_from = 0; - if (auto pos = optional.find("shared:"); pos != std::string_view::npos) { - shared = parse_int(optional.substr(pos + 7)); - } - if (auto pos = optional.find("master:"); pos != std::string_view::npos) { - master = parse_int(optional.substr(pos + 7)); - } - if (auto pos = optional.find("propagate_from:"); - pos != std::string_view::npos) { - propagate_from = parse_int(optional.substr(pos + 15)); - } - - result.emplace_back(mount_info { - .id = id, - .parent = parent, - .device = static_cast(makedev(maj, min)), - .root {root}, - .target {target}, - .vfs_option {vfs_option}, - .optional { - .shared = shared, - .master = master, - .propagate_from = propagate_from, - }, - .type {type}, - .source {source}, - .fs_option {fs_option}, - }); - return true; - }); - return result; -} - sDIR make_dir(DIR *dp) { return sDIR(dp, [](DIR *dp){ return dp ? closedir(dp) : 1; }); } diff --git a/native/src/base/files.hpp b/native/src/base/files.hpp index 0c8f7277b..03fd9bada 100644 --- a/native/src/base/files.hpp +++ b/native/src/base/files.hpp @@ -20,23 +20,6 @@ static inline T align_padding(T v, int a) { return align_to(v, a) - v; } -struct mount_info { - unsigned int id; - unsigned int parent; - dev_t device; - std::string root; - std::string target; - std::string vfs_option; - struct { - unsigned int shared; - unsigned int master; - unsigned int propagate_from; - } optional; - std::string type; - std::string source; - std::string fs_option; -}; - struct mmap_data : public byte_data { static_assert((sizeof(void *) == 8 && BLKGETSIZE64 == 0x80081272) || (sizeof(void *) == 4 && BLKGETSIZE64 == 0x80041272)); @@ -77,7 +60,6 @@ void file_readline(const char *file, const std::function void parse_prop_file(FILE *fp, const std::function &fn); void parse_prop_file(const char *file, const std::function &fn); -std::vector parse_mount_info(const char *pid); std::string resolve_preinit_dir(const char *base_dir); using sFILE = std::unique_ptr;