From: Greg KH <gregkh@suse.de>
To: linux-kernel@vger.kernel.org, stable@kernel.org
Cc: Justin Forbes <jmforbes@linuxtx.org>,
Zwane Mwaikambo <zwane@arm.linux.org.uk>,
"Theodore Ts'o" <tytso@mit.edu>,
Randy Dunlap <rdunlap@xenotime.net>,
Dave Jones <davej@redhat.com>,
Chuck Wolber <chuckw@quantumlinux.com>,
Chris Wedgwood <reviews@ml.cw.f00f.org>,
Michael Krufky <mkrufky@linuxtv.org>,
Chuck Ebbert <cebbert@redhat.com>,
Domenico Andreoli <cavokz@gmail.com>, Willy Tarreau <w@1wt.eu>,
Rodrigo Rubira Branco <rbranco@la.checkpoint.com>,
Jake Edge <jake@lwn.net>, Eugene Teo <eteo@redhat.com>,
torvalds@linux-foundation.org, akpm@linux-foundation.org,
alan@lxorguk.ukuu.org.uk, Michael Neuling <mikey@neuling.org>,
Paul Mackerras <paulus@samba.org>,
Benjamin Herrenschmidt <benh@kernel.crashing.org>
Subject: [patch 07/47] powerpc: Fix swapcontext system for VSX + old ucontext size
Date: Fri, 13 Feb 2009 16:58:17 -0800 [thread overview]
Message-ID: <20090214005817.GH11282@kroah.com> (raw)
In-Reply-To: <20090214005726.GA11282@kroah.com>
[-- Attachment #1: powerpc-fix-swapcontext-system-for-vsx-old-ucontext-size.patch --]
[-- Type: text/plain, Size: 8419 bytes --]
2.6.27-stable review patch. If anyone has any objections, please let us know.
------------------
From: Michael Neuling <mikey@neuling.org>
commit 16c29d180becc5bdf92fd0fc7314a44a671b5f4e upstream.
Since VSX support was added, we now have two sizes of ucontext_t;
the older, smaller size without the extra VSX state, and the new
larger size with the extra VSX state. A program using the
sys_swapcontext system call and supplying smaller ucontext_t
structures will currently get an EINVAL error if the task has
used VSX (e.g. because of calling library code that uses VSX) and
the old_ctx argument is non-NULL (i.e. the program is asking for
its current context to be saved). Thus the program will start
getting EINVAL errors on calls that previously worked.
This commit changes this behaviour so that we don't send an EINVAL in
this case. It will now return the smaller context but the VSX MSR bit
will always be cleared to indicate that the ucontext_t doesn't include
the extra VSX state, even if the task has executed VSX instructions.
Both 32 and 64 bit cases are updated.
[paulus@samba.org - also fix some access_ok() and get_user() calls]
Thanks to Ben Herrenschmidt for noticing this problem.
Signed-off-by: Michael Neuling <mikey@neuling.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
arch/powerpc/kernel/signal_32.c | 36 +++++++++++++++---------------------
arch/powerpc/kernel/signal_64.c | 33 +++++++++++++++------------------
2 files changed, 30 insertions(+), 39 deletions(-)
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -410,7 +410,7 @@ inline unsigned long copy_fpr_from_user(
* altivec/spe instructions at some point.
*/
static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
- int sigret)
+ int sigret, int ctx_has_vsx_region)
{
unsigned long msr = regs->msr;
@@ -451,7 +451,7 @@ static int save_user_regs(struct pt_regs
* the saved MSR value to indicate that frame->mc_vregs
* contains valid data
*/
- if (current->thread.used_vsr) {
+ if (current->thread.used_vsr && ctx_has_vsx_region) {
__giveup_vsx(current);
if (copy_vsx_to_user(&frame->mc_vsregs, current))
return 1;
@@ -858,11 +858,11 @@ int handle_rt_signal32(unsigned long sig
frame = &rt_sf->uc.uc_mcontext;
addr = frame;
if (vdso32_rt_sigtramp && current->mm->context.vdso_base) {
- if (save_user_regs(regs, frame, 0))
+ if (save_user_regs(regs, frame, 0, 1))
goto badframe;
regs->link = current->mm->context.vdso_base + vdso32_rt_sigtramp;
} else {
- if (save_user_regs(regs, frame, __NR_rt_sigreturn))
+ if (save_user_regs(regs, frame, __NR_rt_sigreturn, 1))
goto badframe;
regs->link = (unsigned long) frame->tramp;
}
@@ -936,12 +936,13 @@ long sys_swapcontext(struct ucontext __u
int ctx_size, int r6, int r7, int r8, struct pt_regs *regs)
{
unsigned char tmp;
+ int ctx_has_vsx_region = 0;
#ifdef CONFIG_PPC64
unsigned long new_msr = 0;
if (new_ctx &&
- __get_user(new_msr, &new_ctx->uc_mcontext.mc_gregs[PT_MSR]))
+ get_user(new_msr, &new_ctx->uc_mcontext.mc_gregs[PT_MSR]))
return -EFAULT;
/*
* Check that the context is not smaller than the original
@@ -956,16 +957,9 @@ long sys_swapcontext(struct ucontext __u
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
+ /* Does the context have enough room to store VSX data? */
+ if (ctx_size >= sizeof(struct ucontext))
+ ctx_has_vsx_region = 1;
#else
/* Context size is for future use. Right now, we only make sure
* we are passed something we understand
@@ -985,17 +979,17 @@ long sys_swapcontext(struct ucontext __u
*/
mctx = (struct mcontext __user *)
((unsigned long) &old_ctx->uc_mcontext & ~0xfUL);
- if (!access_ok(VERIFY_WRITE, old_ctx, sizeof(*old_ctx))
- || save_user_regs(regs, mctx, 0)
+ if (!access_ok(VERIFY_WRITE, old_ctx, ctx_size)
+ || save_user_regs(regs, mctx, 0, ctx_has_vsx_region)
|| put_sigset_t(&old_ctx->uc_sigmask, ¤t->blocked)
|| __put_user(to_user_ptr(mctx), &old_ctx->uc_regs))
return -EFAULT;
}
if (new_ctx == NULL)
return 0;
- if (!access_ok(VERIFY_READ, new_ctx, sizeof(*new_ctx))
+ if (!access_ok(VERIFY_READ, new_ctx, ctx_size)
|| __get_user(tmp, (u8 __user *) new_ctx)
- || __get_user(tmp, (u8 __user *) (new_ctx + 1) - 1))
+ || __get_user(tmp, (u8 __user *) new_ctx + ctx_size - 1))
return -EFAULT;
/*
@@ -1196,11 +1190,11 @@ int handle_signal32(unsigned long sig, s
goto badframe;
if (vdso32_sigtramp && current->mm->context.vdso_base) {
- if (save_user_regs(regs, &frame->mctx, 0))
+ if (save_user_regs(regs, &frame->mctx, 0, 1))
goto badframe;
regs->link = current->mm->context.vdso_base + vdso32_sigtramp;
} else {
- if (save_user_regs(regs, &frame->mctx, __NR_sigreturn))
+ if (save_user_regs(regs, &frame->mctx, __NR_sigreturn, 1))
goto badframe;
regs->link = (unsigned long) frame->mctx.tramp;
}
--- a/arch/powerpc/kernel/signal_64.c
+++ b/arch/powerpc/kernel/signal_64.c
@@ -74,7 +74,8 @@ static const char fmt64[] = KERN_INFO \
*/
static long setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
- int signr, sigset_t *set, unsigned long handler)
+ int signr, sigset_t *set, unsigned long handler,
+ int ctx_has_vsx_region)
{
/* When CONFIG_ALTIVEC is set, we _always_ setup v_regs even if the
* process never used altivec yet (MSR_VEC is zero in pt_regs of
@@ -121,7 +122,7 @@ static long setup_sigcontext(struct sigc
* then out to userspace. Update v_regs to point after the
* VMX data.
*/
- if (current->thread.used_vsr) {
+ if (current->thread.used_vsr && ctx_has_vsx_region) {
__giveup_vsx(current);
v_regs += ELF_NVRREG;
err |= copy_vsx_to_user(v_regs, current);
@@ -284,9 +285,10 @@ int sys_swapcontext(struct ucontext __us
unsigned char tmp;
sigset_t set;
unsigned long new_msr = 0;
+ int ctx_has_vsx_region = 0;
if (new_ctx &&
- __get_user(new_msr, &new_ctx->uc_mcontext.gp_regs[PT_MSR]))
+ get_user(new_msr, &new_ctx->uc_mcontext.gp_regs[PT_MSR]))
return -EFAULT;
/*
* Check that the context is not smaller than the original
@@ -301,28 +303,23 @@ int sys_swapcontext(struct ucontext __us
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
+ /* Does the context have enough room to store VSX data? */
+ if (ctx_size >= sizeof(struct ucontext))
+ ctx_has_vsx_region = 1;
+
if (old_ctx != NULL) {
- if (!access_ok(VERIFY_WRITE, old_ctx, sizeof(*old_ctx))
- || setup_sigcontext(&old_ctx->uc_mcontext, regs, 0, NULL, 0)
+ if (!access_ok(VERIFY_WRITE, old_ctx, ctx_size)
+ || setup_sigcontext(&old_ctx->uc_mcontext, regs, 0, NULL, 0,
+ ctx_has_vsx_region)
|| __copy_to_user(&old_ctx->uc_sigmask,
¤t->blocked, sizeof(sigset_t)))
return -EFAULT;
}
if (new_ctx == NULL)
return 0;
- if (!access_ok(VERIFY_READ, new_ctx, sizeof(*new_ctx))
+ if (!access_ok(VERIFY_READ, new_ctx, ctx_size)
|| __get_user(tmp, (u8 __user *) new_ctx)
- || __get_user(tmp, (u8 __user *) (new_ctx + 1) - 1))
+ || __get_user(tmp, (u8 __user *) new_ctx + ctx_size - 1))
return -EFAULT;
/*
@@ -425,7 +422,7 @@ int handle_rt_signal64(int signr, struct
&frame->uc.uc_stack.ss_flags);
err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, signr, NULL,
- (unsigned long)ka->sa.sa_handler);
+ (unsigned long)ka->sa.sa_handler, 1);
err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
if (err)
goto badframe;
next prev parent reply other threads:[~2009-02-14 1:03 UTC|newest]
Thread overview: 50+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20090214005130.617401075@mini.kroah.org>
2009-02-14 0:57 ` [patch 00/47] 2.6.27.18-stable review Greg KH
2009-02-14 0:58 ` [patch 01/47] Fix page writeback thinko, causing Berkeley DB slowdown Greg KH
2009-02-14 0:58 ` [patch 02/47] iwlwifi: scan correct setting of valid rx_chains Greg KH
2009-02-14 0:58 ` [patch 03/47] kernel-doc: fix syscall wrapper processing Greg KH
2009-02-14 0:58 ` [patch 04/47] lockd: fix regression in lockds handling of blocked locks Greg KH
2009-02-14 0:58 ` [patch 05/47] nbd: fix I/O hang on disconnected nbds Greg KH
2009-02-14 0:58 ` [patch 06/47] parport: parport_serial, dont bind netmos ibm 0299 Greg KH
2009-02-14 0:58 ` Greg KH [this message]
2009-02-14 0:58 ` [patch 08/47] powerpc/fsl-booke: Fix mapping functions to use phys_addr_t Greg KH
2009-02-14 0:58 ` [patch 09/47] syscall define: fix uml compile bug Greg KH
2009-02-14 0:58 ` [patch 10/47] w1: w1 temp calculation overflow fix Greg KH
2009-02-14 0:58 ` [patch 11/47] write-back: fix nr_to_write counter Greg KH
2009-02-14 0:58 ` [patch 12/47] writeback: fix break condition Greg KH
2009-02-14 0:58 ` [patch 13/47] x86, vmi: put a missing paravirt_release_pmd in pgd_dtor Greg KH
2009-02-14 0:58 ` [patch 14/47] zd1211rw: adding 0ace:0xa211 as a ZD1211 device Greg KH
2009-02-14 0:58 ` [patch 15/47] zd1211rw: treat MAXIM_NEW_RF(0x08) as UW2453_RF(0x09) for TP-Link WN322/422G Greg KH
2009-02-14 0:58 ` [patch 16/47] sctp: Fix crc32c calculations on big-endian arhes Greg KH
2009-02-14 0:58 ` [patch 17/47] sctp: Correctly start rtx timer on new packet transmissions Greg KH
2009-02-14 0:58 ` [patch 18/47] sctp: Properly timestamp outgoing data chunks for rtx purposes Greg KH
2009-02-14 0:58 ` [patch 19/47] drivers/net/skfp: if !capable(CAP_NET_ADMIN): inverted logic Greg KH
2009-02-14 0:58 ` [patch 20/47] ipv4: fix infinite retry loop in IP-Config Greg KH
2009-02-14 0:58 ` [patch 21/47] ipv6: Disallow rediculious flowlabel option sizes Greg KH
2009-02-14 0:58 ` [patch 22/47] ipv6: Copy cork options in ip6_append_data Greg KH
2009-02-14 0:58 ` [patch 23/47] net: 4 bytes kernel memory disclosure in SO_BSDCOMPAT gsopt try #2 Greg KH
2009-02-14 0:58 ` [patch 24/47] net: packet socket packet_lookup_frame fix Greg KH
2009-02-14 0:58 ` [patch 25/47] sky2: fix hard hang with netconsoling and iface going up Greg KH
2009-02-14 0:58 ` [patch 26/47] sungem: Soft lockup in sungem on Netra AC200 when switching interface up Greg KH
2009-02-14 0:58 ` [patch 27/47] tun: Add some missing TUN compat ioctl translations Greg KH
2009-02-14 0:59 ` [patch 28/47] tun: Fix unicast filter overflow Greg KH
2009-02-14 0:59 ` [patch 29/47] udp: Fix UDP short packet false positive Greg KH
2009-02-14 0:59 ` [patch 30/47] udp: increments sk_drops in __udp_queue_rcv_skb() Greg KH
2009-02-14 0:59 ` [patch 31/47] virtio_net: Fix MAX_PACKET_LEN to support 802.1Q VLANs Greg KH
2009-02-14 0:59 ` [patch 32/47] net: Fix frag_list handling in skb_seq_read Greg KH
2009-02-14 0:59 ` [patch 33/47] net: Fix OOPS in skb_seq_read() Greg KH
2009-02-14 0:59 ` [patch 34/47] packet: Avoid lock_sock in mmap handler Greg KH
2009-02-14 0:59 ` [patch 35/47] tcp: splice as many packets as possible at once Greg KH
2009-02-14 0:59 ` [patch 36/47] tcp: Fix length tcp_splice_data_recv passes to skb_splice_bits Greg KH
2009-02-14 0:59 ` [patch 37/47] sparc: Enable syscall wrappers for 64-bit (CVE-2009-0029) Greg KH
2009-02-14 0:59 ` [patch 38/47] sparc64: Annotate sparc64 specific syscalls with SYSCALL_DEFINEx() Greg KH
2009-02-14 0:59 ` [patch 39/47] netfilter: fix tuple inversion for Node information request Greg KH
2009-02-14 0:59 ` [patch 40/47] netfilter: xt_sctp: sctp chunk mapping doesnt work Greg KH
2009-02-14 0:59 ` [patch 41/47] bluetooth hid: enable quirk handling for Apple Wireless Keyboards in 2.6.27 Greg KH
2009-02-14 22:50 ` Jan Scholz
2009-02-16 17:48 ` Torsten Rausche
2009-02-14 0:59 ` [patch 42/47] HID: adjust report descriptor fixup for MS 1028 receiver Greg KH
2009-02-14 0:59 ` [patch 43/47] libata: fix EH device failure handling Greg KH
2009-02-14 0:59 ` [patch 44/47] ide/libata: fix ata_id_is_cfa() (take 4) Greg KH
2009-02-14 0:59 ` [patch 45/47] x86: fixup config space size of CPU functions for AMD family 11h Greg KH
2009-02-14 0:59 ` [patch 46/47] mac80211: fix a buffer overrun in station debug code Greg KH
2009-02-14 0:59 ` [patch 47/47] ALSA: mtpav - Fix initial value for input hwport Greg KH
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20090214005817.GH11282@kroah.com \
--to=gregkh@suse.de \
--cc=akpm@linux-foundation.org \
--cc=alan@lxorguk.ukuu.org.uk \
--cc=benh@kernel.crashing.org \
--cc=cavokz@gmail.com \
--cc=cebbert@redhat.com \
--cc=chuckw@quantumlinux.com \
--cc=davej@redhat.com \
--cc=eteo@redhat.com \
--cc=jake@lwn.net \
--cc=jmforbes@linuxtx.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mikey@neuling.org \
--cc=mkrufky@linuxtv.org \
--cc=paulus@samba.org \
--cc=rbranco@la.checkpoint.com \
--cc=rdunlap@xenotime.net \
--cc=reviews@ml.cw.f00f.org \
--cc=stable@kernel.org \
--cc=torvalds@linux-foundation.org \
--cc=tytso@mit.edu \
--cc=w@1wt.eu \
--cc=zwane@arm.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox