// Grants the current process the given root capability. void SetCap(cap_flag_t flag, cap_value_t value) {
ScopedCap cap(cap_get_proc());
CHECK_NE(cap.Get(), nullptr);
cap_value_t caps[]{value};
CHECK_EQ(cap_set_flag(cap.Get(), flag, /*ncap=*/1, caps, CAP_SET), 0);
CHECK_EQ(cap_set_proc(cap.Get()), 0);
}
// Returns true if the given process has the given root capability. bool GetCap(pid_t pid, cap_flag_t flag, cap_value_t value) {
ScopedCap cap(cap_get_pid(pid));
CHECK_NE(cap.Get(), nullptr);
cap_flag_value_t flag_value;
CHECK_EQ(cap_get_flag(cap.Get(), value, flag, &flag_value), 0); return flag_value == CAP_SET;
}
class ArtExecTest : public ::testing::Test { protected: void SetUp() override {
::testing::Test::SetUp(); if (!kIsTargetAndroid) {
GTEST_SKIP() << "art_exec is for device only";
} if (getuid() != kRoot) {
GTEST_SKIP() << "art_exec requires root";
}
art_exec_bin_ = GetArtBin("art_exec");
}
std::string art_exec_bin_;
};
TEST_F(ArtExecTest, Command) {
std::string error_msg; int ret = ExecAndReturnCode({art_exec_bin_, "--", GetBin("sh"), "-c", "exit 123"}, &error_msg);
ASSERT_EQ(ret, 123) << error_msg;
}
TEST_F(ArtExecTest, SetTaskProfiles) { // The condition is always true because ArtExecTest is run on device only. #ifdef ART_TARGET_ANDROID if (!android::modules::sdklevel::IsAtLeastU()) {
GTEST_SKIP() << "This test depends on a libartpalette API that is only available on U+";
} #endif
TEST_F(ArtExecTest, DropCapabilities) { // Switch to a non-root user, but still keep the CAP_FOWNER capability available and inheritable. // The order of the following calls matters.
CHECK_EQ(cap_setuid(kNobody), 0);
SetCap(CAP_INHERITABLE, CAP_FOWNER);
SetCap(CAP_EFFECTIVE, CAP_FOWNER);
ASSERT_EQ(cap_set_ambient(CAP_FOWNER, CAP_SET), 0);
// Make sure the test is set up correctly (i.e., the child process should normally have the // inherited root capability: CAP_FOWNER).
{
std::vector<std::string> args{art_exec_bin_, "--", GetBin("true")}; auto [pid, scope_guard] = ScopedExec(args, /*wait=*/true);
ASSERT_TRUE(GetCap(pid, CAP_EFFECTIVE, CAP_FOWNER));
}
// `file1` should be closed, while the other two should be open. There's a blank line at the end.
EXPECT_THAT(Split(open_fds, "\n"), ElementsAre(Not("/dev/zero"), "/dev/zero", "/dev/zero", ""));
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.