@@ -172,10 +172,15 @@ static void __user *apply_user_offset(
172172
173173struct user_ctxs {
174174 struct fpsimd_context __user * fpsimd ;
175+ u32 fpsimd_size ;
175176 struct sve_context __user * sve ;
177+ u32 sve_size ;
176178 struct tpidr2_context __user * tpidr2 ;
179+ u32 tpidr2_size ;
177180 struct za_context __user * za ;
181+ u32 za_size ;
178182 struct zt_context __user * zt ;
183+ u32 zt_size ;
179184};
180185
181186static int preserve_fpsimd_context (struct fpsimd_context __user * ctx )
@@ -199,14 +204,10 @@ static int preserve_fpsimd_context(struct fpsimd_context __user *ctx)
199204static int restore_fpsimd_context (struct user_ctxs * user )
200205{
201206 struct user_fpsimd_state fpsimd ;
202- __u32 size ;
203207 int err = 0 ;
204208
205209 /* 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 ))
210211 return - EINVAL ;
211212
212213 /* copy the FP and status/control registers */
@@ -275,12 +276,12 @@ static int restore_sve_fpsimd_context(struct user_ctxs *user)
275276 struct user_fpsimd_state fpsimd ;
276277 struct sve_context sve ;
277278
279+ if (user -> sve_size < sizeof (* user -> sve ))
280+ return - EINVAL ;
281+
278282 if (__copy_from_user (& sve , user -> sve , sizeof (sve )))
279283 return - EFAULT ;
280284
281- if (sve .head .size < sizeof (* user -> sve ))
282- return - EINVAL ;
283-
284285 if (sve .flags & SVE_SIG_FLAG_SM ) {
285286 if (!system_supports_sme ())
286287 return - EINVAL ;
@@ -296,7 +297,7 @@ static int restore_sve_fpsimd_context(struct user_ctxs *user)
296297 if (sve .vl != vl )
297298 return - EINVAL ;
298299
299- if (sve . head . size == sizeof (* user -> sve )) {
300+ if (user -> sve_size == sizeof (* user -> sve )) {
300301 clear_thread_flag (TIF_SVE );
301302 current -> thread .svcr &= ~SVCR_SM_MASK ;
302303 current -> thread .fp_type = FP_STATE_FPSIMD ;
@@ -305,7 +306,7 @@ static int restore_sve_fpsimd_context(struct user_ctxs *user)
305306
306307 vq = sve_vq_from_vl (sve .vl );
307308
308- if (sve . head . size < SVE_SIG_CONTEXT_SIZE (vq ))
309+ if (user -> sve_size < SVE_SIG_CONTEXT_SIZE (vq ))
309310 return - EINVAL ;
310311
311312 /*
@@ -385,7 +386,9 @@ static int restore_tpidr2_context(struct user_ctxs *user)
385386 u64 tpidr2_el0 ;
386387 int err = 0 ;
387388
388- /* Magic and size were validated deciding to call this function */
389+ if (user -> tpidr2_size != sizeof (* user -> tpidr2 ))
390+ return - EINVAL ;
391+
389392 __get_user_error (tpidr2_el0 , & user -> tpidr2 -> tpidr2 , err );
390393 if (!err )
391394 current -> thread .tpidr2_el0 = tpidr2_el0 ;
@@ -434,23 +437,23 @@ static int restore_za_context(struct user_ctxs *user)
434437 unsigned int vq ;
435438 struct za_context za ;
436439
440+ if (user -> za_size < sizeof (* user -> za ))
441+ return - EINVAL ;
442+
437443 if (__copy_from_user (& za , user -> za , sizeof (za )))
438444 return - EFAULT ;
439445
440- if (za .head .size < sizeof (* user -> za ))
441- return - EINVAL ;
442-
443446 if (za .vl != task_get_sme_vl (current ))
444447 return - EINVAL ;
445448
446- if (za . head . size == sizeof (* user -> za )) {
449+ if (user -> za_size == sizeof (* user -> za )) {
447450 current -> thread .svcr &= ~SVCR_ZA_MASK ;
448451 return 0 ;
449452 }
450453
451454 vq = sve_vq_from_vl (za .vl );
452455
453- if (za . head . size < ZA_SIG_CONTEXT_SIZE (vq ))
456+ if (user -> za_size < ZA_SIG_CONTEXT_SIZE (vq ))
454457 return - EINVAL ;
455458
456459 /*
@@ -521,15 +524,15 @@ static int restore_zt_context(struct user_ctxs *user)
521524 if (!thread_za_enabled (& current -> thread ))
522525 return - EINVAL ;
523526
527+ if (user -> zt_size != ZT_SIG_CONTEXT_SIZE (1 ))
528+ return - EINVAL ;
529+
524530 if (__copy_from_user (& zt , user -> zt , sizeof (zt )))
525531 return - EFAULT ;
526532
527533 if (zt .nregs != 1 )
528534 return - EINVAL ;
529535
530- if (zt .head .size != ZT_SIG_CONTEXT_SIZE (zt .nregs ))
531- return - EINVAL ;
532-
533536 /*
534537 * Careful: we are about __copy_from_user() directly into
535538 * thread.zt_state with preemption enabled, so protection is
@@ -621,6 +624,7 @@ static int parse_user_sigframe(struct user_ctxs *user,
621624 goto invalid ;
622625
623626 user -> fpsimd = (struct fpsimd_context __user * )head ;
627+ user -> fpsimd_size = size ;
624628 break ;
625629
626630 case ESR_MAGIC :
@@ -635,6 +639,7 @@ static int parse_user_sigframe(struct user_ctxs *user,
635639 goto invalid ;
636640
637641 user -> sve = (struct sve_context __user * )head ;
642+ user -> sve_size = size ;
638643 break ;
639644
640645 case TPIDR2_MAGIC :
@@ -644,10 +649,8 @@ static int parse_user_sigframe(struct user_ctxs *user,
644649 if (user -> tpidr2 )
645650 goto invalid ;
646651
647- if (size != sizeof (* user -> tpidr2 ))
648- goto invalid ;
649-
650652 user -> tpidr2 = (struct tpidr2_context __user * )head ;
653+ user -> tpidr2_size = size ;
651654 break ;
652655
653656 case ZA_MAGIC :
@@ -658,6 +661,7 @@ static int parse_user_sigframe(struct user_ctxs *user,
658661 goto invalid ;
659662
660663 user -> za = (struct za_context __user * )head ;
664+ user -> za_size = size ;
661665 break ;
662666
663667 case ZT_MAGIC :
@@ -667,10 +671,8 @@ static int parse_user_sigframe(struct user_ctxs *user,
667671 if (user -> zt )
668672 goto invalid ;
669673
670- if (size < sizeof (* user -> zt ))
671- goto invalid ;
672-
673674 user -> zt = (struct zt_context __user * )head ;
675+ user -> zt_size = size ;
674676 break ;
675677
676678 case EXTRA_MAGIC :
0 commit comments