@@ -172,10 +172,15 @@ static void __user *apply_user_offset(
172
172
173
173
struct user_ctxs {
174
174
struct fpsimd_context __user * fpsimd ;
175
+ u32 fpsimd_size ;
175
176
struct sve_context __user * sve ;
177
+ u32 sve_size ;
176
178
struct tpidr2_context __user * tpidr2 ;
179
+ u32 tpidr2_size ;
177
180
struct za_context __user * za ;
181
+ u32 za_size ;
178
182
struct zt_context __user * zt ;
183
+ u32 zt_size ;
179
184
};
180
185
181
186
static int preserve_fpsimd_context (struct fpsimd_context __user * ctx )
@@ -199,14 +204,10 @@ static int preserve_fpsimd_context(struct fpsimd_context __user *ctx)
199
204
static int restore_fpsimd_context (struct user_ctxs * user )
200
205
{
201
206
struct user_fpsimd_state fpsimd ;
202
- __u32 size ;
203
207
int err = 0 ;
204
208
205
209
/* check the size information */
206
- __get_user_error (size , & user -> fpsimd -> head .size , err );
207
- if (err )
208
- return - EFAULT ;
209
- if (size != sizeof (struct fpsimd_context ))
210
+ if (user -> fpsimd_size != sizeof (struct fpsimd_context ))
210
211
return - EINVAL ;
211
212
212
213
/* copy the FP and status/control registers */
@@ -275,12 +276,12 @@ static int restore_sve_fpsimd_context(struct user_ctxs *user)
275
276
struct user_fpsimd_state fpsimd ;
276
277
struct sve_context sve ;
277
278
279
+ if (user -> sve_size < sizeof (* user -> sve ))
280
+ return - EINVAL ;
281
+
278
282
if (__copy_from_user (& sve , user -> sve , sizeof (sve )))
279
283
return - EFAULT ;
280
284
281
- if (sve .head .size < sizeof (* user -> sve ))
282
- return - EINVAL ;
283
-
284
285
if (sve .flags & SVE_SIG_FLAG_SM ) {
285
286
if (!system_supports_sme ())
286
287
return - EINVAL ;
@@ -296,7 +297,7 @@ static int restore_sve_fpsimd_context(struct user_ctxs *user)
296
297
if (sve .vl != vl )
297
298
return - EINVAL ;
298
299
299
- if (sve . head . size == sizeof (* user -> sve )) {
300
+ if (user -> sve_size == sizeof (* user -> sve )) {
300
301
clear_thread_flag (TIF_SVE );
301
302
current -> thread .svcr &= ~SVCR_SM_MASK ;
302
303
current -> thread .fp_type = FP_STATE_FPSIMD ;
@@ -305,7 +306,7 @@ static int restore_sve_fpsimd_context(struct user_ctxs *user)
305
306
306
307
vq = sve_vq_from_vl (sve .vl );
307
308
308
- if (sve . head . size < SVE_SIG_CONTEXT_SIZE (vq ))
309
+ if (user -> sve_size < SVE_SIG_CONTEXT_SIZE (vq ))
309
310
return - EINVAL ;
310
311
311
312
/*
@@ -385,7 +386,9 @@ static int restore_tpidr2_context(struct user_ctxs *user)
385
386
u64 tpidr2_el0 ;
386
387
int err = 0 ;
387
388
388
- /* Magic and size were validated deciding to call this function */
389
+ if (user -> tpidr2_size != sizeof (* user -> tpidr2 ))
390
+ return - EINVAL ;
391
+
389
392
__get_user_error (tpidr2_el0 , & user -> tpidr2 -> tpidr2 , err );
390
393
if (!err )
391
394
current -> thread .tpidr2_el0 = tpidr2_el0 ;
@@ -434,23 +437,23 @@ static int restore_za_context(struct user_ctxs *user)
434
437
unsigned int vq ;
435
438
struct za_context za ;
436
439
440
+ if (user -> za_size < sizeof (* user -> za ))
441
+ return - EINVAL ;
442
+
437
443
if (__copy_from_user (& za , user -> za , sizeof (za )))
438
444
return - EFAULT ;
439
445
440
- if (za .head .size < sizeof (* user -> za ))
441
- return - EINVAL ;
442
-
443
446
if (za .vl != task_get_sme_vl (current ))
444
447
return - EINVAL ;
445
448
446
- if (za . head . size == sizeof (* user -> za )) {
449
+ if (user -> za_size == sizeof (* user -> za )) {
447
450
current -> thread .svcr &= ~SVCR_ZA_MASK ;
448
451
return 0 ;
449
452
}
450
453
451
454
vq = sve_vq_from_vl (za .vl );
452
455
453
- if (za . head . size < ZA_SIG_CONTEXT_SIZE (vq ))
456
+ if (user -> za_size < ZA_SIG_CONTEXT_SIZE (vq ))
454
457
return - EINVAL ;
455
458
456
459
/*
@@ -521,15 +524,15 @@ static int restore_zt_context(struct user_ctxs *user)
521
524
if (!thread_za_enabled (& current -> thread ))
522
525
return - EINVAL ;
523
526
527
+ if (user -> zt_size != ZT_SIG_CONTEXT_SIZE (1 ))
528
+ return - EINVAL ;
529
+
524
530
if (__copy_from_user (& zt , user -> zt , sizeof (zt )))
525
531
return - EFAULT ;
526
532
527
533
if (zt .nregs != 1 )
528
534
return - EINVAL ;
529
535
530
- if (zt .head .size != ZT_SIG_CONTEXT_SIZE (zt .nregs ))
531
- return - EINVAL ;
532
-
533
536
/*
534
537
* Careful: we are about __copy_from_user() directly into
535
538
* thread.zt_state with preemption enabled, so protection is
@@ -621,6 +624,7 @@ static int parse_user_sigframe(struct user_ctxs *user,
621
624
goto invalid ;
622
625
623
626
user -> fpsimd = (struct fpsimd_context __user * )head ;
627
+ user -> fpsimd_size = size ;
624
628
break ;
625
629
626
630
case ESR_MAGIC :
@@ -635,6 +639,7 @@ static int parse_user_sigframe(struct user_ctxs *user,
635
639
goto invalid ;
636
640
637
641
user -> sve = (struct sve_context __user * )head ;
642
+ user -> sve_size = size ;
638
643
break ;
639
644
640
645
case TPIDR2_MAGIC :
@@ -644,10 +649,8 @@ static int parse_user_sigframe(struct user_ctxs *user,
644
649
if (user -> tpidr2 )
645
650
goto invalid ;
646
651
647
- if (size != sizeof (* user -> tpidr2 ))
648
- goto invalid ;
649
-
650
652
user -> tpidr2 = (struct tpidr2_context __user * )head ;
653
+ user -> tpidr2_size = size ;
651
654
break ;
652
655
653
656
case ZA_MAGIC :
@@ -658,6 +661,7 @@ static int parse_user_sigframe(struct user_ctxs *user,
658
661
goto invalid ;
659
662
660
663
user -> za = (struct za_context __user * )head ;
664
+ user -> za_size = size ;
661
665
break ;
662
666
663
667
case ZT_MAGIC :
@@ -667,10 +671,8 @@ static int parse_user_sigframe(struct user_ctxs *user,
667
671
if (user -> zt )
668
672
goto invalid ;
669
673
670
- if (size < sizeof (* user -> zt ))
671
- goto invalid ;
672
-
673
674
user -> zt = (struct zt_context __user * )head ;
675
+ user -> zt_size = size ;
674
676
break ;
675
677
676
678
case EXTRA_MAGIC :
0 commit comments