diff mbox series

[4/6] linux-user: Initialize aarch64 pac keys

Message ID 20190125225714.10234-6-richard.henderson@linaro.org
State New
Headers show
Series target/arm: Complete ARMv8.3-PAuth linux-user | expand

Commit Message

Richard Henderson Jan. 25, 2019, 10:57 p.m. UTC
Initialize the keys to a non-zero value on process start.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

---
 linux-user/aarch64/target_syscall.h |  2 ++
 linux-user/aarch64/cpu_loop.c       | 31 +++++++++++++++++++++++++++--
 2 files changed, 31 insertions(+), 2 deletions(-)

-- 
2.17.2

Comments

Peter Maydell Feb. 1, 2019, 3:11 p.m. UTC | #1
On Fri, 25 Jan 2019 at 22:57, Richard Henderson
<richard.henderson@linaro.org> wrote:
>

> Initialize the keys to a non-zero value on process start.

>

> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>


> +static uint64_t arm_rand64(void)

> +{

> +    int shift = 64 - clz64(RAND_MAX);

> +    int i, n = 64 / shift + (64 % shift != 0);

> +    uint64_t ret = 0;

> +

> +    for (i = 0; i < n; i++) {

> +        ret = (ret << shift) | rand();

> +    }

> +    return ret;

> +}


I'm not a huge fan of the use of rand() here, but it's what
we're using to initialize AT_RANDOM in linux-user, so I guess
it's OK here. At some point we should investigate whether
there's something better we are guaranteed to have available,
I suppose. (Coverity gripes about use of rand().)

thanks
-- PMM
Richard Henderson Feb. 1, 2019, 6:13 p.m. UTC | #2
On 2/1/19 7:11 AM, Peter Maydell wrote:
> On Fri, 25 Jan 2019 at 22:57, Richard Henderson

> <richard.henderson@linaro.org> wrote:

>>

>> Initialize the keys to a non-zero value on process start.

>>

>> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

> 

>> +static uint64_t arm_rand64(void)

>> +{

>> +    int shift = 64 - clz64(RAND_MAX);

>> +    int i, n = 64 / shift + (64 % shift != 0);

>> +    uint64_t ret = 0;

>> +

>> +    for (i = 0; i < n; i++) {

>> +        ret = (ret << shift) | rand();

>> +    }

>> +    return ret;

>> +}

> 

> I'm not a huge fan of the use of rand() here, but it's what

> we're using to initialize AT_RANDOM in linux-user, so I guess

> it's OK here. At some point we should investigate whether

> there's something better we are guaranteed to have available,

> I suppose. (Coverity gripes about use of rand().)


I considered implementing a qemu version of getentropy,
but then I saw our "-seed" option and thought perhaps
repeatability is more important for qemu.


r~
diff mbox series

Patch

diff --git a/linux-user/aarch64/target_syscall.h b/linux-user/aarch64/target_syscall.h
index 205265e619..937fd7989e 100644
--- a/linux-user/aarch64/target_syscall.h
+++ b/linux-user/aarch64/target_syscall.h
@@ -22,4 +22,6 @@  struct target_pt_regs {
 #define TARGET_PR_SVE_SET_VL  50
 #define TARGET_PR_SVE_GET_VL  51
 
+void arm_init_pauth_key(ARMPACKey *key);
+
 #endif /* AARCH64_TARGET_SYSCALL_H */
diff --git a/linux-user/aarch64/cpu_loop.c b/linux-user/aarch64/cpu_loop.c
index 65d815f030..d75fd9d3e2 100644
--- a/linux-user/aarch64/cpu_loop.c
+++ b/linux-user/aarch64/cpu_loop.c
@@ -147,10 +147,29 @@  void cpu_loop(CPUARMState *env)
     }
 }
 
+static uint64_t arm_rand64(void)
+{
+    int shift = 64 - clz64(RAND_MAX);
+    int i, n = 64 / shift + (64 % shift != 0);
+    uint64_t ret = 0;
+
+    for (i = 0; i < n; i++) {
+        ret = (ret << shift) | rand();
+    }
+    return ret;
+}
+
+void arm_init_pauth_key(ARMPACKey *key)
+{
+    key->lo = arm_rand64();
+    key->hi = arm_rand64();
+}
+
 void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs)
 {
-    CPUState *cpu = ENV_GET_CPU(env);
-    TaskState *ts = cpu->opaque;
+    ARMCPU *cpu = arm_env_get_cpu(env);
+    CPUState *cs = CPU(cpu);
+    TaskState *ts = cs->opaque;
     struct image_info *info = ts->info;
     int i;
 
@@ -172,6 +191,14 @@  void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs)
     }
 #endif
 
+    if (cpu_isar_feature(aa64_pauth, cpu)) {
+        arm_init_pauth_key(&env->apia_key);
+        arm_init_pauth_key(&env->apib_key);
+        arm_init_pauth_key(&env->apda_key);
+        arm_init_pauth_key(&env->apdb_key);
+        arm_init_pauth_key(&env->apga_key);
+    }
+
     ts->stack_base = info->start_stack;
     ts->heap_base = info->brk;
     /* This will be filled in on the first SYS_HEAPINFO call.  */