summaryrefslogtreecommitdiffstats
path: root/fuse_sideload.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'fuse_sideload.cpp')
-rw-r--r--fuse_sideload.cpp95
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);
+}