<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>