112bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak#include <errno.h> 212bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak#include "config.h" 312bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak#if HAVE_SYS_CAPABILITY_H 4354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#include <linux/types.h> 5354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#include <sys/capability.h> 612bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak#endif 712bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak#include <sys/prctl.h> 8e8530df4da095b0ea36a9ff8118ab5ce906b3e84Garrett Cooper#include "test.h" 912bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak 104590c297cff4643bba8c730a62ce71889a22ca92Cyril Hrubis#ifndef SECBIT_KEEP_CAPS 11354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#define SECBIT_KEEP_CAPS (1<<4) 124590c297cff4643bba8c730a62ce71889a22ca92Cyril Hrubis#endif 134590c297cff4643bba8c730a62ce71889a22ca92Cyril Hrubis 1412bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak/* Tests: 1512bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak 1. drop capabilities at setuid if KEEPCAPS is not set and 1612bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak new user is nonroot 1712bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak 2. keep capabilities if set and new user is nonroot 1812bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak a. do with prctl(PR_SET_KEEPCAPS) 1912bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak (call this test 2) 2012bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak b. do with prctl(PR_SET_SECUREBITS, SECURE_KEEP_CAPS) 2112bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak (call this test 3) 2212bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak TODO: test that exec clears KEEPCAPS 2312bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak (just create a simple executable that checks PR_GET_KEEPCAPS 2412bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak results, and execute that as test 4 after doing PR_SET_KEEPCAPS). 2512bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak TODO: all of the other securebits tests. 2612bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak */ 2712bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak 2812bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modakchar *TCID = "keepcaps"; 29bba458c56d16589f0bcbfe299709f6c3929e7e2eCyril Hrubisint TST_TOTAL = 1; 3012bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak 314c35f5b67afa11dabd902e5e4d85d6416e22fa3bZeng Linggang#if (HAVE_LINUX_SECUREBITS_H && HAVE_LIBCAP) 324c35f5b67afa11dabd902e5e4d85d6416e22fa3bZeng Linggang#include <linux/securebits.h> 334c35f5b67afa11dabd902e5e4d85d6416e22fa3bZeng Linggang 3412bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modakstatic int eff_caps_empty(cap_t c) 3512bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak{ 36bba458c56d16589f0bcbfe299709f6c3929e7e2eCyril Hrubis int i, ret, empty = 1; 374590c297cff4643bba8c730a62ce71889a22ca92Cyril Hrubis cap_flag_value_t v; 3812bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak 3912bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak for (i = 0; i < CAP_LAST_CAP; i++) { 4012bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak ret = cap_get_flag(c, i, CAP_PERMITTED, &v); 4109db1372e20f70ee60f14792ab6330bdba3d657fZeng Linggang /* 4209db1372e20f70ee60f14792ab6330bdba3d657fZeng Linggang * If the value of CAP_LAST_CAP in linux/capability.h is greater 4309db1372e20f70ee60f14792ab6330bdba3d657fZeng Linggang * than the value in the capability.h which is used to create 4409db1372e20f70ee60f14792ab6330bdba3d657fZeng Linggang * libcap.so. Then cap_get_flag returns -1, and errno is set to 4509db1372e20f70ee60f14792ab6330bdba3d657fZeng Linggang * EINVAL. 4609db1372e20f70ee60f14792ab6330bdba3d657fZeng Linggang */ 4709db1372e20f70ee60f14792ab6330bdba3d657fZeng Linggang if (ret == -1) { 4809db1372e20f70ee60f14792ab6330bdba3d657fZeng Linggang tst_brkm(TBROK | TERRNO, NULL, 4909db1372e20f70ee60f14792ab6330bdba3d657fZeng Linggang "Not expected. Please check arguments."); 5009db1372e20f70ee60f14792ab6330bdba3d657fZeng Linggang } 5112bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak if (ret || v) 5212bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak empty = 0; 5312bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak } 5412bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak 5512bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak return empty; 5612bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak} 5712bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak 5812bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modakstatic int am_privileged(void) 5912bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak{ 6012bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak int am_privileged = 1; 6112bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak 6212bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak cap_t cap = cap_get_proc(); 6312bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak if (eff_caps_empty(cap)) 6412bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak am_privileged = 0; 6512bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak cap_free(cap); 6612bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak 6712bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak return am_privileged; 6812bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak} 6912bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak 7012bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak#define EXPECT_NOPRIVS 0 7112bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak#define EXPECT_PRIVS 1 7212bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modakstatic void do_setuid(int expect_privs) 7312bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak{ 7412bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak int ret; 7512bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak int have_privs; 7612bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak 7712bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak ret = setuid(1000); 784c35f5b67afa11dabd902e5e4d85d6416e22fa3bZeng Linggang if (ret) 794c35f5b67afa11dabd902e5e4d85d6416e22fa3bZeng Linggang tst_brkm(TERRNO | TFAIL, NULL, "setuid failed"); 8012bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak 8112bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak have_privs = am_privileged(); 8212bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak if (have_privs && expect_privs == EXPECT_PRIVS) { 8312bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak tst_resm(TPASS, "kept privs as expected"); 8412bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak tst_exit(); 8512bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak } 8612bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak if (!have_privs && expect_privs == EXPECT_PRIVS) { 87526fdf8d8ea3b43b73de7cc25eb754f12702c8d2Cyril Hrubis tst_brkm(TFAIL, NULL, "expected to keep privs but did not"); 8812bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak } 8912bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak if (!have_privs && expect_privs == EXPECT_NOPRIVS) { 9012bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak tst_resm(TPASS, "dropped privs as expected"); 9112bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak tst_exit(); 9212bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak } 9312bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak 9412bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak /* have_privs && EXPECT_NOPRIVS */ 954c35f5b67afa11dabd902e5e4d85d6416e22fa3bZeng Linggang tst_brkm(TFAIL, NULL, "expected to drop privs but did not"); 9612bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak} 9712bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak 9812bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modakint main(int argc, char *argv[]) 9912bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak{ 10012bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak int ret, whichtest; 10112bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak 102d1e794d62b1bf619df8390535e4c2a58899b1145Cyril Hrubis tst_require_root(); 103bba458c56d16589f0bcbfe299709f6c3929e7e2eCyril Hrubis 10412bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak ret = prctl(PR_GET_KEEPCAPS); 1054c35f5b67afa11dabd902e5e4d85d6416e22fa3bZeng Linggang if (ret) 1064c35f5b67afa11dabd902e5e4d85d6416e22fa3bZeng Linggang tst_brkm(TBROK, NULL, "keepcaps was already set?"); 1074c35f5b67afa11dabd902e5e4d85d6416e22fa3bZeng Linggang 1084c35f5b67afa11dabd902e5e4d85d6416e22fa3bZeng Linggang if (argc < 2) 1094c35f5b67afa11dabd902e5e4d85d6416e22fa3bZeng Linggang tst_brkm(TBROK, NULL, "Usage: %s <tescase_num>", argv[0]); 11012bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak 11112bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak whichtest = atoi(argv[1]); 1124c35f5b67afa11dabd902e5e4d85d6416e22fa3bZeng Linggang if (whichtest < 1 || whichtest > 3) 1134c35f5b67afa11dabd902e5e4d85d6416e22fa3bZeng Linggang tst_brkm(TFAIL, NULL, "Valid tests are 1-3"); 1144c35f5b67afa11dabd902e5e4d85d6416e22fa3bZeng Linggang 115bba458c56d16589f0bcbfe299709f6c3929e7e2eCyril Hrubis switch (whichtest) { 11612bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak case 1: 117bba458c56d16589f0bcbfe299709f6c3929e7e2eCyril Hrubis do_setuid(EXPECT_NOPRIVS); /* does not return */ 11812bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak case 2: 11912bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak ret = prctl(PR_SET_KEEPCAPS, 1); 12012bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak if (ret == -1) { 1214c35f5b67afa11dabd902e5e4d85d6416e22fa3bZeng Linggang tst_brkm(TFAIL | TERRNO, NULL, 1224c35f5b67afa11dabd902e5e4d85d6416e22fa3bZeng Linggang "PR_SET_KEEPCAPS failed"); 12312bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak } 12412bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak ret = prctl(PR_GET_KEEPCAPS); 12512bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak if (!ret) { 1264c35f5b67afa11dabd902e5e4d85d6416e22fa3bZeng Linggang tst_brkm(TFAIL | TERRNO, NULL, 1274c35f5b67afa11dabd902e5e4d85d6416e22fa3bZeng Linggang "PR_SET_KEEPCAPS did not set keepcaps"); 12812bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak } 129bba458c56d16589f0bcbfe299709f6c3929e7e2eCyril Hrubis do_setuid(EXPECT_PRIVS); /* does not return */ 13012bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak case 3: 13112bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak ret = prctl(PR_GET_SECUREBITS); 13212bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak ret = prctl(PR_SET_SECUREBITS, ret | SECBIT_KEEP_CAPS); 13312bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak if (ret == -1) { 1344c35f5b67afa11dabd902e5e4d85d6416e22fa3bZeng Linggang tst_brkm(TFAIL | TERRNO, NULL, 1354c35f5b67afa11dabd902e5e4d85d6416e22fa3bZeng Linggang "PR_SET_SECUREBITS failed"); 13612bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak } 13712bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak ret = prctl(PR_GET_KEEPCAPS); 13812bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak if (!ret) { 1394c35f5b67afa11dabd902e5e4d85d6416e22fa3bZeng Linggang tst_brkm(TFAIL | TERRNO, NULL, 1404c35f5b67afa11dabd902e5e4d85d6416e22fa3bZeng Linggang "PR_SET_SECUREBITS did not set keepcaps"); 14112bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak } 142bba458c56d16589f0bcbfe299709f6c3929e7e2eCyril Hrubis do_setuid(EXPECT_PRIVS); /* does not return */ 14312bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak default: 1444c35f5b67afa11dabd902e5e4d85d6416e22fa3bZeng Linggang tst_brkm(TFAIL, NULL, "Valid tests are 1-3"); 14512bb83d825c7b58bb4fb3322620591c9fdf4ff5cSubrata Modak } 1464590c297cff4643bba8c730a62ce71889a22ca92Cyril Hrubis} 147c220729f1dea6e6eca696b255c01dfd4dc897df9Cyril Hrubis 148c220729f1dea6e6eca696b255c01dfd4dc897df9Cyril Hrubis#else 149c220729f1dea6e6eca696b255c01dfd4dc897df9Cyril Hrubis 150c220729f1dea6e6eca696b255c01dfd4dc897df9Cyril Hrubisint main(void) 151c220729f1dea6e6eca696b255c01dfd4dc897df9Cyril Hrubis{ 1524c35f5b67afa11dabd902e5e4d85d6416e22fa3bZeng Linggang tst_brkm(TCONF, NULL, "linux/securebits.h or libcap does not exist."); 153c220729f1dea6e6eca696b255c01dfd4dc897df9Cyril Hrubis} 154c220729f1dea6e6eca696b255c01dfd4dc897df9Cyril Hrubis 155c220729f1dea6e6eca696b255c01dfd4dc897df9Cyril Hrubis#endif /* HAVE_LIBCAP */ 156