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

Commit 4c2a2ba8 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "Added system property (dumpstate.unroot)."

parents d08b18d1 4b392be4
Loading
Loading
Loading
Loading
+14 −3
Original line number Diff line number Diff line
@@ -101,13 +101,16 @@ CommandOptions::CommandOptionsBuilder& CommandOptions::CommandOptionsBuilder::Al
}

CommandOptions::CommandOptionsBuilder& CommandOptions::CommandOptionsBuilder::AsRoot() {
    if (!PropertiesHelper::IsUnroot()) {
        values.account_mode_ = SU_ROOT;
    }
    return *this;
}

CommandOptions::CommandOptionsBuilder& CommandOptions::CommandOptionsBuilder::AsRootIfAvailable() {
    if (!PropertiesHelper::IsUserBuild())
        values.account_mode_ = SU_ROOT;
    if (!PropertiesHelper::IsUserBuild()) {
        return AsRoot();
    }
    return *this;
}

@@ -176,6 +179,7 @@ CommandOptions::CommandOptionsBuilder CommandOptions::WithTimeoutInMs(int64_t ti

std::string PropertiesHelper::build_type_ = "";
int PropertiesHelper::dry_run_ = -1;
int PropertiesHelper::unroot_ = -1;

bool PropertiesHelper::IsUserBuild() {
    if (build_type_.empty()) {
@@ -191,6 +195,13 @@ bool PropertiesHelper::IsDryRun() {
    return dry_run_ == 1;
}

bool PropertiesHelper::IsUnroot() {
    if (unroot_ == -1) {
        unroot_ = android::base::GetBoolProperty("dumpstate.unroot", false) ? 1 : 0;
    }
    return unroot_ == 1;
}

int DumpFileToFd(int out_fd, const std::string& title, const std::string& path) {
    android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(path.c_str(), O_RDONLY | O_NONBLOCK | O_CLOEXEC)));
    if (fd.get() < 0) {
+17 −2
Original line number Diff line number Diff line
@@ -97,9 +97,16 @@ class CommandOptions {
      public:
        /* Sets the command to always run, even on `dry-run` mode. */
        CommandOptionsBuilder& Always();
        /* Sets the command's PrivilegeMode as `SU_ROOT` */
        /*
         * Sets the command's PrivilegeMode as `SU_ROOT` unless overridden by system property
         * 'dumpstate.unroot'.
         */
        CommandOptionsBuilder& AsRoot();
        /* If !IsUserBuild(), sets the command's PrivilegeMode as `SU_ROOT` */
        /*
         * Runs AsRoot() on userdebug builds. No-op on user builds since 'su' is
         * not available. This is used for commands that return some useful information even
         * when run as shell.
         */
        CommandOptionsBuilder& AsRootIfAvailable();
        /* Sets the command's PrivilegeMode as `DROP_ROOT` */
        CommandOptionsBuilder& DropRoot();
@@ -162,9 +169,17 @@ class PropertiesHelper {
     */
    static bool IsDryRun();

    /**
     * Checks whether root availability should be overridden.
     *
     * Useful to verify how dumpstate would work in a device with an user build.
     */
    static bool IsUnroot();

  private:
    static std::string build_type_;
    static int dry_run_;
    static int unroot_;
};

/*
+6 −0
Original line number Diff line number Diff line
@@ -52,6 +52,12 @@ mmm -j frameworks/native/cmds/dumpstate/ && adb push ${OUT}/data/nativetest/dump
adb shell setprop dumpstate.dry_run true
```

## To emulate a device with user build

```
adb shell setprop dumpstate.unroot true
```

## To change the `dumpstate` version

```
+56 −0
Original line number Diff line number Diff line
@@ -85,6 +85,10 @@ class DumpstateBaseTest : public Test {
        PropertiesHelper::build_type_ = build_type;
    }

    void SetUnroot(bool unroot) const {
        PropertiesHelper::unroot_ = unroot;
    }

    bool IsStandalone() const {
        return calls_ == 1;
    }
@@ -650,6 +654,32 @@ TEST_F(DumpstateTest, RunCommandAsRootNonUserBuild) {
    EXPECT_THAT(err, StrEq("stderr\n"));
}

TEST_F(DumpstateTest, RunCommandAsRootNonUserBuild_withUnroot) {
    if (!IsStandalone()) {
        // TODO: temporarily disabled because it might cause other tests to fail after dropping
        // to Shell - need to refactor tests to avoid this problem)
        MYLOGE(
            "Skipping DumpstateTest.RunCommandAsRootNonUserBuild_withUnroot() "
            "on test suite\n")
        return;
    }
    if (PropertiesHelper::IsUserBuild()) {
        ALOGI("Skipping RunCommandAsRootNonUserBuild_withUnroot on user builds\n");
        return;
    }

    // Same test as above, but with unroot property set, which will override su availability.
    SetUnroot(true);
    DropRoot();

    EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
                            CommandOptions::WithTimeout(1).AsRoot().Build()));

    // AsRoot is ineffective.
    EXPECT_THAT(out, StrEq("2000\nstdout\n"));
    EXPECT_THAT(err, StrEq("drop_root_user(): already running as Shell\nstderr\n"));
}

TEST_F(DumpstateTest, RunCommandAsRootIfAvailableOnUserBuild) {
    if (!IsStandalone()) {
        // TODO: temporarily disabled because it might cause other tests to fail after dropping
@@ -692,6 +722,32 @@ TEST_F(DumpstateTest, RunCommandAsRootIfAvailableOnDebugBuild) {
    EXPECT_THAT(err, StrEq("stderr\n"));
}

TEST_F(DumpstateTest, RunCommandAsRootIfAvailableOnDebugBuild_withUnroot) {
    if (!IsStandalone()) {
        // TODO: temporarily disabled because it might cause other tests to fail after dropping
        // to Shell - need to refactor tests to avoid this problem)
        MYLOGE(
            "Skipping DumpstateTest.RunCommandAsRootIfAvailableOnDebugBuild_withUnroot() "
            "on test suite\n")
        return;
    }
    if (PropertiesHelper::IsUserBuild()) {
        ALOGI("Skipping RunCommandAsRootIfAvailableOnDebugBuild_withUnroot on user builds\n");
        return;
    }
    // Same test as above, but with unroot property set, which will override su availability.
    SetUnroot(true);

    DropRoot();

    EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
                            CommandOptions::WithTimeout(1).AsRootIfAvailable().Build()));

    // It's a userdebug build, so "su root" should be available, but unroot=true overrides it.
    EXPECT_THAT(out, StrEq("2000\nstdout\n"));
    EXPECT_THAT(err, StrEq("stderr\n"));
}

TEST_F(DumpstateTest, DumpFileNotFoundNoTitle) {
    EXPECT_EQ(-1, DumpFile("", "/I/cant/believe/I/exist"));
    EXPECT_THAT(out,