linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/6] arm64/signal: Signal handling cleanups
@ 2023-01-03 20:25 Mark Brown
  2023-01-03 20:25 ` [PATCH v2 1/6] arm64/signal: Don't redundantly verify FPSIMD magic Mark Brown
                   ` (6 more replies)
  0 siblings, 7 replies; 11+ messages in thread
From: Mark Brown @ 2023-01-03 20:25 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon; +Cc: linux-arm-kernel, linux-kernel, Mark Brown

This series collects a number of small cleanups to the signal handling
code which removes redundant validation of size information and avoids
reading the same data from userspace twice.

There are some overlaps with both the TPIDR2 signal handling and SME2
serieses which are also in flight, applying this will require
adjustments in those serieses and vice versa.

v2:
 - Rebase onto v6.2-rc1

To: Catalin Marinas <catalin.marinas@arm.com>
To: Will Deacon <will@kernel.org>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Mark Brown <broonie@kernel.org>

---
Mark Brown (6):
      arm64/signal: Don't redundantly verify FPSIMD magic
      arm64/signal: Remove redundant size validation from parse_user_sigframe()
      arm64/signal: Make interface for restore_fpsimd_context() consistent
      arm64/signal: Avoid rereading context frame sizes
      arm64/signal: Only read new data when parsing the SVE context
      arm64/signal: Only read new data when parsing the ZA context

 arch/arm64/kernel/signal.c | 91 +++++++++++++++++++++++-----------------------
 1 file changed, 46 insertions(+), 45 deletions(-)
---
base-commit: 1b929c02afd37871d5afb9d498426f83432e71c2
change-id: 20221212-arm64-signal-cleanup-bcd7272de5a9

Best regards,
-- 
Mark Brown <broonie@kernel.org>

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v2 1/6] arm64/signal: Don't redundantly verify FPSIMD magic
  2023-01-03 20:25 [PATCH v2 0/6] arm64/signal: Signal handling cleanups Mark Brown
@ 2023-01-03 20:25 ` Mark Brown
  2023-01-03 20:25 ` [PATCH v2 2/6] arm64/signal: Remove redundant size validation from parse_user_sigframe() Mark Brown
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 11+ messages in thread
From: Mark Brown @ 2023-01-03 20:25 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon; +Cc: linux-arm-kernel, linux-kernel, Mark Brown

We validate that the magic in the struct fpsimd_context is correct in
restore_fpsimd_context() but this is redundant since parse_user_sigframe()
uses this magic to decide to call the function in the first place. Remove
the extra validation.

