Эх сурвалжийг харах

Add strlcpy if not available to enhance copy of device string

- check strlcpy in configure.ac
- test for empty device string
- test truncated device string
Stéphane Raimbault 14 жил өмнө
parent
commit
4ac3cc374f

+ 1 - 2
configure.ac

@@ -81,7 +81,6 @@ AC_CHECK_HEADERS([ \
 # Checks for header files.
 AC_HEADER_STDC
 
-
 # Checks for typedefs, structures, and compiler characteristics.
 AC_C_CONST
 AC_TYPE_SIZE_T
@@ -97,7 +96,7 @@ AC_CHECK_DECLS([__CYGWIN__])
 
 # Checks for library functions.
 AC_FUNC_FORK
-AC_CHECK_FUNCS([gettimeofday inet_ntoa memset select socket strerror])
+AC_CHECK_FUNCS([gettimeofday inet_ntoa memset select socket strerror strlcpy])
 
 AC_CONFIG_FILES([
         Makefile

+ 4 - 0
src/modbus-private.h

@@ -109,6 +109,10 @@ struct _modbus {
 void _modbus_init_common(modbus_t *ctx);
 void _error_print(modbus_t *ctx, const char *context);
 
+#ifndef HAVE_STRLCPY
+size_t strlcpy(char *dest, const char *src, size_t dest_size);
+#endif
+
 MODBUS_END_DECLS
 
 #endif  /* _MODBUS_PRIVATE_H_ */

+ 19 - 5
src/modbus-rtu.c

@@ -853,6 +853,8 @@ modbus_t* modbus_new_rtu(const char *device,
 {
     modbus_t *ctx;
     modbus_rtu_t *ctx_rtu;
+    size_t dest_size;
+    size_t src_size;
 
     ctx = (modbus_t *) malloc(sizeof(modbus_t));
     _modbus_init_common(ctx);
@@ -860,11 +862,23 @@ modbus_t* modbus_new_rtu(const char *device,
     ctx->backend = &_modbus_rtu_backend;
     ctx->backend_data = (modbus_rtu_t *) malloc(sizeof(modbus_rtu_t));
     ctx_rtu = (modbus_rtu_t *)ctx->backend_data;
-#if defined(OpenBSD)
-    strlcpy(ctx_rtu->device, device, sizeof(ctx_rtu->device));
-#else
-    strcpy(ctx_rtu->device, device);
-#endif
+
+    dest_size = sizeof(ctx_rtu->device);
+    src_size = strlcpy(ctx_rtu->device, device, dest_size);
+    if (src_size == 0) {
+        modbus_free(ctx);
+        fprintf(stderr, "The device string is empty\n");
+        errno = EINVAL;
+        return NULL;
+    }
+
+    if (src_size >= dest_size) {
+        modbus_free(ctx);
+        fprintf(stderr, "The device string has been truncated\n");
+        errno = EINVAL;
+        return NULL;
+    }
+
     ctx_rtu->baud = baud;
     if (parity == 'N' || parity == 'E' || parity == 'O') {
         ctx_rtu->parity = parity;

+ 39 - 0
src/modbus.c

@@ -1425,3 +1425,42 @@ int modbus_accept(modbus_t *ctx, int *socket)
 {
     return ctx->backend->accept(ctx, socket);
 }
+
+#ifndef HAVE_STRLCPY
+/*
+/* Function strlcpy was originally developed by
+ * Todd C. Miller <Todd.Miller@courtesan.com> to simplify writing secure code.
+ * See ftp://ftp.openbsd.org/pub/OpenBSD/src/lib/libc/string/strlcpy.3
+ * for more information.
+ *
+ * Thank you Ulrich Drepper... not!
+ *
+ * Copy src to string dest of size dest_size.  At most dest_size-1 characters
+ * will be copied.  Always NUL terminates (unless dest_size == 0).  Returns
+ * strlen(src); if retval >= dest_size, truncation occurred.
+ */
+size_t strlcpy(char *dest, const char *src, size_t dest_size)
+{
+    register char *d = dest;
+    register const char *s = src;
+    register size_t n = dest_size;
+
+    /* Copy as many bytes as will fit */
+    if (n != 0 && --n != 0) {
+        do {
+            if ((*d++ = *s++) == 0)
+                break;
+        } while (--n != 0);
+    }
+
+    /* Not enough room in dest, add NUL and traverse rest of src */
+    if (n == 0) {
+        if (dest_size != 0)
+            *d = '\0'; /* NUL-terminate dest */
+        while (*s++)
+            ;
+    }
+
+    return (s - src - 1); /* count does not include NUL */
+}
+#endif

+ 4 - 0
tests/unit-test-client.c

@@ -48,6 +48,10 @@ int main(void)
 
     /* TCP */
     ctx = modbus_new_tcp("127.0.0.1", 1502);
+    if (ctx == NULL) {
+        fprintf(stderr, "Unable to initialize TCP Modbus\n");
+        return -1;
+    }
     modbus_set_debug(ctx, TRUE);
 
     if (modbus_connect(ctx) == -1) {