Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 19 Apr 2015 10:47:55 +0000 (UTC)
From:      Jakub Wojciech Klama <jceel@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-user@freebsd.org
Subject:   svn commit: r281737 - user/jceel/soc2014_evdev/head/sys/dev/evdev
Message-ID:  <201504191047.t3JAlu5Q048451@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jceel
Date: Sun Apr 19 10:47:55 2015
New Revision: 281737
URL: https://svnweb.freebsd.org/changeset/base/281737

Log:
  Add event checks to evdev_push_event() to prevent overwriting event
  state arrays by potentially malicious uinput provider.

Modified:
  user/jceel/soc2014_evdev/head/sys/dev/evdev/evdev.c
  user/jceel/soc2014_evdev/head/sys/dev/evdev/uinput.c

Modified: user/jceel/soc2014_evdev/head/sys/dev/evdev/evdev.c
==============================================================================
--- user/jceel/soc2014_evdev/head/sys/dev/evdev/evdev.c	Sun Apr 19 09:35:46 2015	(r281736)
+++ user/jceel/soc2014_evdev/head/sys/dev/evdev/evdev.c	Sun Apr 19 10:47:55 2015	(r281737)
@@ -60,6 +60,7 @@ static void evdev_assign_id(struct evdev
 static void evdev_start_repeat(struct evdev_dev *, int32_t);
 static void evdev_stop_repeat(struct evdev_dev *);
 #endif
+static int evdev_check_event(struct evdev_dev *, uint16_t, uint16_t, int32_t);
 static void evdev_client_push(struct evdev_client *, uint16_t, uint16_t,
     int32_t);
 
@@ -270,6 +271,37 @@ evdev_set_repeat_params(struct evdev_dev
 	evdev->ev_rep[property] = value;
 }
 
+static int
+evdev_check_event(struct evdev_dev *evdev, uint16_t type, uint16_t code,
+    int32_t value)
+{
+
+	if (type == EV_KEY) {
+		if (code >= KEY_CNT)
+			return (EINVAL);
+	} else if (type == EV_REL) {
+		if (code >= REL_CNT)
+			return (EINVAL);
+	} else if (type == EV_ABS) {
+		if (code >= ABS_CNT)
+			return (EINVAL);
+	} else if (type == EV_MSC) {
+		if (code >= MSC_CNT)
+			return (EINVAL);
+	} else if (type == EV_LED) {
+		if (code >= LED_CNT)
+			return (EINVAL);
+	} else if (type == EV_SND) {
+		if (code >= SND_CNT)
+			return (EINVAL);
+	} else if (type == EV_SW) {
+		if (code >= SW_CNT)
+			return (EINVAL);
+	} else
+		return (EINVAL);
+
+	return (0);
+}
 
 int
 evdev_push_event(struct evdev_dev *evdev, uint16_t type, uint16_t code,
@@ -277,6 +309,9 @@ evdev_push_event(struct evdev_dev *evdev
 {
 	struct evdev_client *client;
 
+	if (evdev_check_event(evdev, type, code, value) != 0)
+		return (EINVAL);
+
 	debugf("%s pushed event %d/%d/%d",
 	    evdev->ev_shortname, type, code, value);
 

Modified: user/jceel/soc2014_evdev/head/sys/dev/evdev/uinput.c
==============================================================================
--- user/jceel/soc2014_evdev/head/sys/dev/evdev/uinput.c	Sun Apr 19 09:35:46 2015	(r281736)
+++ user/jceel/soc2014_evdev/head/sys/dev/evdev/uinput.c	Sun Apr 19 10:47:55 2015	(r281737)
@@ -87,7 +87,6 @@ struct uinput_cdev_state
 {
 	bool			ucs_connected;
 	struct evdev_dev *	ucs_evdev;
-	struct evdev_dev	ucs_state;
 	struct mtx		ucs_mtx;
 };
 
@@ -181,8 +180,11 @@ uinput_write(struct cdev *dev, struct ui
 
 		while (uio->uio_resid > 0) {
 			uiomove(&event, sizeof(struct input_event), uio);
-			evdev_push_event(state->ucs_evdev, event.type, event.code,
+			ret = evdev_push_event(state->ucs_evdev, event.type, event.code,
 			    event.value);
+
+			if (ret != 0)
+				return (ret);
 		}
 	}
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201504191047.t3JAlu5Q048451>