From 625a1d6f448108c341233773724f517815f32d40 Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Wed, 28 Feb 2024 11:07:53 -0800 Subject: [PATCH] Remove seek support from streams --- native/src/base/include/stream.hpp | 49 ++++++++-------- native/src/base/misc.hpp | 6 +- native/src/base/stream.cpp | 89 ++++++------------------------ native/src/boot/bootimg.cpp | 4 +- native/src/boot/compress.cpp | 10 ++-- native/src/init/getinfo.cpp | 2 +- native/src/init/rootdir.cpp | 6 +- native/src/init/selinux.cpp | 2 +- native/src/sepolicy/policydb.cpp | 2 +- 9 files changed, 56 insertions(+), 114 deletions(-) diff --git a/native/src/base/include/stream.hpp b/native/src/base/include/stream.hpp index 5cb5a1deb..631cfd14b 100644 --- a/native/src/base/include/stream.hpp +++ b/native/src/base/include/stream.hpp @@ -53,22 +53,20 @@ struct in_stream { virtual ~in_stream() = default; }; -// A channel is something that is writable, readable, and seekable -struct channel : public out_stream, public in_stream { - virtual off_t seek(off_t off, int whence) = 0; - virtual ~channel() = default; +// A stream is something that is writable and readable +struct stream : public out_stream, public in_stream { + virtual ~stream() = default; }; -using channel_ptr = std::unique_ptr; +using stream_ptr = std::unique_ptr; -// Byte channel that dynamically allocates memory -class byte_channel : public channel { +// Byte stream that dynamically allocates memory +class byte_stream : public stream { public: - byte_channel(heap_data &data) : _data(data) {} + byte_stream(heap_data &data) : _data(data) {} ssize_t read(void *buf, size_t len) override; bool write(const void *buf, size_t len) override; - off_t seek(off_t off, int whence) override; private: heap_data &_data; @@ -78,13 +76,12 @@ private: void resize(size_t new_sz, bool zero = false); }; -class rust_vec_channel : public channel { +class rust_vec_stream : public stream { public: - rust_vec_channel(rust::Vec &data) : _data(data) {} + rust_vec_stream(rust::Vec &data) : _data(data) {} ssize_t read(void *buf, size_t len) override; bool write(const void *buf, size_t len) override; - off_t seek(off_t off, int whence) override; private: rust::Vec &_data; @@ -93,21 +90,20 @@ private: void ensure_size(size_t sz, bool zero = false); }; -class file_channel : public channel { +class file_stream : public stream { public: bool write(const void *buf, size_t len) final; protected: virtual ssize_t do_write(const void *buf, size_t len) = 0; }; -// File channel but does not close the file descriptor at any time -class fd_channel : public file_channel { +// File stream but does not close the file descriptor at any time +class fd_stream : public file_stream { public: - fd_channel(int fd) : fd(fd) {} + fd_stream(int fd) : fd(fd) {} ssize_t read(void *buf, size_t len) override; ssize_t readv(const iovec *iov, int iovcnt) override; ssize_t writev(const iovec *iov, int iovcnt) override; - off_t seek(off_t off, int whence) override; protected: ssize_t do_write(const void *buf, size_t len) override; private: @@ -115,26 +111,25 @@ private: }; /* **************************************** - * Bridge between channel class and C stdio + * Bridge between stream class and C stdio * ****************************************/ -// sFILE -> channel_ptr -class fp_channel final : public file_channel { +// sFILE -> stream_ptr +class fp_stream final : public file_stream { public: - fp_channel(FILE *fp = nullptr) : fp(fp, fclose) {} - fp_channel(sFILE &&fp) : fp(std::move(fp)) {} + fp_stream(FILE *fp = nullptr) : fp(fp, fclose) {} + fp_stream(sFILE &&fp) : fp(std::move(fp)) {} ssize_t read(void *buf, size_t len) override; - off_t seek(off_t off, int whence) override; protected: ssize_t do_write(const void *buf, size_t len) override; private: sFILE fp; }; -// channel_ptr -> sFILE -sFILE make_channel_fp(channel_ptr &&strm); +// stream_ptr -> sFILE +sFILE make_stream_fp(stream_ptr &&strm); template -sFILE make_channel_fp(Args &&... args) { - return make_channel_fp(channel_ptr(new T(std::forward(args)...))); +sFILE make_stream_fp(Args &&... args) { + return make_stream_fp(stream_ptr(new T(std::forward(args)...))); } diff --git a/native/src/base/misc.hpp b/native/src/base/misc.hpp index cc9253b8f..73fe1c9a2 100644 --- a/native/src/base/misc.hpp +++ b/native/src/base/misc.hpp @@ -205,7 +205,7 @@ private: uint8_t arr[N]; }; -class byte_channel; +class byte_stream; struct heap_data : public byte_data { ALLOW_MOVE_ONLY(heap_data) @@ -214,8 +214,8 @@ struct heap_data : public byte_data { explicit heap_data(size_t sz) : byte_data(calloc(sz, 1), sz) {} ~heap_data() { free(_buf); } - // byte_channel needs to reallocate the internal buffer - friend byte_channel; + // byte_stream needs to reallocate the internal buffer + friend byte_stream; }; struct owned_fd { diff --git a/native/src/base/stream.cpp b/native/src/base/stream.cpp index 8bebf2eaf..2a03b2bef 100644 --- a/native/src/base/stream.cpp +++ b/native/src/base/stream.cpp @@ -7,30 +7,25 @@ using namespace std; static int strm_read(void *v, char *buf, int len) { - auto strm = static_cast(v); + auto strm = static_cast(v); return strm->read(buf, len); } static int strm_write(void *v, const char *buf, int len) { - auto strm = static_cast(v); + auto strm = static_cast(v); if (!strm->write(buf, len)) return -1; return len; } -static fpos_t strm_seek(void *v, fpos_t off, int whence) { - auto strm = static_cast(v); - return strm->seek(off, whence); -} - static int strm_close(void *v) { - auto strm = static_cast(v); + auto strm = static_cast(v); delete strm; return 0; } -sFILE make_channel_fp(channel_ptr &&strm) { - auto fp = make_file(funopen(strm.release(), strm_read, strm_write, strm_seek, strm_close)); +sFILE make_stream_fp(stream_ptr &&strm) { + auto fp = make_file(funopen(strm.release(), strm_read, strm_write, nullptr, strm_close)); setbuf(fp.get(), nullptr); return fp; } @@ -71,19 +66,15 @@ ssize_t out_stream::writev(const iovec *iov, int iovcnt) { return write_sz; } -ssize_t fp_channel::read(void *buf, size_t len) { +ssize_t fp_stream::read(void *buf, size_t len) { auto ret = fread(buf, 1, len, fp.get()); return ret ? ret : (ferror(fp.get()) ? -1 : 0); } -ssize_t fp_channel::do_write(const void *buf, size_t len) { +ssize_t fp_stream::do_write(const void *buf, size_t len) { return fwrite(buf, 1, len, fp.get()); } -off_t fp_channel::seek(off_t off, int whence) { - return fseek(fp.get(), off, whence); -} - bool filter_out_stream::write(const void *buf, size_t len) { return base->write(buf, len); } @@ -131,14 +122,14 @@ void chunk_out_stream::finalize() { } } -ssize_t byte_channel::read(void *buf, size_t len) { +ssize_t byte_stream::read(void *buf, size_t len) { len = std::min((size_t) len, _data._sz- _pos); memcpy(buf, _data.buf() + _pos, len); _pos += len; return len; } -bool byte_channel::write(const void *buf, size_t len) { +bool byte_stream::write(const void *buf, size_t len) { resize(_pos + len); memcpy(_data.buf() + _pos, buf, len); _pos += len; @@ -146,27 +137,7 @@ bool byte_channel::write(const void *buf, size_t len) { return true; } -off_t byte_channel::seek(off_t off, int whence) { - off_t np; - switch (whence) { - case SEEK_CUR: - np = _pos + off; - break; - case SEEK_END: - np = _data._sz+ off; - break; - case SEEK_SET: - np = off; - break; - default: - return -1; - } - resize(np, true); - _pos = np; - return np; -} - -void byte_channel::resize(size_t new_sz, bool zero) { +void byte_stream::resize(size_t new_sz, bool zero) { bool resize = false; size_t old_cap = _cap; while (new_sz > _cap) { @@ -180,41 +151,21 @@ void byte_channel::resize(size_t new_sz, bool zero) { } } -ssize_t rust_vec_channel::read(void *buf, size_t len) { +ssize_t rust_vec_stream::read(void *buf, size_t len) { len = std::min(len, _data.size() - _pos); memcpy(buf, _data.data() + _pos, len); _pos += len; return len; } -bool rust_vec_channel::write(const void *buf, size_t len) { +bool rust_vec_stream::write(const void *buf, size_t len) { ensure_size(_pos + len); memcpy(_data.data() + _pos, buf, len); _pos += len; return true; } -off_t rust_vec_channel::seek(off_t off, int whence) { - off_t np; - switch (whence) { - case SEEK_CUR: - np = _pos + off; - break; - case SEEK_END: - np = _data.size() + off; - break; - case SEEK_SET: - np = off; - break; - default: - return -1; - } - ensure_size(np, true); - _pos = np; - return np; -} - -void rust_vec_channel::ensure_size(size_t sz, bool zero) { +void rust_vec_stream::ensure_size(size_t sz, bool zero) { size_t old_sz = _data.size(); if (sz > old_sz) { resize_vec(_data, sz); @@ -223,27 +174,23 @@ void rust_vec_channel::ensure_size(size_t sz, bool zero) { } } -ssize_t fd_channel::read(void *buf, size_t len) { +ssize_t fd_stream::read(void *buf, size_t len) { return ::read(fd, buf, len); } -ssize_t fd_channel::readv(const iovec *iov, int iovcnt) { +ssize_t fd_stream::readv(const iovec *iov, int iovcnt) { return ::readv(fd, iov, iovcnt); } -ssize_t fd_channel::do_write(const void *buf, size_t len) { +ssize_t fd_stream::do_write(const void *buf, size_t len) { return ::write(fd, buf, len); } -ssize_t fd_channel::writev(const iovec *iov, int iovcnt) { +ssize_t fd_stream::writev(const iovec *iov, int iovcnt) { return ::writev(fd, iov, iovcnt); } -off_t fd_channel::seek(off_t off, int whence) { - return lseek(fd, off, whence); -} - -bool file_channel::write(const void *buf, size_t len) { +bool file_stream::write(const void *buf, size_t len) { size_t write_sz = 0; ssize_t ret; do { diff --git a/native/src/boot/bootimg.cpp b/native/src/boot/bootimg.cpp index 170b8df4b..a6f88c615 100644 --- a/native/src/boot/bootimg.cpp +++ b/native/src/boot/bootimg.cpp @@ -16,14 +16,14 @@ using namespace std; #define SHA_DIGEST_SIZE 20 static void decompress(format_t type, int fd, const void *in, size_t size) { - auto ptr = get_decoder(type, make_unique(fd)); + auto ptr = get_decoder(type, make_unique(fd)); ptr->write(in, size); } static off_t compress(format_t type, int fd, const void *in, size_t size) { auto prev = lseek(fd, 0, SEEK_CUR); { - auto strm = get_encoder(type, make_unique(fd)); + auto strm = get_encoder(type, make_unique(fd)); strm->write(in, size); } auto now = lseek(fd, 0, SEEK_CUR); diff --git a/native/src/boot/compress.cpp b/native/src/boot/compress.cpp index f656bc6b6..2aa3f7321 100644 --- a/native/src/boot/compress.cpp +++ b/native/src/boot/compress.cpp @@ -661,7 +661,7 @@ void decompress(char *infile, const char *outfile) { } FILE *out_fp = outfile == "-"sv ? stdout : xfopen(outfile, "we"); - strm = get_decoder(type, make_unique(out_fp)); + strm = get_decoder(type, make_unique(out_fp)); if (ext) *ext = '.'; } if (!strm->write(buf, len)) @@ -702,7 +702,7 @@ void compress(const char *method, const char *infile, const char *outfile) { out_fp = outfile == "-"sv ? stdout : xfopen(outfile, "we"); } - auto strm = get_encoder(fmt, make_unique(out_fp)); + auto strm = get_encoder(fmt, make_unique(out_fp)); char buf[4096]; size_t len; @@ -726,7 +726,7 @@ bool decompress(rust::Slice buf, int fd) { return false; } - auto strm = get_decoder(type, make_unique(fd)); + auto strm = get_decoder(type, make_unique(fd)); if (!strm->write(buf.data(), buf.length())) { return false; } @@ -734,7 +734,7 @@ bool decompress(rust::Slice buf, int fd) { } bool xz(rust::Slice buf, rust::Vec &out) { - auto strm = get_encoder(XZ, make_unique(out)); + auto strm = get_encoder(XZ, make_unique(out)); if (!strm->write(buf.data(), buf.length())) { return false; } @@ -747,7 +747,7 @@ bool unxz(rust::Slice buf, rust::Vec &out) { LOGE("Input file is not in xz format!\n"); return false; } - auto strm = get_decoder(XZ, make_unique(out)); + auto strm = get_decoder(XZ, make_unique(out)); if (!strm->write(buf.data(), buf.length())) { return false; } diff --git a/native/src/init/getinfo.cpp b/native/src/init/getinfo.cpp index b72e63f8c..d2d9be2b5 100644 --- a/native/src/init/getinfo.cpp +++ b/native/src/init/getinfo.cpp @@ -220,7 +220,7 @@ bool check_two_stage() { void unxz_init(const char *init_xz, const char *init) { LOGD("unxz %s -> %s\n", init_xz, init); int fd = xopen(init, O_WRONLY | O_CREAT, 0777); - fd_channel ch(fd); + fd_stream ch(fd); unxz(ch, mmap_data{init_xz}); close(fd); clone_attr(init_xz, init); diff --git a/native/src/init/rootdir.cpp b/native/src/init/rootdir.cpp index 0fffc8d58..6182da6a6 100644 --- a/native/src/init/rootdir.cpp +++ b/native/src/init/rootdir.cpp @@ -196,7 +196,7 @@ static void extract_files(bool sbin) { mmap_data magisk(m32); unlink(m32); int fd = xopen("magisk32", O_WRONLY | O_CREAT, 0755); - fd_channel ch(fd); + fd_stream ch(fd); unxz(ch, magisk); close(fd); } @@ -204,7 +204,7 @@ static void extract_files(bool sbin) { mmap_data magisk(m64); unlink(m64); int fd = xopen("magisk64", O_WRONLY | O_CREAT, 0755); - fd_channel ch(fd); + fd_stream ch(fd); unxz(ch, magisk); close(fd); xsymlink("./magisk64", "magisk"); @@ -215,7 +215,7 @@ static void extract_files(bool sbin) { mmap_data stub(stub_xz); unlink(stub_xz); int fd = xopen("stub.apk", O_WRONLY | O_CREAT, 0); - fd_channel ch(fd); + fd_stream ch(fd); unxz(ch, stub); close(fd); } diff --git a/native/src/init/selinux.cpp b/native/src/init/selinux.cpp index 8159205a3..e7109ae47 100644 --- a/native/src/init/selinux.cpp +++ b/native/src/init/selinux.cpp @@ -42,7 +42,7 @@ static void dump_preload() { int fd = xopen("/dev/preload.so", O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, 0644); if (fd < 0) return; - fd_channel ch(fd); + fd_stream ch(fd); if (!unxz(ch, byte_view(init_ld_xz, sizeof(init_ld_xz)))) return; close(fd); diff --git a/native/src/sepolicy/policydb.cpp b/native/src/sepolicy/policydb.cpp index 30d7f89be..20211054b 100644 --- a/native/src/sepolicy/policydb.cpp +++ b/native/src/sepolicy/policydb.cpp @@ -241,7 +241,7 @@ bool sepolicy::to_file(const char *file) { // No partial writes are allowed to /sys/fs/selinux/load, thus the reason why we // first dump everything into memory, then directly call write system call heap_data data; - auto fp = make_channel_fp(data); + auto fp = make_stream_fp(data); policy_file_t pf; policy_file_init(&pf);