<div dir="ltr"><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">Hi,</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><br></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">Ping~</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><br></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">I think this patch make sense for the tests, how about applying it?</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><br></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Jan 11, 2018 at 9:16 PM, Jan Stancek <span dir="ltr"><<a href="mailto:jstancek@redhat.com" target="_blank">jstancek@redhat.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">commit 313674661925 ("Unify migrate_pages and move_pages access checks")<br>
tightened checks for unprivileged user. It requires that callers real<br>
uid/gid matches target [es]uig/[es]gid and target to be dumpable<br>
(see __ptrace_may_access()).<br>
<br>
It broke the test, because change of only euid is no longer<br>
sufficient.<br>
<br>
This patch updates test to use setuid(), which sets all user IDs.<br>
Since we can't change uid back to 0, we fork additional child<br>
process for "caller", which is now free to drop privileges.<br>
<br>
This change should be backwards-compatible with kernels < 4.15.<br>
Tested on 4.15-rc6 and 4.14.<br>
<br>
Signed-off-by: Jan Stancek <<a href="mailto:jstancek@redhat.com" target="_blank">jstancek@redhat.com</a>><br>
---<br>
<br>
Note: So far this is only in 4.15-rcX kernels and could still change before release.<br>
<br>
.../syscalls/migrate_pages/mi<wbr>grate_pages02.c | 72 ++++++++++++----------<br>
1 file changed, 41 insertions(+), 31 deletions(-)<br>
<br>
diff --git a/testcases/kernel/syscalls/mi<wbr>grate_pages/migrate_pages02.c b/testcases/kernel/syscalls/mi<wbr>grate_pages/migrate_pages02.c<br>
index faf96b6b79ee..8a5ff158c901 100644<br>
--- a/testcases/kernel/syscalls/mi<wbr>grate_pages/migrate_pages02.c<br>
+++ b/testcases/kernel/syscalls/mi<wbr>grate_pages/migrate_pages02.c<br>
@@ -34,6 +34,7 @@<br>
#include <sys/syscall.h><br>
#include <sys/wait.h><br>
#include <sys/mman.h><br>
+#include <sys/prctl.h><br>
#include <errno.h><br>
#if HAVE_NUMA_H<br>
#include <numa.h><br>
@@ -159,12 +160,12 @@ static int check_addr_on_node(void *addr, int exp_node)<br>
if (node == exp_node) {<br>
tst_resm(TPASS, "pid(%d) addr %p is on expected node: %d",<br>
getpid(), addr, exp_node);<br>
- return 0;<br>
+ return TPASS;<br>
} else {<br>
tst_resm(TFAIL, "pid(%d) addr %p not on expected node: %d "<br>
", expected %d", getpid(), addr, node, exp_node);<br>
print_mem_stats(0, exp_node);<br>
- return 1;<br>
+ return TFAIL;<br>
}<br>
}<br>
<br>
@@ -235,13 +236,13 @@ static void test_migrate_current_process(i<wbr>nt node1, int node2, int cap_sys_nice)<br>
static void test_migrate_other_process(int node1, int node2, int cap_sys_nice)<br>
{<br>
char *testp;<br>
- int status, ret, tmp;<br>
- pid_t child;<br>
- int child_ready[2];<br>
+ int ret, tmp;<br>
+ pid_t child1, child2;<br>
+ int child1_ready[2];<br>
int pages_migrated[2];<br>
<br>
- /* setup pipes to synchronize child/parent */<br>
- if (pipe(child_ready) == -1)<br>
+ /* setup pipes to synchronize child1/child2 */<br>
+ if (pipe(child1_ready) == -1)<br>
tst_resm(TBROK | TERRNO, "pipe #1 failed");<br>
if (pipe(pages_migrated) == -1)<br>
tst_resm(TBROK | TERRNO, "pipe #2 failed");<br>
@@ -249,13 +250,13 @@ static void test_migrate_other_process(int node1, int node2, int cap_sys_nice)<br>
tst_resm(TINFO, "other_process, cap_sys_nice: %d", cap_sys_nice);<br>
<br>
fflush(stdout);<br>
- child = fork();<br>
- switch (child) {<br>
+ child1 = fork();<br>
+ switch (child1) {<br>
case -1:<br>
tst_brkm(TBROK | TERRNO, cleanup, "fork");<br>
break;<br>
case 0:<br>
- close(child_ready[0]);<br>
+ close(child1_ready[0]);<br>
close(pages_migrated[1]);<br>
<br>
testp = SAFE_MALLOC(NULL, getpagesize());<br>
@@ -265,47 +266,56 @@ static void test_migrate_other_process(int node1, int node2, int cap_sys_nice)<br>
migrate_to_node(0, node1);<br>
check_addr_on_node(testp, node1);<br>
<br>
- SAFE_SETEUID(NULL, ltpuser->pw_uid);<br>
+ SAFE_SETUID(NULL, ltpuser->pw_uid);<br>
<br>
- /* signal parent it's OK to migrate child and wait */<br>
- if (write(child_ready[1], &tmp, 1) != 1)<br>
+ /* commit_creds() will clear dumpable, restore it */<br>
+ if (prctl(PR_SET_DUMPABLE, 1))<br>
+ tst_brkm(TBROK | TERRNO, NULL, "prctl");<br>
+<br>
+ /* signal child2 it's OK to migrate child1 and wait */<br>
+ if (write(child1_ready[1], &tmp, 1) != 1)<br>
tst_brkm(TBROK | TERRNO, NULL, "write #1 failed");<br>
if (read(pages_migrated[0], &tmp, 1) != 1)<br>
tst_brkm(TBROK | TERRNO, NULL, "read #1 failed");<br>
<br>
- /* parent can migrate child process with same euid */<br>
- /* parent can migrate child process with CAP_SYS_NICE */<br>
+ /* child2 can migrate child1 process if it's privileged */<br>
+ /* child2 can migrate child1 process if it has same uid */<br>
ret = check_addr_on_node(testp, node2);<br>
<br>
free(testp);<br>
- close(child_ready[1]);<br>
+ close(child1_ready[1]);<br>
close(pages_migrated[0]);<br>
exit(ret);<br>
- default:<br>
- close(child_ready[1]);<br>
- close(pages_migrated[0]);<br>
+ }<br>
+<br>
+ close(child1_ready[1]);<br>
+ close(pages_migrated[0]);<br>
<br>
+ fflush(stdout);<br>
+ child2 = fork();<br>
+ switch (child2) {<br>
+ case -1:<br>
+ tst_brkm(TBROK | TERRNO, cleanup, "fork");<br>
+ break;<br>
+ case 0:<br>
if (!cap_sys_nice)<br>
- SAFE_SETEUID(NULL, ltpuser->pw_uid);<br>
+ SAFE_SETUID(NULL, ltpuser->pw_uid);<br>
<br>
- /* wait until child is ready on node1, then migrate and<br>
+ /* wait until child1 is ready on node1, then migrate and<br>
* signal to check current node */<br>
- if (read(child_ready[0], &tmp, 1) != 1)<br>
+ if (read(child1_ready[0], &tmp, 1) != 1)<br>
tst_brkm(TBROK | TERRNO, NULL, "read #2 failed");<br>
- migrate_to_node(child, node2);<br>
+ migrate_to_node(child1, node2);<br>
if (write(pages_migrated[1], &tmp, 1) != 1)<br>
tst_brkm(TBROK | TERRNO, NULL, "write #2 failed");<br>
<br>
- SAFE_WAITPID(cleanup, child, &status, 0);<br>
- if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)<br>
- tst_resm(TFAIL, "child returns %d", status);<br>
- close(child_ready[0]);<br>
+ close(child1_ready[0]);<br>
close(pages_migrated[1]);<br>
-<br>
- /* reset euid, so this testcase can be used in loop */<br>
- if (!cap_sys_nice)<br>
- SAFE_SETEUID(NULL, 0);<br>
+ exit(TPASS);<br>
}<br>
+<br>
+ tst_record_childstatus(NULL, child2);<br>
+ tst_record_childstatus(NULL, child1);<br>
}<br>
<br>
int main(int argc, char *argv[])<br>
<span class="m_-8107999298311637893HOEnZb"><font color="#888888">-- <br>
1.8.3.1<br>
<br>
</font></span></blockquote></div><br><br clear="all"><br>-- <br><div class="m_-8107999298311637893gmail_signature" data-smartmail="gmail_signature">Li Wang<br><a href="mailto:liwang@redhat.com" target="_blank">liwang@redhat.com</a></div>
</div></div>