staticinlineint error_check(struct error *err, constchar *test_name)
{ /* In case of error we bail out and terminate the test program */ if (err->code == PIDFD_ERROR)
error_report(err, test_name);
snprintf(path, sizeof(path), "/proc/self/fdinfo/%d", pidfd);
f = fopen(path, "re"); if (!f) return error_set(err, PIDFD_ERROR, "fdinfo open failed for %d",
pidfd);
while (getline(&line, &n, f) != -1) { char *val;
if (strncmp(line, prefix, prefix_len)) continue;
found = 1;
val = line + prefix_len;
r = strcmp(val, buffer); if (r != 0) {
trim_newline(line);
trim_newline(buffer);
error_set(err, PIDFD_FAIL, "%s '%s' != '%s'",
prefix, val, buffer);
} break;
}
free(line);
fclose(f);
if (found == 0) return error_set(err, PIDFD_FAIL, "%s not found for fd %d",
prefix, pidfd);
return PIDFD_PASS;
}
staticint child_fdinfo_nspid_test(void *args)
{ struct error err; int pidfd; int r;
/* if we got no fd for the sibling, we are done */ if (!args) return PIDFD_PASS;
/* verify that we can not resolve the pidfd for a process * in a sibling pid namespace, i.e. a pid namespace it is * not in our or a descended namespace
*/
r = mount(NULL, "/", NULL, MS_REC | MS_PRIVATE, 0); if (r < 0) {
ksft_print_msg("Failed to remount / private\n"); return PIDFD_ERROR;
}
(void)umount2("/proc", MNT_DETACH);
r = mount("proc", "/proc", "proc", 0, NULL); if (r < 0) {
ksft_print_msg("Failed to remount /proc\n"); return PIDFD_ERROR;
}
if (r != PIDFD_PASS)
ksft_print_msg("NSpid fdinfo check failed: %s\n", err.msg);
return r;
}
staticvoid test_pidfd_fdinfo_nspid(void)
{ struct child a, b; struct error err = {0, }; constchar *test_name = "pidfd check for NSpid in fdinfo";
/* Create a new child in a new pid and mount namespace */
a = clone_newns(child_fdinfo_nspid_test, NULL, &err);
error_check(&err, test_name);
/* Pass the pidfd representing the first child to the * second child, which will be in a sibling pid namespace, * which means that the fdinfo NSpid entry for the pidfd * should only contain '0'.
*/
b = clone_newns(child_fdinfo_nspid_test, &a.fd, &err);
error_check(&err, test_name);
/* The children will have pid 1 in the new pid namespace, * so the line must be 'NSPid:\t<pid>\t1'.
*/
verify_fdinfo(a.fd, &err, "NSpid:", 6, "\t%d\t%d\n", a.pid, 1);
verify_fdinfo(b.fd, &err, "NSpid:", 6, "\t%d\t%d\n", b.pid, 1);
/* wait for the process, check the exit status and set * 'err' accordingly, if it is not already set.
*/
child_join_close(&a, &err);
child_join_close(&b, &err);
/* Create a new child in a new pid and mount namespace */
a = clone_newns(child_fdinfo_nspid_test, NULL, &err);
error_check(&err, test_name);
child_join(&a, &err);
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.