Signed-off-by: Mark Brown <broonie@kernel.org>
---
 arch/arm64/kernel/signal.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index e0d09bf5b01b..9d3d10269da7 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -189,15 +189,14 @@ static int preserve_fpsimd_context(struct fpsimd_context __user *ctx)
 static int restore_fpsimd_context(struct fpsimd_context __user *ctx)
 {
 	struct user_fpsimd_state fpsimd;
-	__u32 magic, size;
+	__u32 size;
 	int err = 0;
 
-	/* check the magic/size information */
-	__get_user_error(magic, &ctx->head.magic, err);
+	/* check the size information */
 	__get_user_error(size, &ctx->head.size, err);
 	if (err)
 		return -EFAULT;
-	if (magic != FPSIMD_MAGIC || size != sizeof(struct fpsimd_context))
+	if (size != sizeof(struct fpsimd_context))
 		return -EINVAL;
 
 	/* copy the FP and status/control registers */

-- 
2.30.2

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v2 2/6] arm64/signal: Remove redundant size validation from parse_user_sigframe()
  2023-01-03 20:25 [PATCH v2 0/6] arm64/signal: Signal handling cleanups Mark Brown
  2023-01-03 20:25 ` [PATCH v2 1/6] arm64/signal: Don't redundantly verify FPSIMD magic Mark Brown
@ 2023-01-03 20:25 ` Mark Brown
  2023-01-03 20:25 ` [PATCH v2 3/6] arm64/signal: Make interface for restore_fpsimd_context() consistent Mark Brown
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 11+ messages in thread
From: Mark Brown @ 2023-01-03 20:25 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon; +Cc: linux-arm-kernel, linux-kernel, Mark Brown

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>
---
 arch/arm64/kernel/signal.c | 19 ++++++++-----------
 1 file changed, 8 insertions(+), 11 deletions(-)

diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index 9d3d10269da7..a7b4bb584d17 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -274,6 +274,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;
@@ -289,7 +292,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;
@@ -404,10 +407,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;
 	}
@@ -510,9 +516,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;
 
@@ -527,9 +530,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;
 
@@ -540,9 +540,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;
 

-- 
2.30.2

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v2 3/6] arm64/signal: Make interface for restore_fpsimd_context() consistent
  2023-01-03 20:25 [PATCH v2 0/6] arm64/signal: Signal handling cleanups Mark Brown
  2023-01-03 20:25 ` [PATCH v2 1/6] arm64/signal: Don't redundantly verify FPSIMD magic Mark Brown
  2023-01-03 20:25 ` [PATCH v2 2/6] arm64/signal: Remove redundant size validation from parse_user_sigframe() Mark Brown
@ 2023-01-03 20:25 ` Mark Brown
  2023-01-03 20:25 ` [PATCH v2 4/6] arm64/signal: Avoid rereading context frame sizes Mark Brown
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 11+ messages in thread
From: Mark Brown @ 2023-01-03 20:25 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon; +Cc: linux-arm-kernel, linux-kernel, Mark Brown

Instead of taking a pointer to struct user_ctxs like the other two
restore_blah_context() functions the FPSIMD function takes a pointer to the
user struct it should read. Change it to be consistent with the rest, both
for consistency and to prepare for changes which avoid rereading data that
has already been read by the core parsing code.

There should be no functional change from this patch.

Signed-off-by: Mark Brown <broonie@kernel.org>
---
 arch/arm64/kernel/signal.c | 24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index a7b4bb584d17..e9c6ffc1ebba 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -168,6 +168,12 @@ static void __user *apply_user_offset(
 	return base + offset;
 }
 
+struct user_ctxs {
+	struct fpsimd_context __user *fpsimd;
+	struct sve_context __user *sve;
+	struct za_context __user *za;
+};
+
 static int preserve_fpsimd_context(struct fpsimd_context __user *ctx)
 {
 	struct user_fpsimd_state const *fpsimd =
@@ -186,24 +192,24 @@ static int preserve_fpsimd_context(struct fpsimd_context __user *ctx)
 	return err ? -EFAULT : 0;
 }
 
-static int restore_fpsimd_context(struct fpsimd_context __user *ctx)
+static int restore_fpsimd_context(struct user_ctxs *user)
 {
 	struct user_fpsimd_state fpsimd;
 	__u32 size;
 	int err = 0;
 
 	/* check the size information */
-	__get_user_error(size, &ctx->head.size, err);
+	__get_user_error(size, &user->fpsimd->head.size, err);
 	if (err)
 		return -EFAULT;
 	if (size != sizeof(struct fpsimd_context))
 		return -EINVAL;
 
 	/* copy the FP and status/control registers */
-	err = __copy_from_user(fpsimd.vregs, ctx->vregs,
+	err = __copy_from_user(fpsimd.vregs, &(user->fpsimd->vregs),
 			       sizeof(fpsimd.vregs));
-	__get_user_error(fpsimd.fpsr, &ctx->fpsr, err);
-	__get_user_error(fpsimd.fpcr, &ctx->fpcr, err);
+	__get_user_error(fpsimd.fpsr, &(user->fpsimd->fpsr), err);
+	__get_user_error(fpsimd.fpcr, &(user->fpsimd->fpcr), err);
 
 	clear_thread_flag(TIF_SVE);
 	current->thread.fp_type = FP_STATE_FPSIMD;
@@ -216,12 +222,6 @@ static int restore_fpsimd_context(struct fpsimd_context __user *ctx)
 }
 
 
-struct user_ctxs {
-	struct fpsimd_context __user *fpsimd;
-	struct sve_context __user *sve;
-	struct za_context __user *za;
-};
-
 #ifdef CONFIG_ARM64_SVE
 
 static int preserve_sve_context(struct sve_context __user *ctx)
@@ -659,7 +659,7 @@ static int restore_sigframe(struct pt_regs *regs,
 		if (user.sve)
 			err = restore_sve_fpsimd_context(&user);
 		else
-			err = restore_fpsimd_context(user.fpsimd);
+			err = restore_fpsimd_context(&user);
 	}
 
 	if (err == 0 && system_supports_sme() && user.za)

-- 
2.30.2

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v2 4/6] arm64/signal: Avoid rereading context frame sizes
  2023-01-03 20:25 [PATCH v2 0/6] arm64/signal: Signal handling cleanups Mark Brown
                   ` (2 preceding siblings ...)
  2023-01-03 20:25 ` [PATCH v2 3/6] arm64/signal: Make interface for restore_fpsimd_context() consistent Mark Brown
@ 2023-01-03 20:25 ` Mark Brown
  2023-01-03 20:25 ` [PATCH v2 5/6] arm64/signal: Only read new data when parsing the SVE context Mark Brown
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 11+ messages in thread
From: Mark Brown @ 2023-01-03 20:25 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon; +Cc: linux-arm-kernel, linux-kernel, Mark Brown

We need to read the sizes of the signal context frames as part of parsing
the overall signal context in parse_user_sigframe(). In the cases where we
defer frame specific parsing to other functions those functions always
reread the size and validate the version they read, opening the possibility
that the value may change. Avoid this possibility by passing the size read
in parse_user_sigframe() through user_ctxs and referring to that.

Note that for SVE and ZA contexts we still read the size again but after
this change we no longer use the value, further changes will avoid the
read.

Signed-off-by: Mark Brown <broonie@kernel.org>
---
 arch/arm64/kernel/signal.c | 32 +++++++++++++++++---------------
 1 file changed, 17 insertions(+), 15 deletions(-)

diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index e9c6ffc1ebba..82a89b0852ee 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -170,8 +170,11 @@ static void __user *apply_user_offset(
 
 struct user_ctxs {
 	struct fpsimd_context __user *fpsimd;
+	u32 fpsimd_size;
 	struct sve_context __user *sve;
+	u32 sve_size;
 	struct za_context __user *za;
+	u32 za_size;
 };
 
 static int preserve_fpsimd_context(struct fpsimd_context __user *ctx)
@@ -195,14 +198,10 @@ static int preserve_fpsimd_context(struct fpsimd_context __user *ctx)
 static int restore_fpsimd_context(struct user_ctxs *user)
 {
 	struct user_fpsimd_state fpsimd;
-	__u32 size;
 	int err = 0;
 
 	/* check the size information */
-	__get_user_error(size, &user->fpsimd->head.size, err);
-	if (err)
-		return -EFAULT;
-	if (size != sizeof(struct fpsimd_context))
+	if (user->fpsimd_size != sizeof(struct fpsimd_context))
 		return -EINVAL;
 
 	/* copy the FP and status/control registers */
@@ -271,12 +270,12 @@ static int restore_sve_fpsimd_context(struct user_ctxs *user)
 	struct user_fpsimd_state fpsimd;
 	struct sve_context sve;
 
+	if (user->sve_size < sizeof(*user->sve))
+		return -EINVAL;
+
 	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;
@@ -292,7 +291,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 (user->sve_size == sizeof(*user->sve)) {
 		clear_thread_flag(TIF_SVE);
 		current->thread.svcr &= ~SVCR_SM_MASK;
 		current->thread.fp_type = FP_STATE_FPSIMD;
@@ -301,7 +300,7 @@ static int restore_sve_fpsimd_context(struct user_ctxs *user)
 
 	vq = sve_vq_from_vl(sve.vl);
 
-	if (sve.head.size < SVE_SIG_CONTEXT_SIZE(vq))
+	if (user->sve_size < SVE_SIG_CONTEXT_SIZE(vq))
 		return -EINVAL;
 
 	/*
@@ -404,23 +403,23 @@ static int restore_za_context(struct user_ctxs *user)
 	unsigned int vq;
 	struct za_context za;
 
+	if (user->za_size < sizeof(*user->za))
+		return -EINVAL;
+
 	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 (user->za_size == sizeof(*user->za)) {
 		current->thread.svcr &= ~SVCR_ZA_MASK;
 		return 0;
 	}
 
 	vq = sve_vq_from_vl(za.vl);
 
-	if (za.head.size < ZA_SIG_CONTEXT_SIZE(vq))
+	if (user->za_size < ZA_SIG_CONTEXT_SIZE(vq))
 		return -EINVAL;
 
 	/*
@@ -517,6 +516,7 @@ static int parse_user_sigframe(struct user_ctxs *user,
 				goto invalid;
 
 			user->fpsimd = (struct fpsimd_context __user *)head;
+			user->fpsimd_size = size;
 			break;
 
 		case ESR_MAGIC:
@@ -531,6 +531,7 @@ static int parse_user_sigframe(struct user_ctxs *user,
 				goto invalid;
 
 			user->sve = (struct sve_context __user *)head;
+			user->sve_size = size;
 			break;
 
 		case ZA_MAGIC:
@@ -541,6 +542,7 @@ static int parse_user_sigframe(struct user_ctxs *user,
 				goto invalid;
 
 			user->za = (struct za_context __user *)head;
+			user->za_size = size;
 			break;
 
 		case EXTRA_MAGIC:

-- 
2.30.2

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v2 5/6] arm64/signal: Only read new data when parsing the SVE context
  2023-01-03 20:25 [PATCH v2 0/6] arm64/signal: Signal handling cleanups Mark Brown
                   ` (3 preceding siblings ...)
  2023-01-03 20:25 ` [PATCH v2 4/6] arm64/signal: Avoid rereading context frame sizes Mark Brown
@ 2023-01-03 20:25 ` Mark Brown
  2023-01-03 20:25 ` [PATCH v2 6/6] arm64/signal: Only read new data when parsing the ZA context Mark Brown
  2023-01-31 12:51 ` [PATCH v2 0/6] arm64/signal: Signal handling cleanups Catalin Marinas
  6 siblings, 0 replies; 11+ messages in thread
From: Mark Brown @ 2023-01-03 20:25 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon; +Cc: linux-arm-kernel, linux-kernel, Mark Brown

When we parse the SVE signal context we read the entire context from
userspace, including the generic signal context header which was already
read by parse_user_sigframe() and padding bytes that we ignore. Avoid the
possibility of relying on the second read of the data read twice by only
reading the data which we are actually going to use.

Signed-off-by: Mark Brown <broonie@kernel.org>
---
 arch/arm64/kernel/signal.c | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index 82a89b0852ee..26192ab56de4 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -265,18 +265,20 @@ static int preserve_sve_context(struct sve_context __user *ctx)
 
 static int restore_sve_fpsimd_context(struct user_ctxs *user)
 {
-	int err;
+	int err = 0;
 	unsigned int vl, vq;
 	struct user_fpsimd_state fpsimd;
-	struct sve_context sve;
+	u16 user_vl, flags;
 
 	if (user->sve_size < sizeof(*user->sve))
 		return -EINVAL;
 
-	if (__copy_from_user(&sve, user->sve, sizeof(sve)))
-		return -EFAULT;
+	__get_user_error(user_vl, &(user->sve->vl), err);
+	__get_user_error(flags, &(user->sve->flags), err);
+	if (err)
+		return err;
 
-	if (sve.flags & SVE_SIG_FLAG_SM) {
+	if (flags & SVE_SIG_FLAG_SM) {
 		if (!system_supports_sme())
 			return -EINVAL;
 
@@ -288,7 +290,7 @@ static int restore_sve_fpsimd_context(struct user_ctxs *user)
 		vl = task_get_sve_vl(current);
 	}
 
-	if (sve.vl != vl)
+	if (user_vl != vl)
 		return -EINVAL;
 
 	if (user->sve_size == sizeof(*user->sve)) {
@@ -298,7 +300,7 @@ static int restore_sve_fpsimd_context(struct user_ctxs *user)
 		goto fpsimd_only;
 	}
 
-	vq = sve_vq_from_vl(sve.vl);
+	vq = sve_vq_from_vl(vl);
 
 	if (user->sve_size < SVE_SIG_CONTEXT_SIZE(vq))
 		return -EINVAL;
@@ -326,7 +328,7 @@ static int restore_sve_fpsimd_context(struct user_ctxs *user)
 	if (err)
 		return -EFAULT;
 
-	if (sve.flags & SVE_SIG_FLAG_SM)
+	if (flags & SVE_SIG_FLAG_SM)
 		current->thread.svcr |= SVCR_SM_MASK;
 	else
 		set_thread_flag(TIF_SVE);

-- 
2.30.2

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v2 6/6] arm64/signal: Only read new data when parsing the ZA context
  2023-01-03 20:25 [PATCH v2 0/6] arm64/signal: Signal handling cleanups Mark Brown
                   ` (4 preceding siblings ...)
  2023-01-03 20:25 ` [PATCH v2 5/6] arm64/signal: Only read new data when parsing the SVE context Mark Brown
@ 2023-01-03 20:25 ` Mark Brown
  2023-01-31 12:51 ` [PATCH v2 0/6] arm64/signal: Signal handling cleanups Catalin Marinas
  6 siblings, 0 replies; 11+ messages in thread
From: Mark Brown @ 2023-01-03 20:25 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon; +Cc: linux-arm-kernel, linux-kernel, Mark Brown

When we parse the ZA signal context we read the entire context from
userspace, including the generic signal context header which was already
read by parse_user_sigframe() and padding bytes that we ignore. Avoid the
possibility of relying on the second read of the data read twice by only
reading the data which we are actually going to use.

Signed-off-by: Mark Brown <broonie@kernel.org>
---
 arch/arm64/kernel/signal.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index 26192ab56de4..bed27d4f8ce9 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -401,17 +401,18 @@ static int preserve_za_context(struct za_context __user *ctx)
 
 static int restore_za_context(struct user_ctxs *user)
 {
-	int err;
+	int err = 0;
 	unsigned int vq;
-	struct za_context za;
+	u16 user_vl;
 
 	if (user->za_size < sizeof(*user->za))
 		return -EINVAL;
 
-	if (__copy_from_user(&za, user->za, sizeof(za)))
-		return -EFAULT;
+	__get_user_error(user_vl, &(user->za->vl), err);
+	if (err)
+		return err;
 
-	if (za.vl != task_get_sme_vl(current))
+	if (user_vl != task_get_sme_vl(current))
 		return -EINVAL;
 
 	if (user->za_size == sizeof(*user->za)) {
@@ -419,7 +420,7 @@ static int restore_za_context(struct user_ctxs *user)
 		return 0;
 	}
 
-	vq = sve_vq_from_vl(za.vl);
+	vq = sve_vq_from_vl(user_vl);
 
 	if (user->za_size < ZA_SIG_CONTEXT_SIZE(vq))
 		return -EINVAL;

-- 
2.30.2

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH v2 0/6] arm64/signal: Signal handling cleanups
  2023-01-03 20:25 [PATCH v2 0/6] arm64/signal: Signal handling cleanups Mark Brown
                   ` (5 preceding siblings ...)
  2023-01-03 20:25 ` [PATCH v2 6/6] arm64/signal: Only read new data when parsing the ZA context Mark Brown
@ 2023-01-31 12:51 ` Catalin Marinas
  2023-01-31 13:14   ` Mark Brown
  2023-01-31 15:38   ` Will Deacon
  6 siblings, 2 replies; 11+ messages in thread
From: Catalin Marinas @ 2023-01-31 12:51 UTC (permalink / raw)
  To: Mark Brown; +Cc: Will Deacon, linux-arm-kernel, linux-kernel

Hi Mark,

On Tue, Jan 03, 2023 at 08:25:15PM +0000, Mark Brown wrote:
> This series collects a number of small cleanups to the signal handling
> code which removes redundant validation of size information and avoids
> reading the same data from userspace twice.
> 
> There are some overlaps with both the TPIDR2 signal handling and SME2
> serieses which are also in flight, applying this will require
> adjustments in those serieses and vice versa.
[...]
> Mark Brown (6):
>       arm64/signal: Don't redundantly verify FPSIMD magic
>       arm64/signal: Remove redundant size validation from parse_user_sigframe()
>       arm64/signal: Make interface for restore_fpsimd_context() consistent

I'm fine with the first three patches, they seem correct and make the
frame checking more consistent.

>       arm64/signal: Avoid rereading context frame sizes
>       arm64/signal: Only read new data when parsing the SVE context
>       arm64/signal: Only read new data when parsing the ZA context

I'm not sure these add much to the code readability (and the performance
improvement I guess is negligible). We avoid some copy_from_user() into
the context structures but rely on data read previously or some
get_user() into local variables. Personally I'd make the
restore_fpsimd_context() also do a copy_from_user() for consistency with
the current sve and za frames restoring.

Personal preference, not sure whether Will has the same view.

-- 
Catalin

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v2 0/6] arm64/signal: Signal handling cleanups
  2023-01-31 12:51 ` [PATCH v2 0/6] arm64/signal: Signal handling cleanups Catalin Marinas
@ 2023-01-31 13:14   ` Mark Brown
  2023-01-31 15:38   ` Will Deacon
  1 sibling, 0 replies; 11+ messages in thread
From: Mark Brown @ 2023-01-31 13:14 UTC (permalink / raw)
  To: Catalin Marinas; +Cc: Will Deacon, linux-arm-kernel, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1024 bytes --]

