commit e1ae7d3be6faa710b3a711ed317cfe45d90f28bc
parent 5c86bbd67f25815aa9c6c309697df7aea2d80330
Author: Ali H. Fardan <[email protected]>
Date:   Sun, 21 Aug 2016 00:00:23 +0300
added bounds checking via secure strl*() routines
Diffstat:
| M | slstatus.c | 34 | ++++++++++++++++++++-------------- | 
| A | strlcat.h | 55 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++ | 
| A | strlcpy.h | 50 | ++++++++++++++++++++++++++++++++++++++++++++++++++ | 
3 files changed, 125 insertions(+), 14 deletions(-)
diff --git a/slstatus.c b/slstatus.c
@@ -24,6 +24,12 @@
 #include <unistd.h>
 #include <X11/Xlib.h>
 
+#undef strlcat
+#undef strlcpy
+
+#include "strlcat.h"
+#include "strlcpy.h"
+
 /* statusbar configuration type and struct */
 typedef char *(*op_fun) (const char *);
 struct arg {
@@ -101,16 +107,16 @@ battery_perc(const char *battery)
 	FILE *fp;
 
 	/* generate battery nowfile path */
-	strcat(batterynowfile, batterypath);
-	strcat(batterynowfile, battery);
-	strcat(batterynowfile, "/");
-	strcat(batterynowfile, batterynow);
+	strlcat(batterynowfile, batterypath, sizeof(batterynowfile));
+	strlcat(batterynowfile, battery, sizeof(batterynowfile));
+	strlcat(batterynowfile, "/", sizeof(batterynowfile));
+	strlcat(batterynowfile, batterynow, sizeof(batterynowfile));
 
 	/* generate battery fullfile path */
-	strcat(batteryfullfile, batterypath);
-	strcat(batteryfullfile, battery);
-	strcat(batteryfullfile, "/");
-	strcat(batteryfullfile, batteryfull);
+	strlcat(batteryfullfile, batterypath, sizeof(batteryfullfile));
+	strlcat(batteryfullfile, battery, sizeof(batteryfullfile));
+	strlcat(batteryfullfile, "/", sizeof(batteryfullfile));
+	strlcat(batteryfullfile, batteryfull, sizeof(batteryfullfile));
 
 	/* open battery now file */
 	if (!(fp = fopen(batterynowfile, "r"))) {
@@ -688,9 +694,9 @@ wifi_perc(const char *wificard)
 
 	/* generate the path name */
 	memset(path, 0, sizeof path);
-	strcat(path, "/sys/class/net/");
-	strcat(path, wificard);
-	strcat(path, "/operstate");
+	strlcat(path, "/sys/class/net/", sizeof(path));
+	strlcat(path, wificard, sizeof(path));
+	strlcat(path, "/operstate", sizeof(path));
 
 	/* open wifi file */
 	if(!(fp = fopen(path, "r"))) {
@@ -716,8 +722,8 @@ wifi_perc(const char *wificard)
 	}
 
 	/* extract the signal strength */
-	strcpy(needle, wificard);
-	strcat(needle, ":");
+	strlcpy(needle, wificard, sizeof(needle));
+	strlcat(needle, ":", sizeof(needle));
 	fgets(buf, bufsize, fp);
 	fgets(buf, bufsize, fp);
 	fgets(buf, bufsize, fp);
@@ -794,7 +800,7 @@ main(void)
 				element = smprintf(unknowntext);
 				fprintf(stderr, "Failed to format output.\n");
 			}
-			strcat(status_string, element);
+			strlcat(status_string, element, sizeof(status_string));
 			free(res);
 			free(element);
 		}
diff --git a/strlcat.h b/strlcat.h
@@ -0,0 +1,55 @@
+/*	$OpenBSD: strlcat.c,v 1.16 2015/08/31 02:53:57 guenther Exp $	*/
+
+/*
+ * Copyright (c) 1998, 2015 Todd C. Miller <[email protected]>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/types.h>
+#include <string.h>
+
+/*
+ * Appends src to string dst of size dsize (unlike strncat, dsize is the
+ * full size of dst, not space left).  At most dsize-1 characters
+ * will be copied.  Always NUL terminates (unless dsize <= strlen(dst)).
+ * Returns strlen(src) + MIN(dsize, strlen(initial dst)).
+ * If retval >= dsize, truncation occurred.
+ */
+size_t
+strlcat(char *dst, const char *src, size_t dsize)
+{
+	const char *odst = dst;
+	const char *osrc = src;
+	size_t n = dsize;
+	size_t dlen;
+
+	/* Find the end of dst and adjust bytes left but don't go past end. */
+	while (n-- != 0 && *dst != '\0')
+		dst++;
+	dlen = dst - odst;
+	n = dsize - dlen;
+
+	if (n-- == 0)
+		return(dlen + strlen(src));
+	while (*src != '\0') {
+		if (n != 0) {
+			*dst++ = *src;
+			n--;
+		}
+		src++;
+	}
+	*dst = '\0';
+
+	return(dlen + (src - osrc));	/* count does not include NUL */
+}
diff --git a/strlcpy.h b/strlcpy.h
@@ -0,0 +1,50 @@
+/*	$OpenBSD: strlcpy.c,v 1.13 2015/08/31 02:53:57 guenther Exp $	*/
+
+/*
+ * Copyright (c) 1998, 2015 Todd C. Miller <[email protected]>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/types.h>
+#include <string.h>
+
+/*
+ * Copy string src to buffer dst of size dsize.  At most dsize-1
+ * chars will be copied.  Always NUL terminates (unless dsize == 0).
+ * Returns strlen(src); if retval >= dsize, truncation occurred.
+ */
+size_t
+strlcpy(char *dst, const char *src, size_t dsize)
+{
+	const char *osrc = src;
+	size_t nleft = dsize;
+
+	/* Copy as many bytes as will fit. */
+	if (nleft != 0) {
+		while (--nleft != 0) {
+			if ((*dst++ = *src++) == '\0')
+				break;
+		}
+	}
+
+	/* Not enough room in dst, add NUL and traverse rest of src. */
+	if (nleft == 0) {
+		if (dsize != 0)
+			*dst = '\0';		/* NUL-terminate dst */
+		while (*src++)
+			;
+	}
+
+	return(src - osrc - 1);	/* count does not include NUL */
+}