public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] firewire: cdev: fix 32 bit userland on 64 bit kernel compat corner cases
       [not found]             ` <20110810234635.11ea2ea1@stein>
@ 2011-08-10 22:06               ` Stefan Richter
  0 siblings, 0 replies; only message in thread
From: Stefan Richter @ 2011-08-10 22:06 UTC (permalink / raw)
  To: linux1394-devel; +Cc: Clemens Ladisch, Carl Karsten, linux-kernel

Clemens points out that we need to use compat_ptr() in order to safely
cast from u64 to addresses of a 32-bit usermode client.

Before, our conversion went wrong
  - in practice if the client cast from pointer to integer such that
    sign-extension happened, (libraw1394 and libdc1394 at least were not
    doing that, IOW were not affected)
or
  - in theory on s390 (which doesn't have FireWire though) and on the
    tile architecture, regardless of what the client does.
The bug would usually be observed as the initial get_info ioctl failing
with "Bad address" (EFAULT).

Reported-by: Carl Karsten <carl@personnelware.com>
Reported-by: Clemens Ladisch <clemens@ladisch.de>
Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Cc: stable@kernel.org
---
 drivers/firewire/core-cdev.c |   24 +++++++++++++++++++++---
 1 file changed, 21 insertions(+), 3 deletions(-)

Index: b/drivers/firewire/core-cdev.c
===================================================================
--- a/drivers/firewire/core-cdev.c
+++ b/drivers/firewire/core-cdev.c
@@ -216,15 +216,33 @@ struct inbound_phy_packet_event {
 	struct fw_cdev_event_phy_packet phy_packet;
 };
 
-static inline void __user *u64_to_uptr(__u64 value)
+#ifdef CONFIG_COMPAT
+static void __user *u64_to_uptr(u64 value)
+{
+	if (is_compat_task())
+		return compat_ptr(value);
+	else
+		return (void __user *)(unsigned long)value;
+}
+
+static u64 uptr_to_u64(void __user *ptr)
+{
+	if (is_compat_task())
+		return ptr_to_compat(ptr);
+	else
+		return (u64)(unsigned long)ptr;
+}
+#else
+static inline void __user *u64_to_uptr(u64 value)
 {
 	return (void __user *)(unsigned long)value;
 }
 
-static inline __u64 uptr_to_u64(void __user *ptr)
+static inline u64 uptr_to_u64(void __user *ptr)
 {
-	return (__u64)(unsigned long)ptr;
+	return (u64)(unsigned long)ptr;
 }
+#endif /* CONFIG_COMPAT */
 
 static int fw_device_op_open(struct inode *inode, struct file *file)
 {


-- 
Stefan Richter
-=====-==-== =--- -=-=-
http://arcgraph.de/sr/

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2011-08-10 22:06 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <CADmzSSh_gRKxjGNk7c938mhZQhe3N-18KJrqq4UpG8L6FcCQDQ@mail.gmail.com>
     [not found] ` <4E415305.3040404@ladisch.de>
     [not found]   ` <4E4159D1.9020208@ladisch.de>
     [not found]     ` <20110809221719.74e29be5@stein>
     [not found]       ` <4E4231DF.2060303@ladisch.de>
     [not found]         ` <20110810163444.768d583d@stein>
     [not found]           ` <4E42BA4D.7080203@ladisch.de>
     [not found]             ` <20110810234635.11ea2ea1@stein>
2011-08-10 22:06               ` [PATCH] firewire: cdev: fix 32 bit userland on 64 bit kernel compat corner cases Stefan Richter

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox