Revert "ANDROID: Revert: Merge 5.4.60 into android11-5.4"

This reverts commit f553ed04bc and really
does merge v5.4.60 into the tree.

Bug: 161946584
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Change-Id: I164a49d7930e441b52c8a80b2fa5aa2b7ec41ed9
This commit is contained in:
Greg Kroah-Hartman 2020-08-23 12:45:23 +02:00
commit 2669cd8a3e
151 changed files with 1084 additions and 626 deletions

View file

@ -7,6 +7,8 @@
#include <argp.h>
#include <string.h>
#define EXIT_NO_TEST 2
/* defined in test_progs.h */
struct test_env env;
@ -584,5 +586,8 @@ int main(int argc, char **argv)
free(env.test_selector.num_set);
free(env.subtest_selector.num_set);
if (env.succ_cnt + env.fail_cnt + env.skip_cnt == 0)
return EXIT_NO_TEST;
return env.fail_cnt ? EXIT_FAILURE : EXIT_SUCCESS;
}

View file

@ -44,7 +44,7 @@ struct shared_info {
unsigned long amr2;
/* AMR value that ptrace should refuse to write to the child. */
unsigned long amr3;
unsigned long invalid_amr;
/* IAMR value the parent expects to read from the child. */
unsigned long expected_iamr;
@ -57,8 +57,8 @@ struct shared_info {
* (even though they're valid ones) because userspace doesn't have
* access to those registers.
*/
unsigned long new_iamr;
unsigned long new_uamor;
unsigned long invalid_iamr;
unsigned long invalid_uamor;
};
static int sys_pkey_alloc(unsigned long flags, unsigned long init_access_rights)
@ -66,11 +66,6 @@ static int sys_pkey_alloc(unsigned long flags, unsigned long init_access_rights)
return syscall(__NR_pkey_alloc, flags, init_access_rights);
}
static int sys_pkey_free(int pkey)
{
return syscall(__NR_pkey_free, pkey);
}
static int child(struct shared_info *info)
{
unsigned long reg;
@ -100,28 +95,32 @@ static int child(struct shared_info *info)
info->amr1 |= 3ul << pkeyshift(pkey1);
info->amr2 |= 3ul << pkeyshift(pkey2);
info->amr3 |= info->amr2 | 3ul << pkeyshift(pkey3);
/*
* invalid amr value where we try to force write
* things which are deined by a uamor setting.
*/
info->invalid_amr = info->amr2 | (~0x0UL & ~info->expected_uamor);
/*
* if PKEY_DISABLE_EXECUTE succeeded we should update the expected_iamr
*/
if (disable_execute)
info->expected_iamr |= 1ul << pkeyshift(pkey1);
else
info->expected_iamr &= ~(1ul << pkeyshift(pkey1));
info->expected_iamr &= ~(1ul << pkeyshift(pkey2) | 1ul << pkeyshift(pkey3));
info->expected_uamor |= 3ul << pkeyshift(pkey1) |
3ul << pkeyshift(pkey2);
info->new_iamr |= 1ul << pkeyshift(pkey1) | 1ul << pkeyshift(pkey2);
info->new_uamor |= 3ul << pkeyshift(pkey1);
/*
* We allocated pkey2 and pkey 3 above. Clear the IAMR bits.
*/
info->expected_iamr &= ~(1ul << pkeyshift(pkey2));
info->expected_iamr &= ~(1ul << pkeyshift(pkey3));
/*
* We won't use pkey3. We just want a plausible but invalid key to test
* whether ptrace will let us write to AMR bits we are not supposed to.
*
* This also tests whether the kernel restores the UAMOR permissions
* after a key is freed.
* Create an IAMR value different from expected value.
* Kernel will reject an IAMR and UAMOR change.
*/
sys_pkey_free(pkey3);
info->invalid_iamr = info->expected_iamr | (1ul << pkeyshift(pkey1) | 1ul << pkeyshift(pkey2));
info->invalid_uamor = info->expected_uamor & ~(0x3ul << pkeyshift(pkey1));
printf("%-30s AMR: %016lx pkey1: %d pkey2: %d pkey3: %d\n",
user_write, info->amr1, pkey1, pkey2, pkey3);
@ -196,9 +195,9 @@ static int parent(struct shared_info *info, pid_t pid)
PARENT_SKIP_IF_UNSUPPORTED(ret, &info->child_sync);
PARENT_FAIL_IF(ret, &info->child_sync);
info->amr1 = info->amr2 = info->amr3 = regs[0];
info->expected_iamr = info->new_iamr = regs[1];
info->expected_uamor = info->new_uamor = regs[2];
info->amr1 = info->amr2 = regs[0];
info->expected_iamr = regs[1];
info->expected_uamor = regs[2];
/* Wake up child so that it can set itself up. */
ret = prod_child(&info->child_sync);
@ -234,10 +233,10 @@ static int parent(struct shared_info *info, pid_t pid)
return ret;
/* Write invalid AMR value in child. */
ret = ptrace_write_regs(pid, NT_PPC_PKEY, &info->amr3, 1);
ret = ptrace_write_regs(pid, NT_PPC_PKEY, &info->invalid_amr, 1);
PARENT_FAIL_IF(ret, &info->child_sync);
printf("%-30s AMR: %016lx\n", ptrace_write_running, info->amr3);
printf("%-30s AMR: %016lx\n", ptrace_write_running, info->invalid_amr);
/* Wake up child so that it can verify it didn't change. */
ret = prod_child(&info->child_sync);
@ -249,7 +248,7 @@ static int parent(struct shared_info *info, pid_t pid)
/* Try to write to IAMR. */
regs[0] = info->amr1;
regs[1] = info->new_iamr;
regs[1] = info->invalid_iamr;
ret = ptrace_write_regs(pid, NT_PPC_PKEY, regs, 2);
PARENT_FAIL_IF(!ret, &info->child_sync);
@ -257,7 +256,7 @@ static int parent(struct shared_info *info, pid_t pid)
ptrace_write_running, regs[0], regs[1]);
/* Try to write to IAMR and UAMOR. */
regs[2] = info->new_uamor;
regs[2] = info->invalid_uamor;
ret = ptrace_write_regs(pid, NT_PPC_PKEY, regs, 3);
PARENT_FAIL_IF(!ret, &info->child_sync);