126 lines
5.7 KiB
Diff
126 lines
5.7 KiB
Diff
From 7e0f374aaca4d964c880d5966811ce2ecfdda94f Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
|
Date: Wed, 5 May 2021 16:49:41 +0200
|
|
Subject: [PATCH] sd-device: do no allocate strings of unknown length on the
|
|
stack
|
|
|
|
Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=33881.
|
|
|
|
Not only we would duplicate unknown input on the stack, we would do it
|
|
over and over. So let's first check that the input has reasonable length,
|
|
but also allocate just one fixed size buffer.
|
|
|
|
(cherry picked from commit e17c95af8e450caacde692875b30675cea75211f)
|
|
(cherry picked from commit 5172ef4a58bda5be18dcdbbe0abd2c6bb4f08743)
|
|
|
|
Conflict:NA
|
|
Reference:https://github.com/systemd/systemd-stable/commit/7e0f374aaca4d964c880d5966811ce2ecfdda94f
|
|
---
|
|
src/libsystemd/sd-device/sd-device.c | 54 ++++++++++-----------
|
|
1 files changed, 27 insertions(+), 27 deletions(-)
|
|
|
|
diff --git a/src/libsystemd/sd-device/sd-device.c b/src/libsystemd/sd-device/sd-device.c
|
|
index d1aa3282bf..6e05ba586f 100644
|
|
--- a/src/libsystemd/sd-device/sd-device.c
|
|
+++ b/src/libsystemd/sd-device/sd-device.c
|
|
@@ -246,29 +246,31 @@ _public_ int sd_device_new_from_devnum(sd_device **ret, char type, dev_t devnum)
|
|
}
|
|
|
|
_public_ int sd_device_new_from_subsystem_sysname(sd_device **ret, const char *subsystem, const char *sysname) {
|
|
- char *name, *syspath;
|
|
- size_t len = 0;
|
|
+ char syspath[PATH_MAX], *name;
|
|
|
|
assert_return(ret, -EINVAL);
|
|
assert_return(subsystem, -EINVAL);
|
|
assert_return(sysname, -EINVAL);
|
|
+ assert_return(strlen(sysname) < PATH_MAX - strlen("/sys/bus/"), -ENAMETOOLONG);
|
|
|
|
if (streq(subsystem, "subsystem")) {
|
|
- syspath = strjoina("/sys/subsystem/", sysname);
|
|
- if (access(syspath, F_OK) >= 0)
|
|
+ if (snprintf_ok(syspath, sizeof syspath, "/sys/subsystem/%s", sysname) &&
|
|
+ access(syspath, F_OK) >= 0)
|
|
return sd_device_new_from_syspath(ret, syspath);
|
|
|
|
- syspath = strjoina("/sys/bus/", sysname);
|
|
- if (access(syspath, F_OK) >= 0)
|
|
+ if (snprintf_ok(syspath, sizeof syspath, "/sys/bus/%s", sysname) &&
|
|
+ access(syspath, F_OK) >= 0)
|
|
return sd_device_new_from_syspath(ret, syspath);
|
|
|
|
- syspath = strjoina("/sys/class/", sysname);
|
|
- if (access(syspath, F_OK) >= 0)
|
|
+ if (snprintf_ok(syspath, sizeof syspath, "/sys/class/%s", sysname) &&
|
|
+ access(syspath, F_OK) >= 0)
|
|
return sd_device_new_from_syspath(ret, syspath);
|
|
+
|
|
} else if (streq(subsystem, "module")) {
|
|
- syspath = strjoina("/sys/module/", sysname);
|
|
- if (access(syspath, F_OK) >= 0)
|
|
+ if (snprintf_ok(syspath, sizeof syspath, "/sys/module/%s", sysname) &&
|
|
+ access(syspath, F_OK) >= 0)
|
|
return sd_device_new_from_syspath(ret, syspath);
|
|
+
|
|
} else if (streq(subsystem, "drivers")) {
|
|
char subsys[PATH_MAX];
|
|
char *driver;
|
|
@@ -279,39 +281,37 @@ _public_ int sd_device_new_from_subsystem_sysname(sd_device **ret, const char *s
|
|
driver[0] = '\0';
|
|
driver++;
|
|
|
|
- syspath = strjoina("/sys/subsystem/", subsys, "/drivers/", driver);
|
|
- if (access(syspath, F_OK) >= 0)
|
|
+ if (snprintf_ok(syspath, sizeof syspath, "/sys/subsystem/%s/drivers/%s", subsys, driver) &&
|
|
+ access(syspath, F_OK) >= 0)
|
|
return sd_device_new_from_syspath(ret, syspath);
|
|
|
|
- syspath = strjoina("/sys/bus/", subsys, "/drivers/", driver);
|
|
- if (access(syspath, F_OK) >= 0)
|
|
+ if (snprintf_ok(syspath, sizeof syspath, "/sys/bus/%s/drivers/%s", subsys, driver) &&
|
|
+ access(syspath, F_OK) >= 0)
|
|
return sd_device_new_from_syspath(ret, syspath);
|
|
}
|
|
}
|
|
|
|
/* translate sysname back to sysfs filename */
|
|
name = strdupa(sysname);
|
|
- while (name[len] != '\0') {
|
|
- if (name[len] == '/')
|
|
- name[len] = '!';
|
|
|
|
- len++;
|
|
- }
|
|
+ for (size_t i = 0; name[i]; i++)
|
|
+ if (name[i] == '/')
|
|
+ name[i] = '!';
|
|
|
|
- syspath = strjoina("/sys/subsystem/", subsystem, "/devices/", name);
|
|
- if (access(syspath, F_OK) >= 0)
|
|
+ if (snprintf_ok(syspath, sizeof syspath, "/sys/subsystem/%s/devices/%s", subsystem, name) &&
|
|
+ access(syspath, F_OK) >= 0)
|
|
return sd_device_new_from_syspath(ret, syspath);
|
|
|
|
- syspath = strjoina("/sys/bus/", subsystem, "/devices/", name);
|
|
- if (access(syspath, F_OK) >= 0)
|
|
+ if (snprintf_ok(syspath, sizeof syspath, "/sys/bus/%s/devices/%s", subsystem, name) &&
|
|
+ access(syspath, F_OK) >= 0)
|
|
return sd_device_new_from_syspath(ret, syspath);
|
|
|
|
- syspath = strjoina("/sys/class/", subsystem, "/", name);
|
|
- if (access(syspath, F_OK) >= 0)
|
|
+ if (snprintf_ok(syspath, sizeof syspath, "/sys/class/%s/%s", subsystem, name) &&
|
|
+ access(syspath, F_OK) >= 0)
|
|
return sd_device_new_from_syspath(ret, syspath);
|
|
|
|
- syspath = strjoina("/sys/firmware/", subsystem, "/", sysname);
|
|
- if (access(syspath, F_OK) >= 0)
|
|
+ if (snprintf_ok(syspath, sizeof syspath, "/sys/firmware/%s/%s", subsystem, sysname) &&
|
|
+ access(syspath, F_OK) >= 0)
|
|
return sd_device_new_from_syspath(ret, syspath);
|
|
|
|
return -ENODEV;
|
|
--
|
|
2.23.0
|
|
|