Re: [PATCH v8 08/10] x86, mpx: add prctl commands PR_MPX_REGISTER, PR_MPX_UNREGISTER
From: Kevin Easton
Date: Tue Sep 16 2014 - 03:00:50 EST
On Thu, Sep 11, 2014 at 04:46:48PM +0800, Qiaowei Ren wrote:
> +static __user void *task_get_bounds_dir(struct task_struct *tsk)
> +{
> + struct xsave_struct *xsave_buf;
> +
> + fpu_xsave(&tsk->thread.fpu);
> + xsave_buf = &(tsk->thread.fpu.state->xsave);
> + if (!(xsave_buf->bndcsr.cfg_reg_u & MPX_BNDCFG_ENABLE_FLAG))
> + return NULL;
> +
> + return (void __user *)(unsigned long)(xsave_buf->bndcsr.cfg_reg_u &
> + MPX_BNDCFG_ADDR_MASK);
> +}
This only makes sense if called with 'current', so is there any need
for the function argument?
> +
> +int mpx_register(struct task_struct *tsk)
> +{
> + struct mm_struct *mm = tsk->mm;
> +
> + if (!cpu_has_mpx)
> + return -EINVAL;
> +
> + /*
> + * runtime in the userspace will be responsible for allocation of
> + * the bounds directory. Then, it will save the base of the bounds
> + * directory into XSAVE/XRSTOR Save Area and enable MPX through
> + * XRSTOR instruction.
> + *
> + * fpu_xsave() is expected to be very expensive. In order to do
> + * performance optimization, here we get the base of the bounds
> + * directory and then save it into mm_struct to be used in future.
> + */
> + mm->bd_addr = task_get_bounds_dir(tsk);
> + if (!mm->bd_addr)
> + return -EINVAL;
> +
> + return 0;
> +}
> +
> +int mpx_unregister(struct task_struct *tsk)
> +{
> + struct mm_struct *mm = current->mm;
> +
> + if (!cpu_has_mpx)
> + return -EINVAL;
> +
> + mm->bd_addr = NULL;
> + return 0;
> +}
If that's changed, then mpx_register() and mpx_unregister() don't need
a task_struct, just an mm_struct.
Probably these functions should be locking mmap_sem.
Would it be prudent to use an error code other than EINVAL for the
"hardware doesn't support it" case?
> @@ -2011,6 +2017,12 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
> me->mm->def_flags &= ~VM_NOHUGEPAGE;
> up_write(&me->mm->mmap_sem);
> break;
> + case PR_MPX_REGISTER:
> + error = MPX_REGISTER(me);
> + break;
> + case PR_MPX_UNREGISTER:
> + error = MPX_UNREGISTER(me);
> + break;
If you pass me->mm from prctl, that makes it clear that it's per-process
not per-thread, just like PR_SET_DUMPABLE / PR_GET_DUMPABLE.
This code should also enforce nulls in arg2 / arg3 / arg4,/ arg5 if it's
not using them, otherwise you'll be sunk if you ever want to use them later.
It seems like it only makes sense for all threads using the mm to have the
same bounds directory set. If the interface was changed to directly pass
the address, then could the kernel take care of setting it for *all* of
the threads in the process? This seems like something that would be easier
for the kernel to do than userspace.
- Kevin
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/