On Tue, Jan 31, 2023 at 12:51:33PM +0000, Catalin Marinas wrote:
> On Tue, Jan 03, 2023 at 08:25:15PM +0000, Mark Brown wrote:

> >       arm64/signal: Avoid rereading context frame sizes
> >       arm64/signal: Only read new data when parsing the SVE context
> >       arm64/signal: Only read new data when parsing the ZA context

> I'm not sure these add much to the code readability (and the performance
> improvement I guess is negligible). We avoid some copy_from_user() into
> the context structures but rely on data read previously or some
> get_user() into local variables. Personally I'd make the
> restore_fpsimd_context() also do a copy_from_user() for consistency with
> the current sve and za frames restoring.

> Personal preference, not sure whether Will has the same view.

I don't particularly care about those changs either, Will seemed to be
asking for something like that.

Note that I should at some point today send a version of this series
rebased on for-next/core due to the TPIDR2 and SME2 changes.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v2 0/6] arm64/signal: Signal handling cleanups
  2023-01-31 12:51 ` [PATCH v2 0/6] arm64/signal: Signal handling cleanups Catalin Marinas
  2023-01-31 13:14   ` Mark Brown
@ 2023-01-31 15:38   ` Will Deacon
  2023-02-01 11:52     ` Catalin Marinas
  1 sibling, 1 reply; 11+ messages in thread
