svn commit: r281737 - user/jceel/soc2014_evdev/head/sys/dev/evdev
Jakub Wojciech Klama
jceel at FreeBSD.org
Sun Apr 19 10:47:56 UTC 2015
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);
}
}
More information about the svn-src-user
mailing list