libweston: Make module loading safe against long paths
authorDaniel Stone <daniels@collabora.com>
Mon, 28 Nov 2016 12:13:54 +0000 (12:13 +0000)
committerDaniel Stone <daniels@collabora.com>
Wed, 30 Nov 2016 10:27:51 +0000 (10:27 +0000)
Avoid any buffer overflows here by checking we don't go over PATH_MAX
with stupid module names.

Signed-off-by: Daniel Stone <daniels@collabora.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
compositor/main.c
libweston/compositor.c

index 080aa61..2aa4936 100644 (file)
@@ -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);
index ee0a007..6457858 100644 (file)
@@ -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);