Thread (5 messages) 5 messages, 4 authors, 2017-09-22

[PATCH] hid/uhid: fix a double-fetch bug when copying event from user

flat view
STALE3303d

From: Meng Xu <hidden>
Date: 2017-09-19 05:22:01
Also in: lkml
Subsystem: hid core layer, the rest, uhid userspace hid io driver · Maintainers: Jiri Kosina, Benjamin Tissoires, Linus Torvalds, David Rheinsberg

When in_compat_syscall(), a user could make type != UHID_CREATE when
get_user(type, buffer) [first fetch] and later make event->type ==
UHID_CREATE in copy_from_user(event, buffer, ...) [second fetch].

By doing so, an attacker might circumvent the specific logic to handle
the type == UHID_CREATE case and later cause undefined behaviors.

This patch enforces that event->type is overriden to the type value
copied in the first fetch and thus, mitigate this race condition attack.

Signed-off-by: Meng Xu <redacted>
---
 drivers/hid/uhid.c | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/drivers/hid/uhid.c b/drivers/hid/uhid.c
index 7f8ff39..4bbfd8a 100644
--- a/drivers/hid/uhid.c
+++ b/drivers/hid/uhid.c
@@ -448,11 +448,20 @@ static int uhid_event_from_user(const char __user *buffer, size_t len,
 			kfree(compat);
 			return 0;
 		}
+
 		/* All others can be copied directly */
-	}
+		if (copy_from_user(event, buffer, min(len, sizeof(*event))))
+			return -EFAULT;
 
-	if (copy_from_user(event, buffer, min(len, sizeof(*event))))
-		return -EFAULT;
+		/* 
+		 * Override type in case the user process rushes to change it 
+		 * between two fetches 
+		 * */
+		event->type = type;
+	} else {
+		if (copy_from_user(event, buffer, min(len, sizeof(*event))))
+			return -EFAULT;
+	}
 
 	return 0;
 }
-- 
2.7.4
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help