@@ -170,6 +170,19 @@ static void __user *apply_user_offset(
170
170
return base + offset ;
171
171
}
172
172
173
+ struct user_ctxs {
174
+ struct fpsimd_context __user * fpsimd ;
175
+ u32 fpsimd_size ;
176
+ struct sve_context __user * sve ;
177
+ u32 sve_size ;
178
+ struct tpidr2_context __user * tpidr2 ;
179
+ u32 tpidr2_size ;
180
+ struct za_context __user * za ;
181
+ u32 za_size ;
182
+ struct zt_context __user * zt ;
183
+ u32 zt_size ;
184
+ };
185
+
173
186
static int preserve_fpsimd_context (struct fpsimd_context __user * ctx )
174
187
{
175
188
struct user_fpsimd_state const * fpsimd =
@@ -188,25 +201,20 @@ static int preserve_fpsimd_context(struct fpsimd_context __user *ctx)
188
201
return err ? - EFAULT : 0 ;
189
202
}
190
203
191
- static int restore_fpsimd_context (struct fpsimd_context __user * ctx )
204
+ static int restore_fpsimd_context (struct user_ctxs * user )
192
205
{
193
206
struct user_fpsimd_state fpsimd ;
194
- __u32 magic , size ;
195
207
int err = 0 ;
196
208
197
- /* check the magic/size information */
198
- __get_user_error (magic , & ctx -> head .magic , err );
199
- __get_user_error (size , & ctx -> head .size , err );
200
- if (err )
201
- return - EFAULT ;
202
- if (magic != FPSIMD_MAGIC || size != sizeof (struct fpsimd_context ))
209
+ /* check the size information */
210
+ if (user -> fpsimd_size != sizeof (struct fpsimd_context ))
203
211
return - EINVAL ;
204
212
205
213
/* copy the FP and status/control registers */
206
- err = __copy_from_user (fpsimd .vregs , ctx -> vregs ,
214
+ err = __copy_from_user (fpsimd .vregs , & ( user -> fpsimd -> vregs ) ,
207
215
sizeof (fpsimd .vregs ));
208
- __get_user_error (fpsimd .fpsr , & ctx -> fpsr , err );
209
- __get_user_error (fpsimd .fpcr , & ctx -> fpcr , err );
216
+ __get_user_error (fpsimd .fpsr , & ( user -> fpsimd -> fpsr ) , err );
217
+ __get_user_error (fpsimd .fpcr , & ( user -> fpsimd -> fpcr ) , err );
210
218
211
219
clear_thread_flag (TIF_SVE );
212
220
current -> thread .fp_type = FP_STATE_FPSIMD ;
@@ -219,14 +227,6 @@ static int restore_fpsimd_context(struct fpsimd_context __user *ctx)
219
227
}
220
228
221
229
222
- struct user_ctxs {
223
- struct fpsimd_context __user * fpsimd ;
224
- struct sve_context __user * sve ;
225
- struct tpidr2_context __user * tpidr2 ;
226
- struct za_context __user * za ;
227
- struct zt_context __user * zt ;
228
- };
229
-
230
230
#ifdef CONFIG_ARM64_SVE
231
231
232
232
static int preserve_sve_context (struct sve_context __user * ctx )
@@ -271,15 +271,20 @@ static int preserve_sve_context(struct sve_context __user *ctx)
271
271
272
272
static int restore_sve_fpsimd_context (struct user_ctxs * user )
273
273
{
274
- int err ;
274
+ int err = 0 ;
275
275
unsigned int vl , vq ;
276
276
struct user_fpsimd_state fpsimd ;
277
- struct sve_context sve ;
277
+ u16 user_vl , flags ;
278
278
279
- if (__copy_from_user (& sve , user -> sve , sizeof (sve )))
280
- return - EFAULT ;
279
+ if (user -> sve_size < sizeof (* user -> sve ))
280
+ return - EINVAL ;
281
+
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 ;
281
286
282
- if (sve . flags & SVE_SIG_FLAG_SM ) {
287
+ if (flags & SVE_SIG_FLAG_SM ) {
283
288
if (!system_supports_sme ())
284
289
return - EINVAL ;
285
290
@@ -291,19 +296,19 @@ static int restore_sve_fpsimd_context(struct user_ctxs *user)
291
296
vl = task_get_sve_vl (current );
292
297
}
293
298
294
- if (sve . vl != vl )
299
+ if (user_vl != vl )
295
300
return - EINVAL ;
296
301
297
- if (sve . head . size < = sizeof (* user -> sve )) {
302
+ if (user -> sve_size = = sizeof (* user -> sve )) {
298
303
clear_thread_flag (TIF_SVE );
299
304
current -> thread .svcr &= ~SVCR_SM_MASK ;
300
305
current -> thread .fp_type = FP_STATE_FPSIMD ;
301
306
goto fpsimd_only ;
302
307
}
303
308
304
- vq = sve_vq_from_vl (sve . vl );
309
+ vq = sve_vq_from_vl (vl );
305
310
306
- if (sve . head . size < SVE_SIG_CONTEXT_SIZE (vq ))
311
+ if (user -> sve_size < SVE_SIG_CONTEXT_SIZE (vq ))
307
312
return - EINVAL ;
308
313
309
314
/*
@@ -329,7 +334,7 @@ static int restore_sve_fpsimd_context(struct user_ctxs *user)
329
334
if (err )
330
335
return - EFAULT ;
331
336
332
- if (sve . flags & SVE_SIG_FLAG_SM )
337
+ if (flags & SVE_SIG_FLAG_SM )
333
338
current -> thread .svcr |= SVCR_SM_MASK ;
334
339
else
335
340
set_thread_flag (TIF_SVE );
@@ -383,7 +388,9 @@ static int restore_tpidr2_context(struct user_ctxs *user)
383
388
u64 tpidr2_el0 ;
384
389
int err = 0 ;
385
390
386
- /* Magic and size were validated deciding to call this function */
391
+ if (user -> tpidr2_size != sizeof (* user -> tpidr2 ))
392
+ return - EINVAL ;
393
+
387
394
__get_user_error (tpidr2_el0 , & user -> tpidr2 -> tpidr2 , err );
388
395
if (!err )
389
396
current -> thread .tpidr2_el0 = tpidr2_el0 ;
@@ -428,24 +435,28 @@ static int preserve_za_context(struct za_context __user *ctx)
428
435
429
436
static int restore_za_context (struct user_ctxs * user )
430
437
{
431
- int err ;
438
+ int err = 0 ;
432
439
unsigned int vq ;
433
- struct za_context za ;
440
+ u16 user_vl ;
434
441
435
- if (__copy_from_user (& za , user -> za , sizeof (za )))
436
- return - EFAULT ;
442
+ if (user -> za_size < sizeof (* user -> za ))
443
+ return - EINVAL ;
444
+
445
+ __get_user_error (user_vl , & (user -> za -> vl ), err );
446
+ if (err )
447
+ return err ;
437
448
438
- if (za . vl != task_get_sme_vl (current ))
449
+ if (user_vl != task_get_sme_vl (current ))
439
450
return - EINVAL ;
440
451
441
- if (za . head . size < = sizeof (* user -> za )) {
452
+ if (user -> za_size = = sizeof (* user -> za )) {
442
453
current -> thread .svcr &= ~SVCR_ZA_MASK ;
443
454
return 0 ;
444
455
}
445
456
446
- vq = sve_vq_from_vl (za . vl );
457
+ vq = sve_vq_from_vl (user_vl );
447
458
448
- if (za . head . size < ZA_SIG_CONTEXT_SIZE (vq ))
459
+ if (user -> za_size < ZA_SIG_CONTEXT_SIZE (vq ))
449
460
return - EINVAL ;
450
461
451
462
/*
@@ -510,19 +521,19 @@ static int preserve_zt_context(struct zt_context __user *ctx)
510
521
static int restore_zt_context (struct user_ctxs * user )
511
522
{
512
523
int err ;
513
- struct zt_context zt ;
524
+ u16 nregs ;
514
525
515
526
/* ZA must be restored first for this check to be valid */
516
527
if (!thread_za_enabled (& current -> thread ))
517
528
return - EINVAL ;
518
529
519
- if (__copy_from_user (& zt , user -> zt , sizeof (zt )))
520
- return - EFAULT ;
521
-
522
- if (zt .nregs != 1 )
530
+ if (user -> zt_size != ZT_SIG_CONTEXT_SIZE (1 ))
523
531
return - EINVAL ;
524
532
525
- if (zt .head .size != ZT_SIG_CONTEXT_SIZE (zt .nregs ))
533
+ if (__copy_from_user (& nregs , & (user -> zt -> nregs ), sizeof (nregs )))
534
+ return - EFAULT ;
535
+
536
+ if (nregs != 1 )
526
537
return - EINVAL ;
527
538
528
539
/*
@@ -615,10 +626,8 @@ static int parse_user_sigframe(struct user_ctxs *user,
615
626
if (user -> fpsimd )
616
627
goto invalid ;
617
628
618
- if (size < sizeof (* user -> fpsimd ))
619
- goto invalid ;
620
-
621
629
user -> fpsimd = (struct fpsimd_context __user * )head ;
630
+ user -> fpsimd_size = size ;
622
631
break ;
623
632
624
633
case ESR_MAGIC :
@@ -632,10 +641,8 @@ static int parse_user_sigframe(struct user_ctxs *user,
632
641
if (user -> sve )
633
642
goto invalid ;
634
643
635
- if (size < sizeof (* user -> sve ))
636
- goto invalid ;
637
-
638
644
user -> sve = (struct sve_context __user * )head ;
645
+ user -> sve_size = size ;
639
646
break ;
640
647
641
648
case TPIDR2_MAGIC :
@@ -645,10 +652,8 @@ static int parse_user_sigframe(struct user_ctxs *user,
645
652
if (user -> tpidr2 )
646
653
goto invalid ;
647
654
648
- if (size != sizeof (* user -> tpidr2 ))
649
- goto invalid ;
650
-
651
655
user -> tpidr2 = (struct tpidr2_context __user * )head ;
656
+ user -> tpidr2_size = size ;
652
657
break ;
653
658
654
659
case ZA_MAGIC :
@@ -658,10 +663,8 @@ static int parse_user_sigframe(struct user_ctxs *user,
658
663
if (user -> za )
659
664
goto invalid ;
660
665
661
- if (size < sizeof (* user -> za ))
662
- goto invalid ;
663
-
664
666
user -> za = (struct za_context __user * )head ;
667
+ user -> za_size = size ;
665
668
break ;
666
669
667
670
case ZT_MAGIC :
@@ -671,10 +674,8 @@ static int parse_user_sigframe(struct user_ctxs *user,
671
674
if (user -> zt )
672
675
goto invalid ;
673
676
674
- if (size < sizeof (* user -> zt ))
675
- goto invalid ;
676
-
677
677
user -> zt = (struct zt_context __user * )head ;
678
+ user -> zt_size = size ;
678
679
break ;
679
680
680
681
case EXTRA_MAGIC :
@@ -793,7 +794,7 @@ static int restore_sigframe(struct pt_regs *regs,
793
794
if (user .sve )
794
795
err = restore_sve_fpsimd_context (& user );
795
796
else
796
- err = restore_fpsimd_context (user . fpsimd );
797
+ err = restore_fpsimd_context (& user );
797
798
}
798
799
799
800
if (err == 0 && system_supports_sme () && user .tpidr2 )
0 commit comments