- Use asprintf instead of static buffers - Simplify sysctl_exists, devpath_exists api - Fix memory leak in reconnect code path - Return buf in socket_getline only if its size > 0 Index: x11-servers/xorg-server/files/patch-config_devd.c @@ -1,9 +1,8 @@ ---- config/devd.c.orig 2015-05-19 19:41:49 UTC -+++ config/devd.c -@@ -0,0 +1,531 @@ +Index: config/devd.c +@@ -0,0 +1,550 @@ +/* + * Copyright (c) 2012 Baptiste Daroussin -+ * Copyright (c) 2013, 2014 Alex Kozlov ++ * Copyright (c) 2013-2016 Alex Kozlov + * Copyright (c) 2014 Robert Millan + * Copyright (c) 2014 Jean-Sebastien Pedron + * @@ -87,10 +86,9 @@ +}; + +static bool -+sysctl_exists(const struct hw_type *device, int unit, -+ char *devname, size_t devname_len) ++sysctl_exists(const struct hw_type *device, int unit, char **devname) +{ -+ char sysctlname[PATH_MAX]; ++ char *sysctlname; + size_t len; + int ret; + @@ -98,12 +96,18 @@ + return false; + + /* Check if a sysctl exists. */ -+ snprintf(sysctlname, sizeof(sysctlname), "dev.%s.%i.%%desc", -+ device->driver, unit); ++ asprintf(&sysctlname, "dev.%s.%i.%%desc", device->driver, unit); ++ if (sysctlname == NULL) ++ return false; ++ + ret = sysctlbyname(sysctlname, NULL, &len, NULL, 0); ++ free(sysctlname); + + if (ret == 0 && len > 0) { -+ snprintf(devname, devname_len, "%s%i", device->driver, unit); ++ asprintf(devname, "%s%i", device->driver, unit); ++ if (devname == NULL) ++ return false; ++ + return true; + } + @@ -111,8 +115,7 @@ +} + +static bool -+devpath_exists(const struct hw_type *device, -+ char *devname, size_t devname_len) ++devpath_exists(const struct hw_type *device, char **devname) +{ + char *devpath; + struct stat st; @@ -130,7 +133,10 @@ + free(devpath); + + if (ret == 0) { -+ strncpy(devname, device->driver, devname_len); ++ *devname = strdup(device->driver); ++ if (devname == NULL) ++ return false; ++ + return true; + } + @@ -164,8 +170,8 @@ +static void +device_added(const char *devname) +{ -+ char path[PATH_MAX]; -+ char sysctlname[PATH_MAX]; ++ char *path; ++ char *sysctlname; + char *vendor; + char *product = NULL; + char *config_info = NULL; @@ -201,15 +207,18 @@ + return; + } + -+ snprintf(path, sizeof(path), "/dev/%s", devname); -+ + options = input_option_new(NULL, "_source", "server/devd"); + if (!options) + return; + -+ snprintf(sysctlname, sizeof(sysctlname), "dev.%s.%s.%%desc", ++ asprintf(&sysctlname, "dev.%s.%s.%%desc", + hw_types[i].driver, devname + strlen(hw_types[i].driver)); ++ if (sysctlname == NULL) ++ return; ++ + vendor = sysctl_get_str(sysctlname); ++ free(sysctlname); ++ + if (vendor == NULL) { + options = input_option_new(options, "name", devname); + } @@ -233,6 +242,10 @@ + free(vendor); + } + ++ asprintf(&path, "/dev/%s", devname); ++ if (path == NULL) ++ goto unwind; ++ + /* XXX implement usb_id */ + attrs.usb_id = NULL; + attrs.device = strdup(path); @@ -294,6 +307,7 @@ + NewInputDeviceRequest(options, &attrs, &dev); + +unwind: ++ free(path); + free(config_info); + input_option_free_list(&options); + free(attrs.usb_id); @@ -417,6 +431,7 @@ + disconnect_devd(sock_devd); + rtimer = TimerSet(NULL, 0, 1, reconnect_handler, NULL); + LogMessage(X_WARNING, "config/devd: devd socket is lost\n"); ++ free(buf); + return -1; + } + if (c == '\n') @@ -436,7 +451,7 @@ + } + + buf[sz] = '\0'; -+ if (sz >= 0) ++ if (sz > 0) + *out = buf; + else + free(buf); @@ -455,7 +470,7 @@ + return; + + if (FD_ISSET(sock_devd, (fd_set *) read_mask)) { -+ if (socket_getline(sock_devd, &line) < 0) ++ if (socket_getline(sock_devd, &line) <= 0) + return; + + walk = strchr(line + 1, ' '); @@ -484,7 +499,7 @@ +int +config_devd_init(void) +{ -+ char devicename[1024]; ++ char *devname; + int i, j; + + LogMessage(X_INFO, "config/devd: probing input devices...\n"); @@ -499,13 +514,16 @@ + for (i = 0; hw_types[i].driver != NULL; i++) { + /* First scan the sysctl to determine the hardware */ + for (j = 0; j < 16; j++) { -+ if (sysctl_exists(&hw_types[i], j, -+ devicename, sizeof(devicename)) != 0) -+ device_added(devicename); ++ if (sysctl_exists(&hw_types[i], j, &devname)) { ++ device_added(devname); ++ free(devname); ++ } + } + -+ if (devpath_exists(&hw_types[i], devicename, sizeof(devicename)) != 0) -+ device_added(devicename); ++ if (devpath_exists(&hw_types[i], &devname) != 0) { ++ device_added(devname); ++ free(devname); ++ } + } + + if ((sock_devd = connect_devd()) < 0)