Skip to content

Commit f3ac48a

Browse files
brooniectmarinas
authored andcommitted
arm64/signal: Only read new data when parsing the SVE context
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 <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Catalin Marinas <[email protected]>
1 parent b57682b commit f3ac48a

File tree

1 file changed

+10
-8
lines changed

1 file changed

+10
-8
lines changed

arch/arm64/kernel/signal.c

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -271,18 +271,20 @@ static int preserve_sve_context(struct sve_context __user *ctx)
271271

272272
static int restore_sve_fpsimd_context(struct user_ctxs *user)
273273
{
274-
int err;
274+
int err = 0;
275275
unsigned int vl, vq;
276276
struct user_fpsimd_state fpsimd;
277-
struct sve_context sve;
277+
u16 user_vl, flags;
278278

279279
if (user->sve_size < sizeof(*user->sve))
280280
return -EINVAL;
281281

282-
if (__copy_from_user(&sve, user->sve, sizeof(sve)))
283-
return -EFAULT;
282+
__get_user_error(user_vl, &(user->sve->vl), err);
283+
__get_user_error(flags, &(user->sve->flags), err);
284+
if (err)
285+
return err;
284286

285-
if (sve.flags & SVE_SIG_FLAG_SM) {
287+
if (flags & SVE_SIG_FLAG_SM) {
286288
if (!system_supports_sme())
287289
return -EINVAL;
288290

@@ -294,7 +296,7 @@ static int restore_sve_fpsimd_context(struct user_ctxs *user)
294296
vl = task_get_sve_vl(current);
295297
}
296298

297-
if (sve.vl != vl)
299+
if (user_vl != vl)
298300
return -EINVAL;
299301

300302
if (user->sve_size == sizeof(*user->sve)) {
@@ -304,7 +306,7 @@ static int restore_sve_fpsimd_context(struct user_ctxs *user)
304306
goto fpsimd_only;
305307
}
306308

307-
vq = sve_vq_from_vl(sve.vl);
309+
vq = sve_vq_from_vl(vl);
308310

309311
if (user->sve_size < SVE_SIG_CONTEXT_SIZE(vq))
310312
return -EINVAL;
@@ -332,7 +334,7 @@ static int restore_sve_fpsimd_context(struct user_ctxs *user)
332334
if (err)
333335
return -EFAULT;
334336

335-
if (sve.flags & SVE_SIG_FLAG_SM)
337+
if (flags & SVE_SIG_FLAG_SM)
336338
current->thread.svcr |= SVCR_SM_MASK;
337339
else
338340
set_thread_flag(TIF_SVE);

0 commit comments

Comments
 (0)