History

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.

Tejun Heo committed 4 years ago

Commit 613e0401 parent b09c2ba1 file · +68 −0Browse files

Unified · Split

tools/testing/selftests/cgroup/test_core.c+68−0
@@ -674,6 +674,73 @@ cleanup: · 673 unmodified lines
674 return ret;674 return ret;
675}675}
676 676
677/*
678 * cgroup migration permission check should be performed based on the
679 * credentials at the time of open instead of write.
680 */
681static 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
729cleanup:
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
677#define T(x) { x, #x }744#define T(x) { x, #x }
678struct corecg_test {745struct corecg_test {
679 int (*fn)(const char *root);746 int (*fn)(const char *root);
@@ -689,6 +756,7 @@ struct corecg_test { · 9 unmodified lines
689 T(test_cgcore_proc_migration),756 T(test_cgcore_proc_migration),
690 T(test_cgcore_thread_migration),757 T(test_cgcore_thread_migration),
691 T(test_cgcore_destroy),758 T(test_cgcore_destroy),
759 T(test_cgcore_lesser_euid_open),
692};760};
693#undef T761#undef T
694 762