/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// This module creates a special filesystem containing two files.
//
// "/sideload/package.zip" appears to be a normal file, but reading
// from it causes data to be fetched from the adb host.  We can use
// this to sideload packages over an adb connection without having to
// store the entire package in RAM on the device.
//
// Because we may not trust the adb host, this filesystem maintains
// the following invariant: each read of a given position returns the
// same data as the first read at that position.  That is, once a
// section of the file is read, future reads of that section return
// the same data.  (Otherwise, a malicious adb host process could
// return one set of bits when the package is read for signature
// verification, and then different bits for when the package is
// accessed by the installer.)  If the adb host returns something
// different than it did on the first read, the reader of the file
// will see their read fail with EINVAL.
//
// The other file, "/sideload/exit", is used to control the subprocess
// that creates this filesystem.  Calling stat() on the exit file
// causes the filesystem to be unmounted and the adb process on the
// device shut down.
//
// Note that only the minimal set of file operations needed for these
// two files is implemented.  In particular, you can't opendir() or
// readdir() on the "/sideload" directory; ls on it won't work.

#include <ctype.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include "fuse.h"
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/inotify.h>
#include <sys/mount.h>
#include <sys/param.h>
#include <sys/resource.h>
#include <sys/stat.h>
#include <sys/statfs.h>
#include <sys/time.h>
#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 "fuse_sideload.h"

#define PACKAGE_FILE_ID   (FUSE_ROOT_ID+1)
#define EXIT_FLAG_ID      (FUSE_ROOT_ID+2)

#define NO_STATUS         1
#define NO_STATUS_EXIT    2

#ifndef MIN
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#endif

struct fuse_data {
    int ffd;   // file descriptor for the fuse socket

    struct provider_vtab* vtab;
    void* cookie;

    uint64_t file_size;     // bytes

    uint32_t block_size;    // block size that the adb host is using to send the file to us
    uint32_t file_blocks;   // file size in block_size blocks

    uid_t uid;
    gid_t gid;

    uint32_t curr_block;    // cache the block most recently read from the host
    uint8_t* block_data;

    uint8_t* extra_block;   // another block of storage for reads that
                            // span two blocks

    uint8_t* hashes;        // SHA-256 hash of each block (all zeros
                            // if block hasn't been read yet)
};

static void fuse_reply(struct fuse_data* fd, __u64 unique, const void *data, size_t len)
{
    struct fuse_out_header hdr;
    struct iovec vec[2];
    int res;

    hdr.len = len + sizeof(hdr);
    hdr.error = 0;
    hdr.unique = unique;

    vec[0].iov_base = &hdr;
    vec[0].iov_len = sizeof(hdr);
    vec[1].iov_base = /* const_cast */(void*)(data);
    vec[1].iov_len = len;

    res = writev(fd->ffd, vec, 2);
    if (res < 0) {
        printf("*** REPLY FAILED *** %s\n", strerror(errno));
    }
}

static int handle_init(void* data, struct fuse_data* fd, const struct fuse_in_header* hdr) {
    const struct fuse_init_in* req = reinterpret_cast<const struct fuse_init_in*>(data);
    struct fuse_init_out out;
    size_t fuse_struct_size;


    /* Kernel 2.6.16 is the first stable kernel with struct fuse_init_out
     * defined (fuse version 7.6). The structure is the same from 7.6 through
     * 7.22. Beginning with 7.23, the structure increased in size and added
     * new parameters.
     */
    if (req->major != FUSE_KERNEL_VERSION || req->minor < 6) {
        printf("Fuse kernel version mismatch: Kernel version %d.%d, Expected at least %d.6",
               req->major, req->minor, FUSE_KERNEL_VERSION);
        return -1;
    }

    out.minor = MIN(req->minor, FUSE_KERNEL_MINOR_VERSION);
    fuse_struct_size = sizeof(out);
#if defined(FUSE_COMPAT_22_INIT_OUT_SIZE)
    /* FUSE_KERNEL_VERSION >= 23. */

    /* If the kernel only works on minor revs older than or equal to 22,
     * then use the older structure size since this code only uses the 7.22
     * version of the structure. */
    if (req->minor <= 22) {
        fuse_struct_size = FUSE_COMPAT_22_INIT_OUT_SIZE;
    }
#endif

    out.major = FUSE_KERNEL_VERSION;
    out.max_readahead = req->max_readahead;
    out.flags = 0;
    out.max_background = 32;
    out.congestion_threshold = 32;
    out.max_write = 4096;
    fuse_reply(fd, hdr->unique, &out, fuse_struct_size);

    return NO_STATUS;
}

