Skip to content

Commit 613e040

Browse files
committed
selftests: cgroup: Test open-time credential usage for migration checks
When a task is writing to an fd opened by a different task, the perm check should use the credentials of the latter task. Add a test for it. Tested-by: Michal Koutný <[email protected]> Signed-off-by: Tejun Heo <[email protected]>
1 parent b09c2ba commit 613e040

File tree

1 file changed

+68
-0
lines changed

1 file changed

+68
-0
lines changed

tools/testing/selftests/cgroup/test_core.c

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -674,6 +674,73 @@ static int test_cgcore_thread_migration(const char *root)
674674
return ret;
675675
}
676676

677+
/*
678+
* cgroup migration permission check should be performed based on the
679+
* credentials at the time of open instead of write.
680+
*/
681+
static int test_cgcore_lesser_euid_open(const char *root)
682+
{
683+
const uid_t test_euid = 65534; /* usually nobody, any !root is fine */
684+
int ret = KSFT_FAIL;
685+
char *cg_test_a = NULL, *cg_test_b = NULL;
686+
char *cg_test_a_procs = NULL, *cg_test_b_procs = NULL;
687+
int cg_test_b_procs_fd = -1;
688+
uid_t saved_uid;
689+
690+
cg_test_a = cg_name(root, "cg_test_a");
691+
cg_test_b = cg_name(root, "cg_test_b");
692+
693+
if (!cg_test_a || !cg_test_b)
694+
goto cleanup;
695+
696+
cg_test_a_procs = cg_name(cg_test_a, "cgroup.procs");
697+
cg_test_b_procs = cg_name(cg_test_b, "cgroup.procs");
698+
699+
if (!cg_test_a_procs || !cg_test_b_procs)
700+
goto cleanup;
701+
702+
if (cg_create(cg_test_a) || cg_create(cg_test_b))
703+
goto cleanup;
704+
705+
if (cg_enter_current(cg_test_a))
706+
goto cleanup;
707+
708+
if (chown(cg_test_a_procs, test_euid, -1) ||
709+
chown(cg_test_b_procs, test_euid, -1))
710+
goto cleanup;
711+
712+
saved_uid = geteuid();
713+
if (seteuid(test_euid))
714+
goto cleanup;
715+
716+
cg_test_b_procs_fd = open(cg_test_b_procs, O_RDWR);
717+
718+
if (seteuid(saved_uid))
719+
goto cleanup;
720+
721+
if (cg_test_b_procs_fd < 0)
722+
goto cleanup;
723+
724+
if (write(cg_test_b_procs_fd, "0", 1) >= 0 || errno != EACCES)
725+
goto cleanup;
726+
727+
ret = KSFT_PASS;
728+
729+
cleanup:
730+
cg_enter_current(root);
731+
if (cg_test_b_procs_fd >= 0)
732+
close(cg_test_b_procs_fd);
733+
if (cg_test_b)
734+
cg_destroy(cg_test_b);
735+
if (cg_test_a)
736+
cg_destroy(cg_test_a);
737+
free(cg_test_b_procs);
738+
free(cg_test_a_procs);
739+
free(cg_test_b);
740+
free(cg_test_a);
741+
return ret;
742+
}
743+
677744
#define T(x) { x, #x }
678745
struct corecg_test {
679746
int (*fn)(const char *root);
@@ -689,6 +756,7 @@ struct corecg_test {
689756
T(test_cgcore_proc_migration),
690757
T(test_cgcore_thread_migration),
691758
T(test_cgcore_destroy),
759+
T(test_cgcore_lesser_euid_open),
692760
};
693761
#undef T
694762

0 commit comments

Comments
 (0)