From: Will Deacon @ 2023-01-31 15:38 UTC (permalink / raw)
  To: Catalin Marinas; +Cc: Mark Brown, linux-arm-kernel, linux-kernel

On Tue, Jan 31, 2023 at 12:51:33PM +0000, Catalin Marinas wrote:
> Hi Mark,
> 
> On Tue, Jan 03, 2023 at 08:25:15PM +0000, Mark Brown wrote:
> > This series collects a number of small cleanups to the signal handling
> > code which removes redundant validation of size information and avoids
> > reading the same data from userspace twice.
> > 
> > There are some overlaps with both the TPIDR2 signal handling and SME2
> > serieses which are also in flight, applying this will require
> > adjustments in those serieses and vice versa.
> [...]
> > Mark Brown (6):
> >       arm64/signal: Don't redundantly verify FPSIMD magic
> >       arm64/signal: Remove redundant size validation from parse_user_sigframe()
> >       arm64/signal: Make interface for restore_fpsimd_context() consistent
> 
> I'm fine with the first three patches, they seem correct and make the
> frame checking more consistent.
> 
> >       arm64/signal: Avoid rereading context frame sizes
> >       arm64/signal: Only read new data when parsing the SVE context
> >       arm64/signal: Only read new data when parsing the ZA context
> 
> I'm not sure these add much to the code readability (and the performance
> improvement I guess is negligible). We avoid some copy_from_user() into
> the context structures but rely on data read previously or some
> get_user() into local variables. Personally I'd make the
> restore_fpsimd_context() also do a copy_from_user() for consistency with
> the current sve and za frames restoring.
> 
> Personal preference, not sure whether Will has the same view.