static void fill_attr(struct fuse_attr* attr, struct fuse_data* fd,
                      uint64_t nodeid, uint64_t size, uint32_t mode) {
    memset(attr, 0, sizeof(*attr));
    attr->nlink = 1;
    attr->uid = fd->uid;
    attr->gid = fd->gid;
    attr->blksize = 4096;

    attr->ino = nodeid;
    attr->size = size;
    attr->blocks = (size == 0) ? 0 : (((size-1) / attr->blksize) + 1);
    attr->mode = mode;
}

static int handle_getattr(void* /* data */, struct fuse_data* fd, const struct fuse_in_header* hdr) {
    struct fuse_attr_out out;
    memset(&out, 0, sizeof(out));
    out.attr_valid = 10;

    if (hdr->nodeid == FUSE_ROOT_ID) {
        fill_attr(&(out.attr), fd, hdr->nodeid, 4096, S_IFDIR | 0555);
    } else if (hdr->nodeid == PACKAGE_FILE_ID) {
        fill_attr(&(out.attr), fd, PACKAGE_FILE_ID, fd->file_size, S_IFREG | 0444);
    } else if (hdr->nodeid == EXIT_FLAG_ID) {
        fill_attr(&(out.attr), fd, EXIT_FLAG_ID, 0, S_IFREG | 0);
    } else {
        return -ENOENT;
    }

    fuse_reply(fd, hdr->unique, &out, sizeof(out));
    return (hdr->nodeid == EXIT_FLAG_ID) ? NO_STATUS_EXIT : NO_STATUS;
}

static int handle_lookup(void* data, struct fuse_data* fd,
                         const struct fuse_in_header* hdr) {
    struct fuse_entry_out out;
    memset(&out, 0, sizeof(out));
    out.entry_valid = 10;
    out.attr_valid = 10;

    if (strncmp(FUSE_SIDELOAD_HOST_FILENAME, reinterpret_cast<const char*>(data),
                sizeof(FUSE_SIDELOAD_HOST_FILENAME)) == 0) {
        out.nodeid = PACKAGE_FILE_ID;
        out.generation = PACKAGE_FILE_ID;
        fill_attr(&(out.attr), fd, PACKAGE_FILE_ID, fd->file_size, S_IFREG | 0444);
    } else if (strncmp(FUSE_SIDELOAD_HOST_EXIT_FLAG, reinterpret_cast<const char*>(data),
                       sizeof(FUSE_SIDELOAD_HOST_EXIT_FLAG)) == 0) {
        out.nodeid = EXIT_FLAG_ID;
        out.generation = EXIT_FLAG_ID;
        fill_attr(&(out.attr), fd, EXIT_FLAG_ID, 0, S_IFREG | 0);
    } else {
        return -ENOENT;
    }

    fuse_reply(fd, hdr->unique, &out, sizeof(out));
    return (out.nodeid == EXIT_FLAG_ID) ? NO_STATUS_EXIT : NO_STATUS;
}

static int handle_open(void* /* data */, struct fuse_data* fd, const struct fuse_in_header* hdr) {
    if (hdr->nodeid == EXIT_FLAG_ID) return -EPERM;
    if (hdr->nodeid != PACKAGE_FILE_ID) return -ENOENT;

    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;
}

static int handle_flush(void* data, struct fuse_data* fd, const struct fuse_in_header* hdr) {
    return 0;
}

static int handle_release(void* data, struct fuse_data* fd, const struct fuse_in_header* hdr) {
    return 0;
}

