Skip to contentSkip to conversation

firewire: cdev: fix 32 bit userland on 64 bit kernel compat corner cases

PATCH New Stefan Richter 1 participant 1 message Aug 10, 2011 8 messages not in the archive Firewire

lore
Share & tools
lore

A message that is not in the archive (sent off-list or not yet received): CADmzSSh_gRKxjGNk7c938mhZQhe3N-18KJrqq4UpG8L6FcCQDQ@mail.gmail.com

A message that is not in the archive (sent off-list or not yet received): [email protected]

A message that is not in the archive (sent off-list or not yet received): [email protected]

A message that is not in the archive (sent off-list or not yet received): 20110809221719.74e29be5@stein

A message that is not in the archive (sent off-list or not yet received): [email protected]

A message that is not in the archive (sent off-list or not yet received): 20110810163444.768d583d@stein

A message that is not in the archive (sent off-list or not yet received): [email protected]

A message that is not in the archive (sent off-list or not yet received): 20110810234635.11ea2ea1@stein

#8 lore raw

PATCH 1/1 firewire: cdev: fix 32 bit userland on 64 bit kernel compat corner cases

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).

---
 drivers/firewire/core-cdev.c |   24 +++++++++++++++++++++---
 1 file changed, 21 insertions(+), 3 deletions(-)
drivers/firewire/core-cdev.c +21 -3
Index: 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)
 {
Signature · 3 lines
Stefan Richter
-=====-==-== =--- -=-=-
http://arcgraph.de/sr/