That main thing I'm worried about is the potential for ToCToU bugs if we
read userdata more than once. For example, if we end up splitting checks
between the two reads, then an attacker could update the value in the
middle and potential cause us issues. If we just read the stuff once, we
don't have to worry about that.

Will

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v2 0/6] arm64/signal: Signal handling cleanups
  2023-01-31 15:38   ` Will Deacon
@ 2023-02-01 11:52     ` Catalin Marinas
  0 siblings, 0 replies; 11+ messages in thread
From: Catalin Marinas @ 2023-02-01 11:52 UTC (permalink / raw)
  To: Will Deacon; +Cc: Mark Brown, linux-arm-kernel, linux-kernel

On Tue, Jan 31, 2023 at 03:38:16PM +0000, Will Deacon wrote:
> On Tue, Jan 31, 2023 at 12:51:33PM +0000, Catalin Marinas wrote:
> > Hi Mark,
> > 
> > On Tue, Jan 03, 2023 at 08:25:15PM +0000, Mark Brown wrote:
> > > This series collects a number of small cleanups to the signal handling
> > > code which removes redundant validation of size information and avoids
> > > reading the same data from userspace twice.
> > > 
> > > There are some overlaps with both the TPIDR2 signal handling and SME2
> > > serieses which are also in flight, applying this will require
> > > adjustments in those serieses and vice versa.
> > [...]
> > > Mark Brown (6):
> > >       arm64/signal: Don't redundantly verify FPSIMD magic
> > >       arm64/signal: Remove redundant size validation from parse_user_sigframe()
> > >       arm64/signal: Make interface for restore_fpsimd_context() consistent
> > 
> > I'm fine with the first three patches, they seem correct and make the
> > frame checking more consistent.
> > 
> > >       arm64/signal: Avoid rereading context frame sizes
> > >       arm64/signal: Only read new data when parsing the SVE context
> > >       arm64/signal: Only read new data when parsing the ZA context
> > 
> > I'm not sure these add much to the code readability (and the performance
> > improvement I guess is negligible). We avoid some copy_from_user() into
> > the context structures but rely on data read previously or some
> > get_user() into local variables. Personally I'd make the
> > restore_fpsimd_context() also do a copy_from_user() for consistency with
> > the current sve and za frames restoring.
> > 
> > Personal preference, not sure whether Will has the same view.
> 
> That main thing I'm worried about is the potential for ToCToU bugs if we
> read userdata more than once. For example, if we end up splitting checks
> between the two reads, then an attacker could update the value in the
> middle and potential cause us issues. If we just read the stuff once, we
> don't have to worry about that.

