[PATCH weston] libweston: Make module loading safe against long paths

Daniel Stone daniels at collabora.com
Tue Nov 29 10:18:30 UTC 2016


Avoid any buffer overflows here by checking we don't go over PATH_MAX
with stupid module names.

Signed-off-by: Daniel Stone <daniels at collabora.com>
---
 compositor/main.c      | 15 ++++++++++++---
 libweston/compositor.c | 15 ++++++++++++---
 2 files changed, 24 insertions(+), 6 deletions(-)

diff --git a/compositor/main.c b/compositor/main.c
index 080aa61..2aa4936 100644
--- a/compositor/main.c
+++ b/compositor/main.c
@@ -766,19 +766,28 @@ wet_load_module(const char *name, const char *entrypoint)
 	const char *builddir = getenv("WESTON_BUILD_DIR");
 	char path[PATH_MAX];
 	void *module, *init;
+	size_t len;
 
 	if (name == NULL)
 		return NULL;
 
 	if (name[0] != '/') {
 		if (builddir)
-			snprintf(path, sizeof path, "%s/.libs/%s", builddir, name);
+			len = snprintf(path, sizeof path, "%s/.libs/%s", builddir,
+				       name);
 		else
-			snprintf(path, sizeof path, "%s/%s", MODULEDIR, name);
+			len = snprintf(path, sizeof path, "%s/%s", MODULEDIR,
+				       name);
 	} else {
-		snprintf(path, sizeof path, "%s", name);
+		len = snprintf(path, sizeof path, "%s", name);
 	}
 
+	/* snprintf returns the length of the string it would've written,
+	 * _excluding_ the NUL byte. So even being equal to the size of
+	 * our buffer is an error here. */
+	if (len >= sizeof path)
+		return NULL;
+
 	module = dlopen(path, RTLD_NOW | RTLD_NOLOAD);
 	if (module) {
 		weston_log("Module '%s' already loaded\n", path);
diff --git a/libweston/compositor.c b/libweston/compositor.c
index ee0a007..6457858 100644
--- a/libweston/compositor.c
+++ b/libweston/compositor.c
@@ -5225,19 +5225,28 @@ weston_load_module(const char *name, const char *entrypoint)
 	const char *builddir = getenv("WESTON_BUILD_DIR");
 	char path[PATH_MAX];
 	void *module, *init;
+	size_t len;
 
 	if (name == NULL)
 		return NULL;
 
 	if (name[0] != '/') {
 		if (builddir)
-			snprintf(path, sizeof path, "%s/.libs/%s", builddir, name);
+			len = snprintf(path, sizeof path, "%s/.libs/%s",
+				       builddir, name);
 		else
-			snprintf(path, sizeof path, "%s/%s", LIBWESTON_MODULEDIR, name);
+			len = snprintf(path, sizeof path, "%s/%s",
+				       LIBWESTON_MODULEDIR, name);
 	} else {
-		snprintf(path, sizeof path, "%s", name);
+		len = snprintf(path, sizeof path, "%s", name);
 	}
 
+	/* snprintf returns the length of the string it would've written,
+	 * _excluding_ the NUL byte. So even being equal to the size of
+	 * our buffer is an error here. */
+	if (len >= sizeof path)
+		return NULL;
+
 	module = dlopen(path, RTLD_NOW | RTLD_NOLOAD);
 	if (module) {
 		weston_log("Module '%s' already loaded\n", path);
-- 
2.9.3



More information about the wayland-devel mailing list