Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 101778
b: refs/heads/master
c: c1cb299
h: refs/heads/master
v: v3
  • Loading branch information
Michael Neuling authored and Benjamin Herrenschmidt committed Jul 9, 2008
1 parent 96fcf2b commit 962d395
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 6 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 1b17adf19b4d66858f366acd82b4e81cba5edc93
refs/heads/master: c1cb299ead405f0ac065c4430729549b187e5b32
39 changes: 38 additions & 1 deletion trunk/arch/powerpc/kernel/signal_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,13 @@
#define mcontext mcontext32
#define ucontext ucontext32

/*
* Userspace code may pass a ucontext which doesn't include VSX added
* at the end. We need to check for this case.
*/
#define UCONTEXTSIZEWITHOUTVSX \
(sizeof(struct ucontext) - sizeof(elf_vsrreghalf_t32))

/*
* Returning 0 means we return to userspace via
* ret_from_except and thus restore all user
Expand Down Expand Up @@ -930,12 +937,42 @@ long sys_swapcontext(struct ucontext __user *old_ctx,
{
unsigned char tmp;

#ifdef CONFIG_PPC64
unsigned long new_msr = 0;

if (new_ctx &&
__get_user(new_msr, &new_ctx->uc_mcontext.mc_gregs[PT_MSR]))
return -EFAULT;
/*
* Check that the context is not smaller than the original
* size (with VMX but without VSX)
*/
if (ctx_size < UCONTEXTSIZEWITHOUTVSX)
return -EINVAL;
/*
* If the new context state sets the MSR VSX bits but
* it doesn't provide VSX state.
*/
if ((ctx_size < sizeof(struct ucontext)) &&
(new_msr & MSR_VSX))
return -EINVAL;
#ifdef CONFIG_VSX
/*
* If userspace doesn't provide enough room for VSX data,
* but current thread has used VSX, we don't have anywhere
* to store the full context back into.
*/
if ((ctx_size < sizeof(struct ucontext)) &&
(current->thread.used_vsr && old_ctx))
return -EINVAL;
#endif
#else
/* Context size is for future use. Right now, we only make sure
* we are passed something we understand
*/
if (ctx_size < sizeof(struct ucontext))
return -EINVAL;

#endif
if (old_ctx != NULL) {
struct mcontext __user *mctx;

Expand Down
36 changes: 32 additions & 4 deletions trunk/arch/powerpc/kernel/signal_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,13 @@ static long setup_trampoline(unsigned int syscall, unsigned int __user *tramp)
return err;
}

/*
* Userspace code may pass a ucontext which doesn't include VSX added
* at the end. We need to check for this case.
*/
#define UCONTEXTSIZEWITHOUTVSX \
(sizeof(struct ucontext) - 32*sizeof(long))

/*
* Handle {get,set,swap}_context operations
*/
Expand All @@ -276,13 +283,34 @@ int sys_swapcontext(struct ucontext __user *old_ctx,
{
unsigned char tmp;
sigset_t set;
unsigned long new_msr = 0;

/* Context size is for future use. Right now, we only make sure
* we are passed something we understand
if (new_ctx &&
__get_user(new_msr, &new_ctx->uc_mcontext.gp_regs[PT_MSR]))
return -EFAULT;
/*
* Check that the context is not smaller than the original
* size (with VMX but without VSX)
*/
if (ctx_size < sizeof(struct ucontext))
if (ctx_size < UCONTEXTSIZEWITHOUTVSX)
return -EINVAL;

/*
* If the new context state sets the MSR VSX bits but
* it doesn't provide VSX state.
*/
if ((ctx_size < sizeof(struct ucontext)) &&
(new_msr & MSR_VSX))
return -EINVAL;
#ifdef CONFIG_VSX
/*
* If userspace doesn't provide enough room for VSX data,
* but current thread has used VSX, we don't have anywhere
* to store the full context back into.
*/
if ((ctx_size < sizeof(struct ucontext)) &&
(current->thread.used_vsr && old_ctx))
return -EINVAL;
#endif
if (old_ctx != NULL) {
if (!access_ok(VERIFY_WRITE, old_ctx, sizeof(*old_ctx))
|| setup_sigcontext(&old_ctx->uc_mcontext, regs, 0, NULL, 0)
Expand Down

0 comments on commit 962d395

Please sign in to comment.