// Fetch a block from the host into fd->curr_block and fd->block_data.
// Returns 0 on successful fetch, negative otherwise.
static int fetch_block(struct fuse_data* fd, uint32_t block) {
    if (block == fd->curr_block) {
        return 0;
    }

    if (block >= fd->file_blocks) {
        memset(fd->block_data, 0, fd->block_size);
        fd->curr_block = block;
        return 0;
    }

    size_t fetch_size = fd->block_size;
    if (block * fd->block_size + fetch_size > fd->file_size) {
        // If we're reading the last (partial) block of the file,
        // expect a shorter response from the host, and pad the rest
        // of the block with zeroes.
        fetch_size = fd->file_size - (block * fd->block_size);
        memset(fd->block_data + fetch_size, 0, fd->block_size - fetch_size);
    }

    int result = fd->vtab->read_block(fd->cookie, block, fd->block_data, fetch_size);
    if (result < 0) return result;

    fd->curr_block = block;

    // Verify the hash of the block we just got from the host.
    //
    // - If the hash of the just-received data matches the stored hash
    //   for the block, accept it.
    // - If the stored hash is all zeroes, store the new hash and
    //   accept the block (this is the first time we've read this
    //   block).
    // - Otherwise, return -EINVAL for the read.

    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;
    }

    int i;
    for (i = 0; i < SHA256_DIGEST_LENGTH; ++i) {
        if (blockhash[i] != 0) {
            fd->curr_block = -1;
            return -EIO;
        }
    }

    memcpy(blockhash, hash, SHA256_DIGEST_LENGTH);
    return 0;
}

static int handle_read(void* data, struct fuse_data* fd, const struct fuse_in_header* hdr) {
    const struct fuse_read_in* req = reinterpret_cast<const struct fuse_read_in*>(data);
    struct fuse_out_header outhdr;
    struct iovec vec[3];
    int vec_used;
    int result;

    if (hdr->nodeid != PACKAGE_FILE_ID) return -ENOENT;

    uint64_t offset = req->offset;
    uint32_t size = req->size;

    // The docs on the fuse kernel interface are vague about what to
    // do when a read request extends past the end of the file.  We
    // can return a short read -- the return structure does include a
    // length field -- but in testing that caused the program using
    // the file to segfault.  (I speculate that this is due to the
    // reading program accessing it via mmap; maybe mmap dislikes when
    // you return something short of a whole page?)  To fix this we
    // zero-pad reads that extend past the end of the file so we're
    // always returning exactly as many bytes as were requested.
    // (Users of the mapped file have to know its real length anyway.)

    outhdr.len = sizeof(outhdr) + size;
    outhdr.error = 0;
    outhdr.unique = hdr->unique;
    vec[0].iov_base = &outhdr;
    vec[0].iov_len = sizeof(outhdr);

    uint32_t block = offset / fd->block_size;
    result = fetch_block(fd, block);
    if (result != 0) return result;

    // Two cases:
    //
    //   - the read request is entirely within this block.  In this
    //     case we can reply immediately.
    //
    //   - the read request goes over into the next block.  Note that
    //     since we mount the filesystem with max_read=block_size, a
    //     read can never span more than two blocks.  In this case we
    //     copy the block to extra_block and issue a fetch for the
    //     following block.

    uint32_t block_offset = offset - (block * fd->block_size);

    if (size + block_offset <= fd->block_size) {
        // First case: the read fits entirely in the first block.

        vec[1].iov_base = fd->block_data + block_offset;
        vec[1].iov_len = size;
        vec_used = 2;
    } else {
        // Second case: the read spills over into the next block.

        memcpy(fd->extra_block, fd->block_data + block_offset,
               fd->block_size - block_offset);
        vec[1].iov_base = fd->extra_block;
        vec[1].iov_len = fd->block_size - block_offset;

        result = fetch_block(fd, block+1);
        if (result != 0) return result;
        vec[2].iov_base = fd->block_data;
        vec[2].iov_len = size - vec[1].iov_len;
        vec_used = 3;
    }

    if (writev(fd->ffd, vec, vec_used) < 0) {
        printf("*** READ REPLY FAILED: %s ***\n", strerror(errno));
    }
    return NO_STATUS;
}

