Add test for ambient caps

PR_CAP_AMBIENT landed in 4.3 and has been backported to earlier kernels
in kernel/common.

Test: bionic-unit-test --gtest_filter=sys_prctl.pr_cap_ambient
Change-Id: I632f6316ef1a4eb636d2bf7e07d541e400567ef4
Signed-off-by: Greg Hackmann <ghackmann@google.com>
This commit is contained in:
Greg Hackmann 2016-12-06 15:17:59 -08:00
parent b2d36b4ec7
commit ba1f77d650
1 changed files with 50 additions and 0 deletions

View File

@ -15,7 +15,9 @@
*/
#include <inttypes.h>
#include <limits.h>
#include <stdio.h>
#include <sys/capability.h>
#include <sys/mman.h>
#include <sys/prctl.h>
#include <unistd.h>
@ -64,3 +66,51 @@ TEST(sys_prctl, bug_20017123) {
GTEST_LOG_(INFO) << "This test does nothing as it tests an Android specific kernel feature.";
#endif
}
TEST(sys_prctl, pr_cap_ambient) {
// PR_CAP_AMBIENT was introduced in v4.3. Android devices should always
// have a backport, but we can't guarantee it's available on the host.
#if defined(__ANDROID__) || defined(PR_CAP_AMBIENT)
const std::string caps_sha =
"https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/"
"?id=58319057b7847667f0c9585b9de0e8932b0fdb08";
const std::string caps_typo_sha =
"https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/"
"?id=b7f76ea2ef6739ee484a165ffbac98deb855d3d3";
auto err = prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_CLEAR_ALL, 0, 0, 0);
EXPECT_EQ(0, err);
// EINVAL -> unrecognized prctl option
ASSERT_NE(EINVAL, errno) << "kernel missing required commits:\n"
<< caps_sha << "\n"
<< caps_typo_sha << "\n";
// Unprivileged processes shouldn't be able to raise CAP_SYS_ADMIN,
// but they can check or lower it
err = prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, CAP_SYS_ADMIN, 0, 0);
EXPECT_EQ(-1, err);
EXPECT_EQ(EPERM, errno);
err = prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_SYS_ADMIN, 0, 0);
EXPECT_EQ(0, err);
err = prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_LOWER, CAP_SYS_ADMIN, 0, 0);
EXPECT_EQ(0, err);
// ULONG_MAX isn't a legal cap
err = prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, ULONG_MAX, 0, 0);
EXPECT_EQ(-1, err);
EXPECT_EQ(EINVAL, errno);
err = prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, ULONG_MAX, 0, 0);
EXPECT_EQ(-1, err);
EXPECT_EQ(EINVAL, errno);
err = prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_LOWER, ULONG_MAX, 0, 0);
EXPECT_EQ(-1, err);
EXPECT_EQ(EINVAL, errno);
#else
GTEST_LOG_(INFO)
<< "Skipping test that requires host support for PR_CAP_AMBIENT.";
#endif
}