Re: arm64: fp-stress: BUG: KFENCE: memory corruption in fpsimd_release_task

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I don't know this code at all so probably this is dumb...  I don't
undestand how vec_set_vector_length() ensures that sme_state_size()
stays in sync with the actual size allocated in sme_alloc()

arch/arm64/kernel/fpsimd.c
   847  int vec_set_vector_length(struct task_struct *task, enum vec_type type,
   848                            unsigned long vl, unsigned long flags)
                                               ^^^
"vl" comes from the user and is 0-u16max.

   849  {
   850          if (flags & ~(unsigned long)(PR_SVE_VL_INHERIT |
   851                                       PR_SVE_SET_VL_ONEXEC))
   852                  return -EINVAL;
   853  
   854          if (!sve_vl_valid(vl))

valid values are '16-8192'

   855                  return -EINVAL;
   856  
   857          /*
   858           * Clamp to the maximum vector length that VL-agnostic code
   859           * can work with.  A flag may be assigned in the future to
   860           * allow setting of larger vector lengths without confusing
   861           * older software.
   862           */
   863          if (vl > VL_ARCH_MAX)
   864                  vl = VL_ARCH_MAX;

Now 16-256'

   865  
   866          vl = find_supported_vector_length(type, vl);

type is ARM64_VEC_SVE.  I've looked at this function for a while and
I don't see anything which ensures that "vl" is less than the current
value.

   867  
   868          if (flags & (PR_SVE_VL_INHERIT |
   869                       PR_SVE_SET_VL_ONEXEC))
   870                  task_set_vl_onexec(task, type, vl);
   871          else
   872                  /* Reset VL to system default on next exec: */
   873                  task_set_vl_onexec(task, type, 0);
   874  
   875          /* Only actually set the VL if not deferred: */
   876          if (flags & PR_SVE_SET_VL_ONEXEC)

Assume the PR_SVE_SET_VL_ONEXEC flag is not set.

   877                  goto out;
   878  
   879          if (vl == task_get_vl(task, type))

This checks if the flag is == and if so we are done.

   880                  goto out;
   881  
   882          /*
   883           * To ensure the FPSIMD bits of the SVE vector registers are preserved,
   884           * write any live register state back to task_struct, and convert to a
   885           * regular FPSIMD thread.
   886           */
   887          if (task == current) {
   888                  get_cpu_fpsimd_context();
   889  
   890                  fpsimd_save();
   891          }
   892  
   893          fpsimd_flush_task_state(task);
   894          if (test_and_clear_tsk_thread_flag(task, TIF_SVE) ||
   895              thread_sm_enabled(&task->thread)) {
   896                  sve_to_fpsimd(task);
   897                  task->thread.fp_type = FP_STATE_FPSIMD;
   898          }
   899  
   900          if (system_supports_sme() && type == ARM64_VEC_SME) {
   901                  task->thread.svcr &= ~(SVCR_SM_MASK |
   902                                         SVCR_ZA_MASK);
   903                  clear_thread_flag(TIF_SME);
   904          }
   905  
   906          if (task == current)
   907                  put_cpu_fpsimd_context();
   908  
   909          /*
   910           * Force reallocation of task SVE and SME state to the correct
   911           * size on next use:
   912           */
   913          sve_free(task);
   914          if (system_supports_sme() && type == ARM64_VEC_SME)
   915                  sme_free(task);
   916  
   917          task_set_vl(task, type, vl);

"vl" is set here.  This is fine if we are setting it to a smaller value,
but if we are setting it to a larger value then I think we need to
realloc the ->sme_state buffer.

When we call sme_alloc() it will say the buffer is already allocated
and just zero out what we need for "vl", but the existing buffer is too
small.

   918  
   919  out:
   920          update_tsk_thread_flag(task, vec_vl_inherit_flag(type),
   922  
   923          return 0;
   924  }

regards,
dan carpenter



[Index of Archives]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Share Photos]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]

  Powered by Linux