int run_fuse_sideload(struct provider_vtab* vtab, void* cookie,
                      uint64_t file_size, uint32_t block_size)
{
    int result;

    // If something's already mounted on our mountpoint, try to remove
    // it.  (Mostly in case of a previous abnormal exit.)
    umount2(FUSE_SIDELOAD_HOST_MOUNTPOINT, MNT_FORCE);

    if (block_size < 1024) {
        fprintf(stderr, "block size (%u) is too small\n", block_size);
        return -1;
    }
    if (block_size > (1<<22)) {   // 4 MiB
        fprintf(stderr, "block size (%u) is too large\n", block_size);
        return -1;
    }

    struct fuse_data fd;
    memset(&fd, 0, sizeof(fd));
    fd.vtab = vtab;
    fd.cookie = cookie;
    fd.file_size = file_size;
    fd.block_size = block_size;
    fd.file_blocks = (file_size == 0) ? 0 : (((file_size-1) / block_size) + 1);

    if (fd.file_blocks > (1<<18)) {
        fprintf(stderr, "file has too many blocks (%u)\n", fd.file_blocks);
        result = -1;
        goto done;
    }

    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();

    fd.curr_block = -1;
    fd.block_data = (uint8_t*)malloc(block_size);
    if (fd.block_data == NULL) {
        fprintf(stderr, "failed to allocate %d bites for block_data\n", block_size);
        result = -1;
        goto done;
    }
    fd.extra_block = (uint8_t*)malloc(block_size);
    if (fd.extra_block == NULL) {
        fprintf(stderr, "failed to allocate %d bites for extra_block\n", block_size);
        result = -1;
        goto done;
    }

    fd.ffd = open("/dev/fuse", O_RDWR);
    if (fd.ffd < 0) {
        perror("open /dev/fuse");
        result = -1;
        goto done;
    }

    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;
    }
    uint8_t request_buffer[sizeof(struct fuse_in_header) + PATH_MAX*8];
    for (;;) {
        ssize_t len = TEMP_FAILURE_RETRY(read(fd.ffd, request_buffer, sizeof(request_buffer)));
        if (len == -1) {
            perror("read request");
            if (errno == ENODEV) {
                result = -1;
                break;
            }
            continue;
        }

        if ((size_t)len < sizeof(struct fuse_in_header)) {
            fprintf(stderr, "request too short: len=%zu\n", (size_t)len);
            continue;
        }

        struct fuse_in_header* hdr = (struct fuse_in_header*) request_buffer;
        void* data = request_buffer + sizeof(struct fuse_in_header);

        result = -ENOSYS;

        switch (hdr->opcode) {
             case FUSE_INIT:
                result = handle_init(data, &fd, hdr);
                break;

             case FUSE_LOOKUP:
                result = handle_lookup(data, &fd, hdr);
                break;

            case FUSE_GETATTR:
                result = handle_getattr(data, &fd, hdr);
                break;

            case FUSE_OPEN:
                result = handle_open(data, &fd, hdr);
                break;

            case FUSE_READ:
                result = handle_read(data, &fd, hdr);
                break;

            case FUSE_FLUSH:
                result = handle_flush(data, &fd, hdr);
                break;

            case FUSE_RELEASE:
                result = handle_release(data, &fd, hdr);
                break;

            default:
                fprintf(stderr, "unknown fuse request opcode %d\n", hdr->opcode);
                break;
        }

        if (result == NO_STATUS_EXIT) {
            result = 0;
            break;
        }

        if (result != NO_STATUS) {
            struct fuse_out_header outhdr;
            outhdr.len = sizeof(outhdr);
            outhdr.error = result;
            outhdr.unique = hdr->unique;
            TEMP_FAILURE_RETRY(write(fd.ffd, &outhdr, sizeof(outhdr)));
        }
    }

  done:
    fd.vtab->close(fd.cookie);

    result = umount2(FUSE_SIDELOAD_HOST_MOUNTPOINT, MNT_DETACH);
    if (result < 0) {
        printf("fuse_sideload umount failed: %s\n", strerror(errno));
    }

    if (fd.ffd) close(fd.ffd);
    free(fd.hashes);
    free(fd.block_data);
    free(fd.extra_block);

    return result;
}

extern "C" int run_old_fuse_sideload(struct provider_vtab* vtab, void* cookie,
                      uint64_t file_size, uint32_t block_size)
{
    return run_fuse_sideload(vtab, cookie, file_size, block_size);
}
