On Sun, 2023-07-16 at 22:51 +0100, Mark Brown wrote:
+int arch_set_shadow_stack_status(struct task_struct *task, unsigned long arg) +{ + unsigned long gcs, size;
+ if (!system_supports_gcs()) + return -EINVAL;
+ if (is_compat_thread(task_thread_info(task))) + return -EINVAL;
+ /* Reject unknown flags */ + if (arg & ~PR_SHADOW_STACK_SUPPORTED_STATUS_MASK) + return -EINVAL;
+ /* If the task has been locked block any attempted changes */ + if (task->thread.gcs_el0_mode & PR_SHADOW_STACK_LOCK) + return -EBUSY;
+ /* Drop flags other than lock if disabling */ + if (!(arg & PR_SHADOW_STACK_ENABLE)) + arg &= ~PR_SHADOW_STACK_LOCK;
+ /* If we are enabling GCS then make sure we have a stack */ + if (arg & PR_SHADOW_STACK_ENABLE) { + if (!task_gcs_el0_enabled(task)) { + /* Do not allow GCS to be reenabled */ + if (task->thread.gcs_base) + return -EINVAL;
+ size = gcs_size(0); + gcs = alloc_gcs(task->thread.gcspr_el0, size, + 0, 0); + if (!gcs) + return -ENOMEM;
+ task->thread.gcspr_el0 = gcs + size - sizeof(u64); + task->thread.gcs_base = gcs; + task->thread.gcs_size = size; + if (task == current) + write_sysreg_s(task-
thread.gcspr_el0,
+ SYS_GCSPR_EL0);
+ } + }
+ task->thread.gcs_el0_mode = arg; + if (task == current) + gcs_set_el0_mode(task);
Ah! So does this task == current part mean this can be called from another task via ptrace?
If so, then is the alloc_gcs() part on the wrong mm?