diff options
Diffstat (limited to 'fuse_sideload.cpp')
-rw-r--r-- | fuse_sideload.cpp | 95 |
1 files changed, 64 insertions, 31 deletions
diff --git a/fuse_sideload.cpp b/fuse_sideload.cpp index 1c7e98f01..45c79f90b 100644 --- a/fuse_sideload.cpp +++ b/fuse_sideload.cpp @@ -45,8 +45,9 @@ #include <errno.h> #include <fcntl.h> -#include <limits.h> // PATH_MAX -#include <linux/fuse.h> +#include <limits.h> +#include "fuse.h" +#include <pthread.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> @@ -57,13 +58,19 @@ #include <sys/uio.h> #include <unistd.h> +#ifdef USE_MINCRYPT +#include "mincrypt/sha256.h" +#define SHA256_DIGEST_LENGTH SHA256_DIGEST_SIZE +#else +#include <openssl/sha.h> +#endif + #include <array> #include <string> #include <vector> -#include <android-base/stringprintf.h> -#include <android-base/unique_fd.h> -#include <openssl/sha.h> +//#include <android-base/stringprintf.h> +//#include <android-base/unique_fd.h> static constexpr uint64_t PACKAGE_FILE_ID = FUSE_ROOT_ID + 1; static constexpr uint64_t EXIT_FLAG_ID = FUSE_ROOT_ID + 2; @@ -73,8 +80,12 @@ static constexpr int NO_STATUS_EXIT = 2; using SHA256Digest = std::array<uint8_t, SHA256_DIGEST_LENGTH>; +#ifndef MIN +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#endif + struct fuse_data { - android::base::unique_fd ffd; // file descriptor for the fuse socket + int ffd; // file descriptor for the fuse socket provider_vtab vtab; @@ -91,8 +102,8 @@ struct fuse_data { uint8_t* extra_block; // another block of storage for reads that span two blocks - std::vector<SHA256Digest> - hashes; // SHA-256 hash of each block (all zeros if block hasn't been read yet) + uint8_t* hashes; // SHA-256 hash of each block (all zeros + // if block hasn't been read yet) }; static void fuse_reply(const fuse_data* fd, uint64_t unique, const void* data, size_t len) { @@ -151,7 +162,7 @@ static int handle_init(void* data, fuse_data* fd, const fuse_in_header* hdr) { static void fill_attr(fuse_attr* attr, const fuse_data* fd, uint64_t nodeid, uint64_t size, uint32_t mode) { - *attr = {}; + memset(attr, 0, sizeof(*attr)); attr->nlink = 1; attr->uid = fd->uid; attr->gid = fd->gid; @@ -164,7 +175,8 @@ static void fill_attr(fuse_attr* attr, const fuse_data* fd, uint64_t nodeid, uin } static int handle_getattr(void* /* data */, const fuse_data* fd, const fuse_in_header* hdr) { - fuse_attr_out out = {}; + struct fuse_attr_out out; + memset(&out, 0, sizeof(out)); out.attr_valid = 10; if (hdr->nodeid == FUSE_ROOT_ID) { @@ -184,7 +196,8 @@ static int handle_getattr(void* /* data */, const fuse_data* fd, const fuse_in_h static int handle_lookup(void* data, const fuse_data* fd, const fuse_in_header* hdr) { if (data == nullptr) return -ENOENT; - fuse_entry_out out = {}; + struct fuse_entry_out out; + memset(&out, 0, sizeof(out)); out.entry_valid = 10; out.attr_valid = 10; @@ -209,7 +222,8 @@ static int handle_open(void* /* data */, const fuse_data* fd, const fuse_in_head if (hdr->nodeid == EXIT_FLAG_ID) return -EPERM; if (hdr->nodeid != PACKAGE_FILE_ID) return -ENOENT; - fuse_open_out out = {}; + struct fuse_open_out out; + memset(&out, 0, sizeof(out)); out.fh = 10; // an arbitrary number; we always use the same handle fuse_reply(fd, hdr->unique, &out, sizeof(out)); return NO_STATUS; @@ -256,22 +270,26 @@ static int fetch_block(fuse_data* fd, uint32_t block) { // time we've read this block). // - Otherwise, return -EINVAL for the read. - SHA256Digest hash; - SHA256(fd->block_data, fd->block_size, hash.data()); - - const SHA256Digest& blockhash = fd->hashes[block]; - if (hash == blockhash) { + uint8_t hash[SHA256_DIGEST_LENGTH]; +#ifdef USE_MINCRYPT + SHA256_hash(fd->block_data, fd->block_size, hash); +#else + SHA256(fd->block_data, fd->block_size, hash); +#endif + uint8_t* blockhash = fd->hashes + block * SHA256_DIGEST_LENGTH; + if (memcmp(hash, blockhash, SHA256_DIGEST_LENGTH) == 0) { return 0; } - for (uint8_t i : blockhash) { - if (i != 0) { + int i; + for (i = 0; i < SHA256_DIGEST_LENGTH; ++i) { + if (blockhash[i] != 0) { fd->curr_block = -1; return -EIO; } } - fd->hashes[block] = hash; + memcpy(blockhash, hash, SHA256_DIGEST_LENGTH); return 0; } @@ -356,7 +374,8 @@ int run_fuse_sideload(const provider_vtab& vtab, uint64_t file_size, uint32_t bl return -1; } - fuse_data fd = {}; + fuse_data fd; + memset(&fd, 0, sizeof(fd)); fd.vtab = vtab; fd.file_size = file_size; fd.block_size = block_size; @@ -369,8 +388,14 @@ int run_fuse_sideload(const provider_vtab& vtab, uint64_t file_size, uint32_t bl goto done; } - // All hashes will be zero-initialized. - fd.hashes.resize(fd.file_blocks); + fd.hashes = (uint8_t*)calloc(fd.file_blocks, SHA256_DIGEST_LENGTH); + if (fd.hashes == NULL) { + fprintf(stderr, "failed to allocate %d bites for hashes\n", + fd.file_blocks * SHA256_DIGEST_LENGTH); + result = -1; + goto done; + } + fd.uid = getuid(); fd.gid = getgid(); @@ -388,7 +413,7 @@ int run_fuse_sideload(const provider_vtab& vtab, uint64_t file_size, uint32_t bl goto done; } - fd.ffd.reset(open("/dev/fuse", O_RDWR)); + fd.ffd = open("/dev/fuse", O_RDWR); if (!fd.ffd) { perror("open /dev/fuse"); result = -1; @@ -396,13 +421,15 @@ int run_fuse_sideload(const provider_vtab& vtab, uint64_t file_size, uint32_t bl } { - std::string opts = android::base::StringPrintf( - "fd=%d,user_id=%d,group_id=%d,max_read=%u,allow_other,rootmode=040000", fd.ffd.get(), - fd.uid, fd.gid, block_size); - - result = mount("/dev/fuse", mount_point, "fuse", MS_NOSUID | MS_NODEV | MS_RDONLY | MS_NOEXEC, - opts.c_str()); - if (result == -1) { + char opts[256]; + snprintf(opts, sizeof(opts), + ("fd=%d,user_id=%d,group_id=%d,max_read=%u," + "allow_other,rootmode=040000"), + fd.ffd, fd.uid, fd.gid, block_size); + + result = mount("/dev/fuse", FUSE_SIDELOAD_HOST_MOUNTPOINT, "fuse", + MS_NOSUID | MS_NODEV | MS_RDONLY | MS_NOEXEC, opts); + if (result < 0) { perror("mount"); goto done; } @@ -490,3 +517,9 @@ done: return result; } + +extern "C" int run_old_fuse_sideload(const struct provider_vtab& vtab, void* cookie __unused, + uint64_t file_size, uint32_t block_size) +{ + return run_fuse_sideload(vtab, file_size, block_size, FUSE_SIDELOAD_HOST_MOUNTPOINT); +} |