summaryrefslogtreecommitdiffstats
path: root/arch/arm64/kernel/signal.c
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2023-01-31 23:20:40 +0100
committerCatalin Marinas <catalin.marinas@arm.com>2023-02-01 18:56:47 +0100
commit0eb23720f29e4e7010c4b5195cf0d6500921a146 (patch)
tree179c7c9d01c52260d2f62d7eabdfd2d46d832fd3 /arch/arm64/kernel/signal.c
parentarm64/signal: Don't redundantly verify FPSIMD magic (diff)
downloadlinux-0eb23720f29e4e7010c4b5195cf0d6500921a146.tar.xz
linux-0eb23720f29e4e7010c4b5195cf0d6500921a146.zip
arm64/signal: Remove redundant size validation from parse_user_sigframe()
There is some minimal size validation in parse_user_sigframe() however all of the individual parsing functions perform frame specific validation of the sizing information, remove the frame specific size checks in the core so that there isn't any confusion about what we validate for size. Since the checks in the SVE and ZA parsing are after we have read the relevant context and since they won't report an error if the frame is undersized they are adjusted to check for this before doing anything else. Signed-off-by: Mark Brown <broonie@kernel.org> Link: https://lore.kernel.org/r/20221212-arm64-signal-cleanup-v3-2-4545c94b20ff@kernel.org Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Diffstat (limited to 'arch/arm64/kernel/signal.c')
-rw-r--r--arch/arm64/kernel/signal.c19
1 files changed, 8 insertions, 11 deletions
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index 882f6d913508..3228b5a1dfe3 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -278,6 +278,9 @@ static int restore_sve_fpsimd_context(struct user_ctxs *user)
if (__copy_from_user(&sve, user->sve, sizeof(sve)))
return -EFAULT;
+ if (sve.head.size < sizeof(*user->sve))
+ return -EINVAL;
+
if (sve.flags & SVE_SIG_FLAG_SM) {
if (!system_supports_sme())
return -EINVAL;
@@ -293,7 +296,7 @@ static int restore_sve_fpsimd_context(struct user_ctxs *user)
if (sve.vl != vl)
return -EINVAL;
- if (sve.head.size <= sizeof(*user->sve)) {
+ if (sve.head.size == sizeof(*user->sve)) {
clear_thread_flag(TIF_SVE);
current->thread.svcr &= ~SVCR_SM_MASK;
current->thread.fp_type = FP_STATE_FPSIMD;
@@ -434,10 +437,13 @@ static int restore_za_context(struct user_ctxs *user)
if (__copy_from_user(&za, user->za, sizeof(za)))
return -EFAULT;
+ if (za.head.size < sizeof(*user->za))
+ return -EINVAL;
+
if (za.vl != task_get_sme_vl(current))
return -EINVAL;
- if (za.head.size <= sizeof(*user->za)) {
+ if (za.head.size == sizeof(*user->za)) {
current->thread.svcr &= ~SVCR_ZA_MASK;
return 0;
}
@@ -614,9 +620,6 @@ static int parse_user_sigframe(struct user_ctxs *user,
if (user->fpsimd)
goto invalid;
- if (size < sizeof(*user->fpsimd))
- goto invalid;
-
user->fpsimd = (struct fpsimd_context __user *)head;
break;
@@ -631,9 +634,6 @@ static int parse_user_sigframe(struct user_ctxs *user,
if (user->sve)
goto invalid;
- if (size < sizeof(*user->sve))
- goto invalid;
-
user->sve = (struct sve_context __user *)head;
break;
@@ -657,9 +657,6 @@ static int parse_user_sigframe(struct user_ctxs *user,
if (user->za)
goto invalid;
- if (size < sizeof(*user->za))
- goto invalid;
-
user->za = (struct za_context __user *)head;
break;