Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 182f220d authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 10843824 from 2a405b58 to 24Q1-release

Change-Id: I8053c22790688ed35f1091d74a7c36f704fa7d54
parents 55637826 2a405b58
Loading
Loading
Loading
Loading
+3 −3
Original line number Original line Diff line number Diff line
@@ -692,7 +692,7 @@ static bool verifyKernelTraceFuncs(const char* funcs)
    while (func) {
    while (func) {
        if (!strchr(func, '*')) {
        if (!strchr(func, '*')) {
            String8 fancyFunc = String8::format("\n%s\n", func);
            String8 fancyFunc = String8::format("\n%s\n", func);
            bool found = funcList.find(fancyFunc.string(), 0) >= 0;
            bool found = funcList.find(fancyFunc.c_str(), 0) >= 0;
            if (!found || func[0] == '\0') {
            if (!found || func[0] == '\0') {
                fprintf(stderr, "error: \"%s\" is not a valid kernel function "
                fprintf(stderr, "error: \"%s\" is not a valid kernel function "
                        "to trace.\n", func);
                        "to trace.\n", func);
@@ -796,11 +796,11 @@ static bool setCategoriesEnableFromFile(const char* categories_file)
    bool ok = true;
    bool ok = true;
    while (!tokenizer->isEol()) {
    while (!tokenizer->isEol()) {
        String8 token = tokenizer->nextToken(" ");
        String8 token = tokenizer->nextToken(" ");
        if (token.isEmpty()) {
        if (token.empty()) {
            tokenizer->skipDelimiters(" ");
            tokenizer->skipDelimiters(" ");
            continue;
            continue;
        }
        }
        ok &= setCategoryEnable(token.string());
        ok &= setCategoryEnable(token.c_str());
    }
    }
    delete tokenizer;
    delete tokenizer;
    return ok;
    return ok;
+3 −0
Original line number Original line Diff line number Diff line
@@ -27,6 +27,9 @@ cc_library_static {
        "libselinux",
        "libselinux",
        "libbinder",
        "libbinder",
    ],
    ],
    whole_static_libs: [
        "libc++fs",
    ],


    cflags: [
    cflags: [
        "-Wall",
        "-Wall",
+11 −12
Original line number Original line Diff line number Diff line
@@ -27,6 +27,7 @@
#include <utils/Mutex.h>
#include <utils/Mutex.h>
#include <utils/Vector.h>
#include <utils/Vector.h>


#include <filesystem>
#include <getopt.h>
#include <getopt.h>
#include <stdlib.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdio.h>
@@ -69,16 +70,14 @@ public:
    virtual int openFile(const String16& path, const String16& seLinuxContext,
    virtual int openFile(const String16& path, const String16& seLinuxContext,
            const String16& mode) {
            const String16& mode) {
        String8 path8(path);
        String8 path8(path);
        char cwd[256];
        auto fullPath = std::filesystem::current_path();
        getcwd(cwd, 256);
        fullPath /= path8.c_str();
        String8 fullPath(cwd);
        fullPath.appendPath(path8);
        if (!mActive) {
        if (!mActive) {
            mErrorLog << "Open attempt after active for: " << fullPath << endl;
            mErrorLog << "Open attempt after active for: " << fullPath << endl;
            return -EPERM;
            return -EPERM;
        }
        }
#if DEBUG
#if DEBUG
        ALOGD("openFile: %s, full=%s", path8.string(), fullPath.string());
        ALOGD("openFile: %s, full=%s", path8.c_str(), fullPath.c_str());
#endif
#endif
        int flags = 0;
        int flags = 0;
        bool checkRead = false;
        bool checkRead = false;
@@ -96,10 +95,10 @@ public:
            flags = O_RDWR;
            flags = O_RDWR;
            checkRead = checkWrite = true;
            checkRead = checkWrite = true;
        } else {
        } else {
            mErrorLog << "Invalid mode requested: " << mode.string() << endl;
            mErrorLog << "Invalid mode requested: " << mode.c_str() << endl;
            return -EINVAL;
            return -EINVAL;
        }
        }
        int fd = open(fullPath.string(), flags, S_IRWXU|S_IRWXG);
        int fd = open(fullPath.c_str(), flags, S_IRWXU|S_IRWXG);
#if DEBUG
#if DEBUG
        ALOGD("openFile: fd=%d", fd);
        ALOGD("openFile: fd=%d", fd);
#endif
#endif
@@ -109,29 +108,29 @@ public:
        if (is_selinux_enabled() && seLinuxContext.size() > 0) {
        if (is_selinux_enabled() && seLinuxContext.size() > 0) {
            String8 seLinuxContext8(seLinuxContext);
            String8 seLinuxContext8(seLinuxContext);
            char* tmp = nullptr;
            char* tmp = nullptr;
            getfilecon(fullPath.string(), &tmp);
            getfilecon(fullPath.c_str(), &tmp);
            Unique_SecurityContext context(tmp);
            Unique_SecurityContext context(tmp);
            if (checkWrite) {
            if (checkWrite) {
                int accessGranted = selinux_check_access(seLinuxContext8.string(), context.get(),
                int accessGranted = selinux_check_access(seLinuxContext8.c_str(), context.get(),
                        "file", "write", nullptr);
                        "file", "write", nullptr);
                if (accessGranted != 0) {
                if (accessGranted != 0) {
#if DEBUG
#if DEBUG
                    ALOGD("openFile: failed selinux write check!");
                    ALOGD("openFile: failed selinux write check!");
#endif
#endif
                    close(fd);
                    close(fd);
                    mErrorLog << "System server has no access to write file context " << context.get() << " (from path " << fullPath.string() << ", context " << seLinuxContext8.string() << ")" << endl;
                    mErrorLog << "System server has no access to write file context " << context.get() << " (from path " << fullPath.c_str() << ", context " << seLinuxContext8.c_str() << ")" << endl;
                    return -EPERM;
                    return -EPERM;
                }
                }
            }
            }
            if (checkRead) {
            if (checkRead) {
                int accessGranted = selinux_check_access(seLinuxContext8.string(), context.get(),
                int accessGranted = selinux_check_access(seLinuxContext8.c_str(), context.get(),
                        "file", "read", nullptr);
                        "file", "read", nullptr);
                if (accessGranted != 0) {
                if (accessGranted != 0) {
#if DEBUG
#if DEBUG
                    ALOGD("openFile: failed selinux read check!");
                    ALOGD("openFile: failed selinux read check!");
#endif
#endif
                    close(fd);
                    close(fd);
                    mErrorLog << "System server has no access to read file context " << context.get() << " (from path " << fullPath.string() << ", context " << seLinuxContext8.string() << ")" << endl;
                    mErrorLog << "System server has no access to read file context " << context.get() << " (from path " << fullPath.c_str() << ", context " << seLinuxContext8.c_str() << ")" << endl;
                    return -EPERM;
                    return -EPERM;
                }
                }
            }
            }
+2 −2
Original line number Original line Diff line number Diff line
@@ -543,7 +543,7 @@ status_t Dumpsys::writeDump(int fd, const String16& serviceName, std::chrono::mi


    if ((status == TIMED_OUT) && (!asProto)) {
    if ((status == TIMED_OUT) && (!asProto)) {
        std::string msg = StringPrintf("\n*** SERVICE '%s' DUMP TIMEOUT (%llums) EXPIRED ***\n\n",
        std::string msg = StringPrintf("\n*** SERVICE '%s' DUMP TIMEOUT (%llums) EXPIRED ***\n\n",
                                       String8(serviceName).string(), timeout.count());
                                       String8(serviceName).c_str(), timeout.count());
        WriteStringToFd(msg, fd);
        WriteStringToFd(msg, fd);
    }
    }


@@ -562,6 +562,6 @@ void Dumpsys::writeDumpFooter(int fd, const String16& serviceName,
    oss << std::put_time(&finish_tm, "%Y-%m-%d %H:%M:%S");
    oss << std::put_time(&finish_tm, "%Y-%m-%d %H:%M:%S");
    std::string msg =
    std::string msg =
        StringPrintf("--------- %.3fs was the duration of dumpsys %s, ending at: %s\n",
        StringPrintf("--------- %.3fs was the duration of dumpsys %s, ending at: %s\n",
                     elapsedDuration.count(), String8(serviceName).string(), oss.str().c_str());
                     elapsedDuration.count(), String8(serviceName).c_str(), oss.str().c_str());
    WriteStringToFd(msg, fd);
    WriteStringToFd(msg, fd);
}
}
+160 −15
Original line number Original line Diff line number Diff line
@@ -19,6 +19,7 @@
#include <errno.h>
#include <errno.h>
#include <fts.h>
#include <fts.h>
#include <inttypes.h>
#include <inttypes.h>
#include <linux/fsverity.h>
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
#include <string.h>
#include <string.h>
@@ -51,6 +52,7 @@
#include <android-base/unique_fd.h>
#include <android-base/unique_fd.h>
#include <cutils/ashmem.h>
#include <cutils/ashmem.h>
#include <cutils/fs.h>
#include <cutils/fs.h>
#include <cutils/misc.h>
#include <cutils/properties.h>
#include <cutils/properties.h>
#include <cutils/sched_policy.h>
#include <cutils/sched_policy.h>
#include <linux/quota.h>
#include <linux/quota.h>
@@ -84,6 +86,8 @@
using android::base::ParseUint;
using android::base::ParseUint;
using android::base::Split;
using android::base::Split;
using android::base::StringPrintf;
using android::base::StringPrintf;
using android::base::unique_fd;
using android::os::ParcelFileDescriptor;
using std::endl;
using std::endl;


namespace android {
namespace android {
@@ -229,6 +233,14 @@ binder::Status checkArgumentFileName(const std::string& path) {
    return ok();
    return ok();
}
}


binder::Status checkUidInAppRange(int32_t appUid) {
    if (FIRST_APPLICATION_UID <= appUid && appUid <= LAST_APPLICATION_UID) {
        return ok();
    }
    return exception(binder::Status::EX_ILLEGAL_ARGUMENT,
                     StringPrintf("UID %d is outside of the range", appUid));
}

#define ENFORCE_UID(uid) {                                  \
#define ENFORCE_UID(uid) {                                  \
    binder::Status status = checkUid((uid));                \
    binder::Status status = checkUid((uid));                \
    if (!status.isOk()) {                                   \
    if (!status.isOk()) {                                   \
@@ -240,12 +252,18 @@ binder::Status checkArgumentFileName(const std::string& path) {
// in UserHandle.java and carry specific meanings that may not be handled by certain APIs here.
// in UserHandle.java and carry specific meanings that may not be handled by certain APIs here.
#define ENFORCE_VALID_USER(userId)                                                               \
#define ENFORCE_VALID_USER(userId)                                                               \
    {                                                                                            \
    {                                                                                            \
        if (static_cast<uid_t>(std::abs(userId)) >=                    \
        if (static_cast<uid_t>(userId) >= std::numeric_limits<uid_t>::max() / AID_USER_OFFSET) { \
            std::numeric_limits<uid_t>::max() / AID_USER_OFFSET) {     \
            return error("userId invalid: " + std::to_string(userId));                           \
            return error("userId invalid: " + std::to_string(userId));                           \
        }                                                                                        \
        }                                                                                        \
    }
    }


#define ENFORCE_VALID_USER_OR_NULL(userId)             \
    {                                                  \
        if (static_cast<uid_t>(userId) != USER_NULL) { \
            ENFORCE_VALID_USER(userId);                \
        }                                              \
    }

#define CHECK_ARGUMENT_UUID(uuid) {                         \
#define CHECK_ARGUMENT_UUID(uuid) {                         \
    binder::Status status = checkArgumentUuid((uuid));      \
    binder::Status status = checkArgumentUuid((uuid));      \
    if (!status.isOk()) {                                   \
    if (!status.isOk()) {                                   \
@@ -283,6 +301,14 @@ binder::Status checkArgumentFileName(const std::string& path) {
        }                                                      \
        }                                                      \
    }
    }


#define CHECK_ARGUMENT_UID_IN_APP_RANGE(uid)               \
    {                                                      \
        binder::Status status = checkUidInAppRange((uid)); \
        if (!status.isOk()) {                              \
            return status;                                 \
        }                                                  \
    }

#ifdef GRANULAR_LOCKS
#ifdef GRANULAR_LOCKS


/**
/**
@@ -383,6 +409,33 @@ using PackageLockGuard = std::lock_guard<PackageLock>;


}  // namespace
}  // namespace


binder::Status InstalldNativeService::FsveritySetupAuthToken::authenticate(
        const ParcelFileDescriptor& authFd, int32_t appUid, int32_t userId) {
    int open_flags = fcntl(authFd.get(), F_GETFL);
    if (open_flags < 0) {
        return exception(binder::Status::EX_SERVICE_SPECIFIC, "fcntl failed");
    }
    if ((open_flags & O_ACCMODE) != O_WRONLY && (open_flags & O_ACCMODE) != O_RDWR) {
        return exception(binder::Status::EX_SECURITY, "Received FD with unexpected open flag");
    }
    if (fstat(authFd.get(), &this->mStatFromAuthFd) < 0) {
        return exception(binder::Status::EX_SERVICE_SPECIFIC, "fstat failed");
    }
    if (!S_ISREG(this->mStatFromAuthFd.st_mode)) {
        return exception(binder::Status::EX_SECURITY, "Not a regular file");
    }
    // Don't accept a file owned by a different app.
    uid_t uid = multiuser_get_uid(userId, appUid);
    if (this->mStatFromAuthFd.st_uid != uid) {
        return exception(binder::Status::EX_SERVICE_SPECIFIC, "File not owned by appUid");
    }
    return ok();
}

bool InstalldNativeService::FsveritySetupAuthToken::isSameStat(const struct stat& st) const {
    return memcmp(&st, &mStatFromAuthFd, sizeof(st)) == 0;
}

status_t InstalldNativeService::start() {
status_t InstalldNativeService::start() {
    IPCThreadState::self()->disableBackgroundScheduling(true);
    IPCThreadState::self()->disableBackgroundScheduling(true);
    status_t ret = BinderService<InstalldNativeService>::publish();
    status_t ret = BinderService<InstalldNativeService>::publish();
@@ -704,7 +757,7 @@ static binder::Status createAppDataDirs(const std::string& path, int32_t uid, in
binder::Status InstalldNativeService::createAppDataLocked(
binder::Status InstalldNativeService::createAppDataLocked(
        const std::optional<std::string>& uuid, const std::string& packageName, int32_t userId,
        const std::optional<std::string>& uuid, const std::string& packageName, int32_t userId,
        int32_t flags, int32_t appId, int32_t previousAppId, const std::string& seInfo,
        int32_t flags, int32_t appId, int32_t previousAppId, const std::string& seInfo,
        int32_t targetSdkVersion, int64_t* _aidl_return) {
        int32_t targetSdkVersion, int64_t* ceDataInode, int64_t* deDataInode) {
    ENFORCE_UID(AID_SYSTEM);
    ENFORCE_UID(AID_SYSTEM);
    ENFORCE_VALID_USER(userId);
    ENFORCE_VALID_USER(userId);
    CHECK_ARGUMENT_UUID(uuid);
    CHECK_ARGUMENT_UUID(uuid);
@@ -714,7 +767,8 @@ binder::Status InstalldNativeService::createAppDataLocked(
    const char* pkgname = packageName.c_str();
    const char* pkgname = packageName.c_str();


    // Assume invalid inode unless filled in below
    // Assume invalid inode unless filled in below
    if (_aidl_return != nullptr) *_aidl_return = -1;
    if (ceDataInode != nullptr) *ceDataInode = -1;
    if (deDataInode != nullptr) *deDataInode = -1;


    int32_t uid = multiuser_get_uid(userId, appId);
    int32_t uid = multiuser_get_uid(userId, appId);


@@ -752,12 +806,12 @@ binder::Status InstalldNativeService::createAppDataLocked(


        // And return the CE inode of the top-level data directory so we can
        // And return the CE inode of the top-level data directory so we can
        // clear contents while CE storage is locked
        // clear contents while CE storage is locked
        if (_aidl_return != nullptr) {
        if (ceDataInode != nullptr) {
            ino_t result;
            ino_t result;
            if (get_path_inode(path, &result) != 0) {
            if (get_path_inode(path, &result) != 0) {
                return error("Failed to get_path_inode for " + path);
                return error("Failed to get_path_inode for " + path);
            }
            }
            *_aidl_return = static_cast<uint64_t>(result);
            *ceDataInode = static_cast<uint64_t>(result);
        }
        }
    }
    }
    if (flags & FLAG_STORAGE_DE) {
    if (flags & FLAG_STORAGE_DE) {
@@ -776,6 +830,14 @@ binder::Status InstalldNativeService::createAppDataLocked(
        if (!prepare_app_profile_dir(packageName, appId, userId)) {
        if (!prepare_app_profile_dir(packageName, appId, userId)) {
            return error("Failed to prepare profiles for " + packageName);
            return error("Failed to prepare profiles for " + packageName);
        }
        }

        if (deDataInode != nullptr) {
            ino_t result;
            if (get_path_inode(path, &result) != 0) {
                return error("Failed to get_path_inode for " + path);
            }
            *deDataInode = static_cast<uint64_t>(result);
        }
    }
    }


    if (flags & FLAG_STORAGE_SDK) {
    if (flags & FLAG_STORAGE_SDK) {
@@ -839,14 +901,14 @@ binder::Status InstalldNativeService::createSdkSandboxDataPackageDirectory(
binder::Status InstalldNativeService::createAppData(
binder::Status InstalldNativeService::createAppData(
        const std::optional<std::string>& uuid, const std::string& packageName, int32_t userId,
        const std::optional<std::string>& uuid, const std::string& packageName, int32_t userId,
        int32_t flags, int32_t appId, int32_t previousAppId, const std::string& seInfo,
        int32_t flags, int32_t appId, int32_t previousAppId, const std::string& seInfo,
        int32_t targetSdkVersion, int64_t* _aidl_return) {
        int32_t targetSdkVersion, int64_t* ceDataInode, int64_t* deDataInode) {
    ENFORCE_UID(AID_SYSTEM);
    ENFORCE_UID(AID_SYSTEM);
    ENFORCE_VALID_USER(userId);
    ENFORCE_VALID_USER(userId);
    CHECK_ARGUMENT_UUID(uuid);
    CHECK_ARGUMENT_UUID(uuid);
    CHECK_ARGUMENT_PACKAGE_NAME(packageName);
    CHECK_ARGUMENT_PACKAGE_NAME(packageName);
    LOCK_PACKAGE_USER();
    LOCK_PACKAGE_USER();
    return createAppDataLocked(uuid, packageName, userId, flags, appId, previousAppId, seInfo,
    return createAppDataLocked(uuid, packageName, userId, flags, appId, previousAppId, seInfo,
                               targetSdkVersion, _aidl_return);
                               targetSdkVersion, ceDataInode, deDataInode);
}
}


binder::Status InstalldNativeService::createAppData(
binder::Status InstalldNativeService::createAppData(
@@ -857,9 +919,12 @@ binder::Status InstalldNativeService::createAppData(
    // Locking is performed depeer in the callstack.
    // Locking is performed depeer in the callstack.


    int64_t ceDataInode = -1;
    int64_t ceDataInode = -1;
    int64_t deDataInode = -1;
    auto status = createAppData(args.uuid, args.packageName, args.userId, args.flags, args.appId,
    auto status = createAppData(args.uuid, args.packageName, args.userId, args.flags, args.appId,
            args.previousAppId, args.seInfo, args.targetSdkVersion, &ceDataInode);
                                args.previousAppId, args.seInfo, args.targetSdkVersion,
                                &ceDataInode, &deDataInode);
    _aidl_return->ceDataInode = ceDataInode;
    _aidl_return->ceDataInode = ceDataInode;
    _aidl_return->deDataInode = deDataInode;
    _aidl_return->exceptionCode = status.exceptionCode();
    _aidl_return->exceptionCode = status.exceptionCode();
    _aidl_return->exceptionMessage = status.exceptionMessage();
    _aidl_return->exceptionMessage = status.exceptionMessage();
    return ok();
    return ok();
@@ -1786,7 +1851,8 @@ binder::Status InstalldNativeService::moveCompleteApp(const std::optional<std::s
        }
        }


        if (!createAppDataLocked(toUuid, packageName, userId, FLAG_STORAGE_CE | FLAG_STORAGE_DE,
        if (!createAppDataLocked(toUuid, packageName, userId, FLAG_STORAGE_CE | FLAG_STORAGE_DE,
                                 appId, /* previousAppId */ -1, seInfo, targetSdkVersion, nullptr)
                                 appId, /* previousAppId */ -1, seInfo, targetSdkVersion, nullptr,
                                 nullptr)
                     .isOk()) {
                     .isOk()) {
            res = error("Failed to create package target");
            res = error("Failed to create package target");
            goto fail;
            goto fail;
@@ -3794,7 +3860,7 @@ binder::Status InstalldNativeService::prepareAppProfile(const std::string& packa
        int32_t userId, int32_t appId, const std::string& profileName, const std::string& codePath,
        int32_t userId, int32_t appId, const std::string& profileName, const std::string& codePath,
        const std::optional<std::string>& dexMetadata, bool* _aidl_return) {
        const std::optional<std::string>& dexMetadata, bool* _aidl_return) {
    ENFORCE_UID(AID_SYSTEM);
    ENFORCE_UID(AID_SYSTEM);
    ENFORCE_VALID_USER(userId);
    ENFORCE_VALID_USER_OR_NULL(userId);
    CHECK_ARGUMENT_PACKAGE_NAME(packageName);
    CHECK_ARGUMENT_PACKAGE_NAME(packageName);
    CHECK_ARGUMENT_PATH(codePath);
    CHECK_ARGUMENT_PATH(codePath);
    LOCK_PACKAGE_USER();
    LOCK_PACKAGE_USER();
@@ -3857,5 +3923,84 @@ binder::Status InstalldNativeService::getOdexVisibility(
    return *_aidl_return == -1 ? error() : ok();
    return *_aidl_return == -1 ? error() : ok();
}
}


// Creates an auth token to be used in enableFsverity. This token is really to store a proof that
// the caller can write to a file, represented by the authFd. Effectively, system_server as the
// attacker-in-the-middle cannot enable fs-verity on arbitrary app files. If the FD is not writable,
// return null.
//
// appUid and userId are passed for additional ownership check, such that one app can not be
// authenticated for another app's file. These parameters are assumed trusted for this purpose of
// consistency check.
//
// Notably, creating the token allows us to manage the writable FD easily during enableFsverity.
// Since enabling fs-verity to a file requires no outstanding writable FD, passing the authFd to the
// server allows the server to hold the only reference (as long as the client app doesn't).
binder::Status InstalldNativeService::createFsveritySetupAuthToken(
        const ParcelFileDescriptor& authFd, int32_t appUid, int32_t userId,
        sp<IFsveritySetupAuthToken>* _aidl_return) {
    CHECK_ARGUMENT_UID_IN_APP_RANGE(appUid);
    ENFORCE_VALID_USER(userId);

    auto token = sp<FsveritySetupAuthToken>::make();
    binder::Status status = token->authenticate(authFd, appUid, userId);
    if (!status.isOk()) {
        return status;
    }
    *_aidl_return = token;
    return ok();
}

// Enables fs-verity for filePath, which must be an absolute path and the same inode as in the auth
// token previously returned from createFsveritySetupAuthToken, and owned by the app uid. As
// installd is more privileged than its client / system server, we attempt to limit what a
// (compromised) client can do.
//
// The reason for this app request to go through installd is to avoid exposing a risky area (PKCS#7
// signature verification) in the kernel to the app as an attack surface (it can't be system server
// because it can't override DAC and manipulate app files). Note that we should be able to drop
// these hops and simply the app calls the ioctl, once all upgrading devices run with a kernel
// without fs-verity built-in signature (https://r.android.com/2650402).
binder::Status InstalldNativeService::enableFsverity(const sp<IFsveritySetupAuthToken>& authToken,
                                                     const std::string& filePath,
                                                     const std::string& packageName,
                                                     int32_t* _aidl_return) {
    ENFORCE_UID(AID_SYSTEM);
    CHECK_ARGUMENT_PATH(filePath);
    CHECK_ARGUMENT_PACKAGE_NAME(packageName);
    LOCK_PACKAGE();
    if (authToken == nullptr) {
        return exception(binder::Status::EX_ILLEGAL_ARGUMENT, "Received a null auth token");
    }

    // Authenticate to check the targeting file is the same inode as the authFd.
    sp<IBinder> authTokenBinder = IInterface::asBinder(authToken)->localBinder();
    if (authTokenBinder == nullptr) {
        return exception(binder::Status::EX_SECURITY, "Received a non-local auth token");
    }
    auto authTokenInstance = sp<FsveritySetupAuthToken>::cast(authTokenBinder);
    unique_fd rfd(open(filePath.c_str(), O_RDONLY | O_CLOEXEC | O_NOFOLLOW));
    struct stat stFromPath;
    if (fstat(rfd.get(), &stFromPath) < 0) {
        *_aidl_return = errno;
        return ok();
    }
    if (!authTokenInstance->isSameStat(stFromPath)) {
        LOG(DEBUG) << "FD authentication failed";
        *_aidl_return = EPERM;
        return ok();
    }

    fsverity_enable_arg arg = {};
    arg.version = 1;
    arg.hash_algorithm = FS_VERITY_HASH_ALG_SHA256;
    arg.block_size = 4096;
    if (ioctl(rfd.get(), FS_IOC_ENABLE_VERITY, &arg) < 0) {
        *_aidl_return = errno;
    } else {
        *_aidl_return = 0;
    }
    return ok();
}

}  // namespace installd
}  // namespace installd
}  // namespace android
}  // namespace android
Loading