I thought this may be the case but I couldn't come up with an exploit.
The actual size validation is done after the second read. The first read
of the size is used to walk the frame and check the magic values.

Anyway, you are probably right, it's easier to reason about ToCToU if we
only read the size once.

-- 
Catalin

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2023-02-01 11:52 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-01-03 20:25 [PATCH v2 0/6] arm64/signal: Signal handling cleanups Mark Brown
2023-01-03 20:25 ` [PATCH v2 1/6] arm64/signal: Don't redundantly verify FPSIMD magic Mark Brown
2023-01-03 20:25 ` [PATCH v2 2/6] arm64/signal: Remove redundant size validation from parse_user_sigframe() Mark Brown
2023-01-03 20:25 ` [PATCH v2 3/6] arm64/signal: Make interface for restore_fpsimd_context() consistent Mark Brown
2023-01-03 20:25 ` [PATCH v2 4/6] arm64/signal: Avoid rereading context frame sizes Mark Brown
2023-01-03 20:25 ` [PATCH v2 5/6] arm64/signal: Only read new data when parsing the SVE context Mark Brown
2023-01-03 20:25 ` [PATCH v2 6/6] arm64/signal: Only read new data when parsing the ZA context Mark Brown
2023-01-31 12:51 ` [PATCH v2 0/6] arm64/signal: Signal handling cleanups Catalin Marinas
2023-01-31 13:14   ` Mark Brown
2023-01-31 15:38   ` Will Deacon
2023-02-01 11:52     ` Catalin Marinas

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).