Timo Aaltonen pushed to branch debian-unstable at X Strike Force / lib / libinput
Commits:
-
2a8b8fde
by Peter Hutterer at 2022-04-20T14:08:15+10:00
-
562f7bce
by Peter Hutterer at 2022-04-20T15:24:35+10:00
-
492e34af
by Timo Aaltonen at 2022-04-20T10:00:36+03:00
-
d0352d4e
by Timo Aaltonen at 2022-04-20T10:01:16+03:00
-
acc393e6
by Timo Aaltonen at 2022-04-20T10:02:46+03:00
8 changed files:
- debian/changelog
- meson.build
- src/evdev.c
- src/evdev.h
- src/util-strings.h
- + test/litest-device-format-string.c
- test/litest.h
- test/test-utils.c
Changes:
1 | +libinput (1.20.1-1) unstable; urgency=medium
|
|
2 | + |
|
3 | + * New upstream release.
|
|
4 | + - CVE-2020-1215
|
|
5 | + |
|
6 | + -- Timo Aaltonen <tjaalton@debian.org> Wed, 20 Apr 2022 10:02:34 +0300
|
|
7 | + |
|
1 | 8 | libinput (1.20.0-1) unstable; urgency=medium
|
2 | 9 | |
3 | 10 | * New upstream release.
|
1 | 1 | project('libinput', 'c',
|
2 | - version : '1.20.0',
|
|
2 | + version : '1.20.1',
|
|
3 | 3 | license : 'MIT/Expat',
|
4 | 4 | default_options : [ 'c_std=gnu99', 'warning_level=2' ],
|
5 | 5 | meson_version : '>= 0.49.0')
|
... | ... | @@ -733,6 +733,7 @@ if get_option('tests') |
733 | 733 | 'test/litest-device-dell-canvas-totem-touch.c',
|
734 | 734 | 'test/litest-device-elantech-touchpad.c',
|
735 | 735 | 'test/litest-device-elan-tablet.c',
|
736 | + 'test/litest-device-format-string.c',
|
|
736 | 737 | 'test/litest-device-generic-pressurepad.c',
|
737 | 738 | 'test/litest-device-generic-singletouch.c',
|
738 | 739 | 'test/litest-device-gpio-keys.c',
|
... | ... | @@ -2356,19 +2356,19 @@ evdev_device_create(struct libinput_seat *seat, |
2356 | 2356 | struct libinput *libinput = seat->libinput;
|
2357 | 2357 | struct evdev_device *device = NULL;
|
2358 | 2358 | int rc;
|
2359 | - int fd;
|
|
2359 | + int fd = -1;
|
|
2360 | 2360 | int unhandled_device = 0;
|
2361 | 2361 | const char *devnode = udev_device_get_devnode(udev_device);
|
2362 | - const char *sysname = udev_device_get_sysname(udev_device);
|
|
2362 | + char *sysname = str_sanitize(udev_device_get_sysname(udev_device));
|
|
2363 | 2363 | |
2364 | 2364 | if (!devnode) {
|
2365 | 2365 | log_info(libinput, "%s: no device node associated\n", sysname);
|
2366 | - return NULL;
|
|
2366 | + goto err;
|
|
2367 | 2367 | }
|
2368 | 2368 | |
2369 | 2369 | if (udev_device_should_be_ignored(udev_device)) {
|
2370 | 2370 | log_debug(libinput, "%s: device is ignored\n", sysname);
|
2371 | - return NULL;
|
|
2371 | + goto err;
|
|
2372 | 2372 | }
|
2373 | 2373 | |
2374 | 2374 | /* Use non-blocking mode so that we can loop on read on
|
... | ... | @@ -2382,13 +2382,15 @@ evdev_device_create(struct libinput_seat *seat, |
2382 | 2382 | sysname,
|
2383 | 2383 | devnode,
|
2384 | 2384 | strerror(-fd));
|
2385 | - return NULL;
|
|
2385 | + goto err;
|
|
2386 | 2386 | }
|
2387 | 2387 | |
2388 | 2388 | if (!evdev_device_have_same_syspath(udev_device, fd))
|
2389 | 2389 | goto err;
|
2390 | 2390 | |
2391 | 2391 | device = zalloc(sizeof *device);
|
2392 | + device->sysname = sysname;
|
|
2393 | + sysname = NULL;
|
|
2392 | 2394 | |
2393 | 2395 | libinput_device_init(&device->base, seat);
|
2394 | 2396 | libinput_seat_ref(seat);
|
... | ... | @@ -2411,6 +2413,9 @@ evdev_device_create(struct libinput_seat *seat, |
2411 | 2413 | device->dispatch = NULL;
|
2412 | 2414 | device->fd = fd;
|
2413 | 2415 | device->devname = libevdev_get_name(device->evdev);
|
2416 | + /* the log_prefix_name is used as part of a printf format string and
|
|
2417 | + * must not contain % directives, see evdev_log_msg */
|
|
2418 | + device->log_prefix_name = str_sanitize(device->devname);
|
|
2414 | 2419 | device->scroll.threshold = 5.0; /* Default may be overridden */
|
2415 | 2420 | device->scroll.direction_lock_threshold = 5.0; /* Default may be overridden */
|
2416 | 2421 | device->scroll.direction = 0;
|
... | ... | @@ -2451,12 +2456,16 @@ evdev_device_create(struct libinput_seat *seat, |
2451 | 2456 | return device;
|
2452 | 2457 | |
2453 | 2458 | err:
|
2454 | - close_restricted(libinput, fd);
|
|
2455 | - if (device) {
|
|
2456 | - unhandled_device = device->seat_caps == 0;
|
|
2457 | - evdev_device_destroy(device);
|
|
2459 | + if (fd >= 0) {
|
|
2460 | + close_restricted(libinput, fd);
|
|
2461 | + if (device) {
|
|
2462 | + unhandled_device = device->seat_caps == 0;
|
|
2463 | + evdev_device_destroy(device);
|
|
2464 | + }
|
|
2458 | 2465 | }
|
2459 | 2466 | |
2467 | + free(sysname);
|
|
2468 | + |
|
2460 | 2469 | return unhandled_device ? EVDEV_UNHANDLED_DEVICE : NULL;
|
2461 | 2470 | }
|
2462 | 2471 | |
... | ... | @@ -2469,7 +2478,7 @@ evdev_device_get_output(struct evdev_device *device) |
2469 | 2478 | const char *
|
2470 | 2479 | evdev_device_get_sysname(struct evdev_device *device)
|
2471 | 2480 | {
|
2472 | - return udev_device_get_sysname(device->udev_device);
|
|
2481 | + return device->sysname;
|
|
2473 | 2482 | }
|
2474 | 2483 | |
2475 | 2484 | const char *
|
... | ... | @@ -3066,6 +3075,8 @@ evdev_device_destroy(struct evdev_device *device) |
3066 | 3075 | if (device->base.group)
|
3067 | 3076 | libinput_device_group_unref(device->base.group);
|
3068 | 3077 | |
3078 | + free(device->log_prefix_name);
|
|
3079 | + free(device->sysname);
|
|
3069 | 3080 | free(device->output_name);
|
3070 | 3081 | filter_destroy(device->pointer.filter);
|
3071 | 3082 | libinput_timer_destroy(&device->scroll.timer);
|
... | ... | @@ -169,6 +169,8 @@ struct evdev_device { |
169 | 169 | struct udev_device *udev_device;
|
170 | 170 | char *output_name;
|
171 | 171 | const char *devname;
|
172 | + char *log_prefix_name;
|
|
173 | + char *sysname;
|
|
172 | 174 | bool was_removed;
|
173 | 175 | int fd;
|
174 | 176 | enum evdev_device_seat_capability seat_caps;
|
... | ... | @@ -786,7 +788,7 @@ evdev_log_msg(struct evdev_device *device, |
786 | 788 | sizeof(buf),
|
787 | 789 | "%-7s - %s%s%s",
|
788 | 790 | evdev_device_get_sysname(device),
|
789 | - (priority > LIBINPUT_LOG_PRIORITY_DEBUG) ? device->devname : "",
|
|
791 | + (priority > LIBINPUT_LOG_PRIORITY_DEBUG) ? device->log_prefix_name : "",
|
|
790 | 792 | (priority > LIBINPUT_LOG_PRIORITY_DEBUG) ? ": " : "",
|
791 | 793 | format);
|
792 | 794 | |
... | ... | @@ -824,7 +826,7 @@ evdev_log_msg_ratelimit(struct evdev_device *device, |
824 | 826 | sizeof(buf),
|
825 | 827 | "%-7s - %s%s%s",
|
826 | 828 | evdev_device_get_sysname(device),
|
827 | - (priority > LIBINPUT_LOG_PRIORITY_DEBUG) ? device->devname : "",
|
|
829 | + (priority > LIBINPUT_LOG_PRIORITY_DEBUG) ? device->log_prefix_name : "",
|
|
828 | 830 | (priority > LIBINPUT_LOG_PRIORITY_DEBUG) ? ": " : "",
|
829 | 831 | format);
|
830 | 832 |
... | ... | @@ -43,6 +43,8 @@ |
43 | 43 | #include <xlocale.h>
|
44 | 44 | #endif
|
45 | 45 | |
46 | +#include "util-macros.h"
|
|
47 | + |
|
46 | 48 | static inline bool
|
47 | 49 | streq(const char *str1, const char *str2)
|
48 | 50 | {
|
... | ... | @@ -398,3 +400,31 @@ safe_basename(const char *filename); |
398 | 400 | |
399 | 401 | char *
|
400 | 402 | trunkname(const char *filename);
|
403 | + |
|
404 | +/**
|
|
405 | + * Return a copy of str with all % converted to %% to make the string
|
|
406 | + * acceptable as printf format.
|
|
407 | + */
|
|
408 | +static inline char *
|
|
409 | +str_sanitize(const char *str)
|
|
410 | +{
|
|
411 | + if (!str)
|
|
412 | + return NULL;
|
|
413 | + |
|
414 | + if (!strchr(str, '%'))
|
|
415 | + return strdup(str);
|
|
416 | + |
|
417 | + size_t slen = min(strlen(str), 512);
|
|
418 | + char *sanitized = zalloc(2 * slen + 1);
|
|
419 | + const char *src = str;
|
|
420 | + char *dst = sanitized;
|
|
421 | + |
|
422 | + for (size_t i = 0; i < slen; i++) {
|
|
423 | + if (*src == '%')
|
|
424 | + *dst++ = '%';
|
|
425 | + *dst++ = *src++;
|
|
426 | + }
|
|
427 | + *dst = '\0';
|
|
428 | + |
|
429 | + return sanitized;
|
|
430 | +} |
1 | + |
|
2 | +/*
|
|
3 | + * Copyright © 2013 Red Hat, Inc.
|
|
4 | + *
|
|
5 | + * Permission is hereby granted, free of charge, to any person obtaining a
|
|
6 | + * copy of this software and associated documentation files (the "Software"),
|
|
7 | + * to deal in the Software without restriction, including without limitation
|
|
8 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
9 | + * and/or sell copies of the Software, and to permit persons to whom the
|
|
10 | + * Software is furnished to do so, subject to the following conditions:
|
|
11 | + *
|
|
12 | + * The above copyright notice and this permission notice (including the next
|
|
13 | + * paragraph) shall be included in all copies or substantial portions of the
|
|
14 | + * Software.
|
|
15 | + *
|
|
16 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
19 | + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
21 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
22 | + * DEALINGS IN THE SOFTWARE.
|
|
23 | + */
|
|
24 | + |
|
25 | +#include "config.h"
|
|
26 | + |
|
27 | +#include "litest.h"
|
|
28 | +#include "litest-int.h"
|
|
29 | + |
|
30 | +static struct input_id input_id = {
|
|
31 | + .bustype = 0x3,
|
|
32 | + .vendor = 0x0123,
|
|
33 | + .product = 0x0456,
|
|
34 | +};
|
|
35 | + |
|
36 | +static int events[] = {
|
|
37 | + EV_KEY, BTN_LEFT,
|
|
38 | + EV_KEY, BTN_RIGHT,
|
|
39 | + EV_KEY, BTN_MIDDLE,
|
|
40 | + EV_REL, REL_X,
|
|
41 | + EV_REL, REL_Y,
|
|
42 | + EV_REL, REL_WHEEL,
|
|
43 | + EV_REL, REL_WHEEL_HI_RES,
|
|
44 | + -1 , -1,
|
|
45 | +};
|
|
46 | + |
|
47 | +TEST_DEVICE("mouse-format-string",
|
|
48 | + .type = LITEST_MOUSE_FORMAT_STRING,
|
|
49 | + .features = LITEST_RELATIVE | LITEST_BUTTON | LITEST_WHEEL,
|
|
50 | + .interface = NULL,
|
|
51 | + |
|
52 | + .name = "Evil %s %d %x Mouse %p %",
|
|
53 | + .id = &input_id,
|
|
54 | + .absinfo = NULL,
|
|
55 | + .events = events,
|
|
56 | +) |
... | ... | @@ -321,6 +321,7 @@ enum litest_device_type { |
321 | 321 | LITEST_SYNAPTICS_PRESSUREPAD,
|
322 | 322 | LITEST_GENERIC_PRESSUREPAD,
|
323 | 323 | LITEST_WACOM_ISDV4_524C_PEN,
|
324 | + LITEST_MOUSE_FORMAT_STRING,
|
|
324 | 325 | };
|
325 | 326 | |
326 | 327 | #define LITEST_DEVICELESS -2
|
... | ... | @@ -1267,6 +1267,31 @@ START_TEST(strstartswith_test) |
1267 | 1267 | }
|
1268 | 1268 | END_TEST
|
1269 | 1269 | |
1270 | +START_TEST(strsanitize_test)
|
|
1271 | +{
|
|
1272 | + struct strsanitize_test {
|
|
1273 | + const char *string;
|
|
1274 | + const char *expected;
|
|
1275 | + } tests[] = {
|
|
1276 | + { "foobar", "foobar" },
|
|
1277 | + { "", "" },
|
|
1278 | + { "%", "%%" },
|
|
1279 | + { "%%%%", "%%%%%%%%" },
|
|
1280 | + { "x %s", "x %%s" },
|
|
1281 | + { "x %", "x %%" },
|
|
1282 | + { "%sx", "%%sx" },
|
|
1283 | + { "%s%s", "%%s%%s" },
|
|
1284 | + { NULL, NULL },
|
|
1285 | + };
|
|
1286 | + |
|
1287 | + for (struct strsanitize_test *t = tests; t->string; t++) {
|
|
1288 | + char *sanitized = str_sanitize(t->string);
|
|
1289 | + ck_assert_str_eq(sanitized, t->expected);
|
|
1290 | + free(sanitized);
|
|
1291 | + }
|
|
1292 | +}
|
|
1293 | +END_TEST
|
|
1294 | + |
|
1270 | 1295 | START_TEST(list_test_insert)
|
1271 | 1296 | {
|
1272 | 1297 | struct list_test {
|
... | ... | @@ -1489,6 +1514,7 @@ litest_utils_suite(void) |
1489 | 1514 | tcase_add_test(tc, strstrip_test);
|
1490 | 1515 | tcase_add_test(tc, strendswith_test);
|
1491 | 1516 | tcase_add_test(tc, strstartswith_test);
|
1517 | + tcase_add_test(tc, strsanitize_test);
|
|
1492 | 1518 | tcase_add_test(tc, time_conversion);
|
1493 | 1519 | tcase_add_test(tc, human_time);
|
1494 | 1520 |