-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Pan fix #6169
Pan fix #6169
Conversation
Dear @jenswi-linaro I have a question about I got the following stack trace when I tried
|
I assume you have removed the enter_user_access() and exit_user_access() from scall_handle_ldelf(). |
Thanks for hint. |
Oh, IIUC so it was not fault of the QEMU (it's always easy to blame others), but the |
Did you guys encounter PAN exception on xtest 1033 ? It seems that in the |
Oh, another SPSR fabrication problem hiding that. I'll take care of that too in the PR. |
Thanks! I just found that xtest 2001 has the same problem. |
Yeah, I just noticed that too. I'm taking care of that. Then there's also xtest 6001, I'm looking at that at the moment. |
Rewrote "core: arm64: preserve PSTATE.PAN when making SPSR" to address another SPSR fabrication issue. Now we have a common function to fabricate an SPSR based on PSTATE. Also added a few more patches fixing more PAN problems discovered with the SPSR fabrication problem out of the way. This update fixes all issues with PAN I'm currently aware of. I'm planning to add more fine-grained PAN for ldelf syscalls too, but that will go into another pull request. |
CI timeout should be fixed by OP-TEE/build#665 |
All checks has passed now. |
Please help to review these PAN fixes. |
Thank you for the work! I will take time to further review the PR. At the first glance, regarding the commit "core: arm64: preserve PSTATE.PAN when making SPSR", IIUC the function |
Regarding "core: add user buffer to tee_invoke_supp_plugin_rpc()", do we have any call-sites where |
Thanks, I'll fix that.
Yes, that's for future-proofing. |
Update to take care of the |
core/arch/arm/kernel/abort.c
Outdated
daif = (ai->regs->spsr >> SPSR_32_AIF_SHIFT) & SPSR_32_AIF_MASK; | ||
/* XXX what about DAIF_D? */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One thing I am not sure about is that if it is okay to remove this line. It seems like el0_sync_abort
does not touch the memory at the offset THREAD_ABG_REG_SPSR
, but I am just wondering if I am missing something. Other than this, it looks good to me and I think it can be squashed into previous commit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
THREAD_ABT_REG_SPSR
is updated at:
optee_os/core/arch/arm/kernel/thread_a64.S
Lines 1027 to 1029 in f7e4fc1
mrs x2, spsr_el1 | |
/* Store spsr, sp_el0 */ | |
stp x2, x3, [sp, #THREAD_ABT_REG_SPSR] |
However, there is a problem. We might need to create the new SPSR based on the EL0 SPSR since for instance (some of?) the DAIF bits are masked when taking an exception.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am wondering if we need to keep the previous EL0 SPSR value here. If the abort_handler()
hits the handle_user_mode_panic()
then it will never return to the EL0 iiuc, and the previous spsr
value has been already printed (in get_fault_type()
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed back to the old way of setting the SPSR, except that I preserve the PAN bit in the same way as the DAIF bits.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM as sticking to the old way would introduce less side effects.
Squashed in the updates and added another sentence to "core: arm64: preserve PSTATE.PAN when making SPSR" |
Applied parts of this PR and tested on RISC-V architecture with
|
I noticed that we don't have the PAN bit set while at S-EL0 so SPSR_EL1.PAN isn't set. So we need to copy the PSTATE.PAN bit instead. |
I am wondering if this PR is on radar of other maintainers for review. |
@seonghp it is on my to-do list and hopefully others can review too, but note this is summer time and some people are on vacation 😉 |
Good news! Thank you for the confirmation 👍 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Small fixes in the commit descriptions:
- For "core: fix reading result in ldelf_dlopen()":
s/start to a use/start to use a/
- For "core: syscall_storage_obj_rename(): fix direct user memory access":
s/lead a data/lead to a data/
- For "core: arm64: preserve PSTATE.PAN when making SPSR":
s/only go to/only going to/
plus see one comment in the code below.
With that and for the whole series:
Reviewed-by: Jerome Forissier <jerome.forissier@linaro.org>
One more thing: how come the CI wasn't failing without these fixes? The QEMUv8_check job has a line with CFG_PAN=y
and QEMU is started with -cpu max
, so PAN is supposed to be active. Is it only because the test cases are not exercising the proper parts of the code?
core/arch/arm/kernel/thread.c
Outdated
{ | ||
uint64_t spsr = SPSR_64(SPSR_64_MODE_EL1, SPSR_64_MODE_SP_EL0, 0); | ||
|
||
spsr = SPSR_64(SPSR_64_MODE_EL1, SPSR_64_MODE_SP_EL0, 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Duplicated initialization
It's because "core: arm64: preserve PSTATE.PAN when making SPSR" fixes a few bugs that otherwise effectively disables PAN in some cases. |
Adds check_user_access() to simplify checking if a user mode memory buffer may be accessed as expected. Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org> Reviewed-by: Jerome Forissier <jerome.forissier@linaro.org>
Adds default implementations for copy_to_user_private() and copy_to_user() when CFG_WITH_USER_TA=n. Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org> Reviewed-by: Jerome Forissier <jerome.forissier@linaro.org>
Adds a user buffer to tee_invoke_supp_plugin_rpc() so direct user memory access can be used when called with a buffer in user memory instead of core memory. tee_invoke_supp_plugin_rpc() can still take a core memory buffer as an argument if needed. PTA_SYSTEM_SUPP_PLUGIN_INVOKE in the system PTA is updated to pass the memref as a user memory buffer instead of a core memory buffer. This fixes a direct privileged memory access to user space memory. Fixes: 4e15432 ("core: Apply finer-grained PAN") Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org> Reviewed-by: Jerome Forissier <jerome.forissier@linaro.org>
The commit 52e7b1a ("core: use user-access functions in ldelf interaction") start to use a bounce buffer to initialize the argument for LDELF_DL_ENTRY_DLSYM. However, it also reads the result of LDELF_DL_ENTRY_DLSYM from the bounce buffer. This is an error since the result of LDELF_DL_ENTRY_DLSYM still remains on the stack used by ldelf. So fix this by reading the result from the ldelf stack. Fixes: 52e7b1a ("core: use user-access functions in ldelf interaction") Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org> Reviewed-by: Jerome Forissier <jerome.forissier@linaro.org>
Replaces direct user memory accesses in the socket PTA with copy_to_user() and copy_from_user(). This avoids PAN errors when PAN is active. Fixes: 4e15432 ("core: Apply finer-grained PAN") Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org> Reviewed-by: Jerome Forissier <jerome.forissier@linaro.org>
Fixes a direct user memory access in syscall_storage_obj_rename() which can lead to a data abort if PAN is enabled. Fixes: 84f7897 ("core: use user-access functions for storage svc") Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org> Reviewed-by: Jerome Forissier <jerome.forissier@linaro.org>
Updates the create(), read(), and write() function pointers in struct ts_store_ops to take a user space buffer in addition to the previous core buffer. Core buffers are normal secure memory while user space buffers should only be accessed using the user_access.h functions. The different FS storage implementations are updated accordingly. Note that the RPMB FS storage implementation resorts to using enter_user_access() and exit_user_access() due to internal complexities. Fixes: 4e15432 ("core: Apply finer-grained PAN") Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org> Reviewed-by: Jerome Forissier <jerome.forissier@linaro.org>
Adds the wrapper function read_pan() to read PSTATE.PAN, also adds a SPSR_64_PAN define. Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org> Reviewed-by: Jerome Forissier <jerome.forissier@linaro.org>
Adds the helper function feat_pan_implemented() to extract the implemented PAN version. No version is 0 so this function can be used tested as a boolean too. Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org> Reviewed-by: Jerome Forissier <jerome.forissier@linaro.org>
When setup_unwind_user_mode() prepares to resume execution after syscall_sys_return() or when a thread is suspended a new SPSR is fabricated base on the current PSTATE. Until now when remaining in S-EL1 to fabricate an SPSR only the PSTATE.DAIF bits had to be taken into account. However, with PSTATE.PAN there's yet another bit to consider. Since PSTATE has a few more bits and more may be added as AArch64 evolves this problem is only going to get worse. So implement this in a single internal C function to replace current open codes C and assembly versions. The AArch64 assembly versions of thread_rpc() are renamed to thread_rpc_spsr() to indicate that SPSR is passed in the second argument instead of having it open coded internally in the assembly function. New C wrapper functions are added to preserve the old thread_rpc() interface as needed. handle_user_mode_panic() is still basing its created SPSR on the saved SPSR from S-EL0, but now PAN bit is copied too. Fixes: 6fa59c9 ("arm64: Introduce permissive PAN implementation") Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org> Reviewed-by: Jerome Forissier <jerome.forissier@linaro.org>
Comments addressed, tag applied. |
@gagachang @seonghp any comment? |
LGTM, I tested this PR on RISC-V and worked well. |
LGTM. Thanks for your work! |
Fixes the missing PSTATE.PAN bit when returning with
syscall_sys_return()
. Did crash as expected without PR #6161.