diff options
| -rw-r--r-- | CMakeLists.txt | 4 | ||||
| -rw-r--r-- | src/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/core/endpt.c | 3 | ||||
| -rw-r--r-- | src/core/list.c | 2 | ||||
| -rw-r--r-- | src/core/nng_impl.h | 1 | ||||
| -rw-r--r-- | src/core/options.c | 6 | ||||
| -rw-r--r-- | src/core/strs.c | 98 | ||||
| -rw-r--r-- | src/core/strs.h | 21 | ||||
| -rw-r--r-- | src/core/transport.c | 11 | ||||
| -rw-r--r-- | src/platform/posix/posix_ipc.c | 7 | ||||
| -rw-r--r-- | src/platform/posix/posix_sockaddr.c | 5 | ||||
| -rw-r--r-- | src/transport/ipc/ipc.c | 20 | ||||
| -rw-r--r-- | src/transport/tcp/tcp.c | 9 |
13 files changed, 169 insertions, 20 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index d7d05c56..87320843 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -239,6 +239,10 @@ else () nng_check_struct_member(msghdr msg_control sys/socket.h NNG_HAVE_MSG_CONTROL) endif () +nng_check_sym (strdup string.h NNG_HAVE_STRDUP) +nng_check_sym (strlcat string.h NNG_HAVE_STRLCAT) +nng_check_sym (strlcpy string.h NNG_HAVE_STRLCPY) + add_subdirectory (src) if (NNG_TESTS) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1510d633..1d616e95 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -66,6 +66,8 @@ set (NNG_SOURCES core/random.h core/socket.c core/socket.h + core/strs.c + core/strs.h core/taskq.c core/taskq.h core/thread.c diff --git a/src/core/endpt.c b/src/core/endpt.c index f6aaf629..9dc33867 100644 --- a/src/core/endpt.c +++ b/src/core/endpt.c @@ -146,8 +146,7 @@ nni_ep_create(nni_ep **epp, nni_sock *s, const char *addr, int mode) // dereference on hot paths. ep->ep_ops = *tran->tran_ep; - // Could safely use strcpy here, but this avoids discussion. - (void) snprintf(ep->ep_addr, sizeof(ep->ep_addr), "%s", addr); + (void) nni_strlcpy(ep->ep_addr, addr, sizeof(ep->ep_addr)); NNI_LIST_NODE_INIT(&ep->ep_node); diff --git a/src/core/list.c b/src/core/list.c index 97fe5c30..8b26b64a 100644 --- a/src/core/list.c +++ b/src/core/list.c @@ -1,5 +1,5 @@ // -// Copyright 2017up Garrett D'Amore <garrett@damore.org> +// Copyright 2017 Garrett D'Amore <garrett@damore.org> // // This software is supplied under the terms of the MIT License, a // copy of which should be located in the distribution where this diff --git a/src/core/nng_impl.h b/src/core/nng_impl.h index 8510dfb5..905411d7 100644 --- a/src/core/nng_impl.h +++ b/src/core/nng_impl.h @@ -38,6 +38,7 @@ #include "core/panic.h" #include "core/protocol.h" #include "core/random.h" +#include "core/strs.h" #include "core/taskq.h" #include "core/thread.h" #include "core/timer.h" diff --git a/src/core/options.c b/src/core/options.c index 03002d6c..4027564c 100644 --- a/src/core/options.c +++ b/src/core/options.c @@ -275,13 +275,11 @@ nni_option_set_id(const char *name, int id) nni_mtx_unlock(&nni_option_lk); return (NNG_ENOMEM); } - len = strlen(name) + 1; - if ((opt->o_name = nni_alloc(len)) == NULL) { + if ((opt->o_name = nni_strdup(name)) == NULL) { nni_mtx_unlock(&nni_option_lk); NNI_FREE_STRUCT(opt); return (NNG_ENOMEM); } - (void) snprintf(opt->o_name, len, "%s", name); if (id < 0) { id = nni_option_nextid++; } @@ -347,7 +345,7 @@ nni_option_sys_fini(void) nni_option *opt; while ((opt = nni_list_first(&nni_options)) != NULL) { nni_list_remove(&nni_options, opt); - nni_free(opt->o_name, strlen(opt->o_name) + 1); + nni_strfree(opt->o_name); NNI_FREE_STRUCT(opt); } } diff --git a/src/core/strs.c b/src/core/strs.c new file mode 100644 index 00000000..7f236236 --- /dev/null +++ b/src/core/strs.c @@ -0,0 +1,98 @@ +// +// Copyright 2017 Garrett D'Amore <garrett@damore.org> +// Copyright 2017 Capitar IT Group BV <info@capitar.com> +// +// This software is supplied under the terms of the MIT License, a +// copy of which should be located in the distribution where this +// file was obtained (LICENSE.txt). A copy of the license may also be +// found online at https://opensource.org/licenses/MIT. +// + +#include <stdlib.h> +#include <string.h> + +#include "core/nng_impl.h" + +// This file contains implementation of utility functions that are not +// part of standard C99. (C11 has added some things here, but we cannot +// count on them.) + +char * +nni_strdup(const char *src) +{ +#ifdef NNG_HAVE_STRDUP + return (strdup(src)); +#else + char * dst; + size_t len = strlen(src); + + if ((dst = nni_alloc(len)) != NULL) { + memcpy(dst, src, len); + } + return (dst); +#endif +} + +void +nni_strfree(char *s) +{ + if (s != NULL) { +#ifdef NNG_HAVE_STRDUP + free(s); +#else + nni_free(s, strlen(s) + 1); +#endif + } +} + +size_t +nni_strlcpy(char *dst, const char *src, size_t len) +{ +#ifdef NNG_HAVE_STRLCPY + return (strlcpy(dst, src, len)); +#else + size_t n; + char c; + + n = 0; + do { + c = *src++; + n++; + if (n < len) { + *dst++ = c; + } else if (n == len) { + *dst = '\0'; + } + } while (c); + return (n - 1); +#endif +} + +size_t +nni_strlcat(char *dst, const char *src, size_t len) +{ +#ifdef NNG_HAVE_STRLCAT + return (strlcat(dst, src, len)); +#else + size_t n; + char c; + + n = 0; + while ((*dst != '\0') && (n < len)) { + n++; + dst++; + } + + do { + c = *src++; + n++; + if (n < len) { + *dst++ = c; + } else if (n == len) { + *dst = '\0'; + } + } while (c); + + return (n - 1); +#endif +} diff --git a/src/core/strs.h b/src/core/strs.h new file mode 100644 index 00000000..741504cd --- /dev/null +++ b/src/core/strs.h @@ -0,0 +1,21 @@ +// +// Copyright 2017 Garrett D'Amore <garrett@damore.org> +// Copyright 2017 Capitar IT Group BV <info@capitar.com> +// +// This software is supplied under the terms of the MIT License, a +// copy of which should be located in the distribution where this +// file was obtained (LICENSE.txt). A copy of the license may also be +// found online at https://opensource.org/licenses/MIT. +// + +#ifndef CORE_STRS_H +#define CORE_STRS_H + +// Safe string functions, in case the platform misses these. + +extern char * nni_strdup(const char *); +extern void nni_strfree(char *); +extern size_t nni_strlcpy(char *, const char *, size_t); +extern size_t nni_strlcat(char *, const char *, size_t); + +#endif // CORE_STRS_H diff --git a/src/core/transport.c b/src/core/transport.c index 3130ae26..eead861b 100644 --- a/src/core/transport.c +++ b/src/core/transport.c @@ -34,6 +34,7 @@ nni_tran_register(const nni_tran *tran) { nni_transport *t; int rv; + size_t sz; // Its entirely possible that we are called before any sockets // are opened. Make sure we are initialized. This has to be @@ -56,12 +57,18 @@ nni_tran_register(const nni_tran *tran) } } if ((t = NNI_ALLOC_STRUCT(t)) == NULL) { + nni_mtx_unlock(&nni_tran_lk); return (NNG_ENOMEM); } t->t_tran = *tran; - (void) snprintf( - t->t_prefix, sizeof(t->t_prefix), "%s://", tran->tran_scheme); + sz = sizeof(t->t_prefix); + if ((nni_strlcpy(t->t_prefix, tran->tran_scheme, sz) >= sz) || + (nni_strlcat(t->t_prefix, "://", sz) >= sz)) { + nni_mtx_unlock(&nni_tran_lk); + NNI_FREE_STRUCT(t); + return (NNG_EINVAL); + } if ((rv = t->t_tran.tran_init()) != 0) { nni_mtx_unlock(&nni_tran_lk); NNI_FREE_STRUCT(t); diff --git a/src/platform/posix/posix_ipc.c b/src/platform/posix/posix_ipc.c index 2daec4ea..f0a9a973 100644 --- a/src/platform/posix/posix_ipc.c +++ b/src/platform/posix/posix_ipc.c @@ -98,9 +98,14 @@ nni_plat_ipc_remove_stale(const char *path) int fd; int rv; struct sockaddr_un sun; + size_t sz; sun.sun_family = AF_UNIX; - snprintf(sun.sun_path, sizeof(sun.sun_path), "%s", path); + sz = sizeof(sun.sun_path); + + if (nni_strlcpy(sun.sun_path, path, sz) >= sz) { + return (NNG_EADDRINVAL); + } if ((fd = socket(AF_UNIX, NNI_STREAM_SOCKTYPE, 0)) < 0) { return (nni_plat_errno(errno)); diff --git a/src/platform/posix/posix_sockaddr.c b/src/platform/posix/posix_sockaddr.c index 21a2b863..ea630b01 100644 --- a/src/platform/posix/posix_sockaddr.c +++ b/src/platform/posix/posix_sockaddr.c @@ -31,6 +31,7 @@ nni_posix_nn2sockaddr(void *sa, const nni_sockaddr *na) const nng_sockaddr_in * nsin; const nng_sockaddr_in6 * nsin6; const nng_sockaddr_path *nspath; + size_t sz; switch (na->s_un.s_family) { case NNG_AF_INET: @@ -59,8 +60,8 @@ nni_posix_nn2sockaddr(void *sa, const nni_sockaddr *na) nspath = &na->s_un.s_path; memset(spath, 0, sizeof(*spath)); // Make sure that the path fits! - if (snprintf(spath->sun_path, sizeof(spath->sun_path), "%s", - nspath->sa_path) >= sizeof(spath->sun_path)) { + sz = sizeof(spath->sun_path); + if (nni_strlcpy(spath->sun_path, nspath->sa_path, sz) >= sz) { return (-1); } spath->sun_family = PF_UNIX; diff --git a/src/transport/ipc/ipc.c b/src/transport/ipc/ipc.c index e5e19f36..b2c382fb 100644 --- a/src/transport/ipc/ipc.c +++ b/src/transport/ipc/ipc.c @@ -486,20 +486,29 @@ nni_ipc_ep_init(void **epp, const char *url, nni_sock *sock, int mode) nni_ipc_ep * ep; int rv; nni_sockaddr sa; + size_t sz; - if ((strlen(url) > NNG_MAXADDRLEN - 1) || - (strncmp(url, "ipc://", strlen("ipc://")) != 0)) { + if (strncmp(url, "ipc://", strlen("ipc://")) != 0) { return (NNG_EADDRINVAL); } + url += strlen("ipc://"); + sz = sizeof(sa.s_un.s_path.sa_path); sa.s_un.s_path.sa_family = NNG_AF_IPC; - (void) snprintf(sa.s_un.s_path.sa_path, sizeof(sa.s_un.s_path.sa_path), - "%s", url + strlen("ipc://")); + + if (nni_strlcpy(sa.s_un.s_path.sa_path, url, sz) >= sz) { + return (NNG_EADDRINVAL); + } if ((ep = NNI_ALLOC_STRUCT(ep)) == NULL) { return (NNG_ENOMEM); } - url += strlen("ipc://"); + + if (nni_strlcpy(ep->addr, url, sizeof(ep->addr)) >= sizeof(ep->addr)) { + NNI_FREE_STRUCT(ep); + return (NNG_EADDRINVAL); + } + if ((rv = nni_plat_ipc_ep_init(&ep->iep, &sa, mode)) != 0) { NNI_FREE_STRUCT(ep); return (rv); @@ -509,7 +518,6 @@ nni_ipc_ep_init(void **epp, const char *url, nni_sock *sock, int mode) nni_aio_init(&ep->aio, nni_ipc_ep_cb, ep); ep->proto = nni_sock_proto(sock); - (void) snprintf(ep->addr, sizeof(ep->addr), "%s", url); *epp = ep; return (0); diff --git a/src/transport/tcp/tcp.c b/src/transport/tcp/tcp.c index de1bfa66..f0f07592 100644 --- a/src/transport/tcp/tcp.c +++ b/src/transport/tcp/tcp.c @@ -579,7 +579,9 @@ nni_tcp_ep_init(void **epp, const char *url, nni_sock *sock, int mode) int passive; // Make a copy of the url (to allow for destructive operations) - snprintf(buf, sizeof(buf), "%s", url); + if (nni_strlcpy(buf, url, sizeof(buf)) >= sizeof(buf)) { + return (NNG_EADDRINVAL); + } // Parse the URLs first. rv = nni_tcp_parse_url(buf, &lhost, &lserv, &rhost, &rserv, mode); @@ -620,6 +622,10 @@ nni_tcp_ep_init(void **epp, const char *url, nni_sock *sock, int mode) if ((ep = NNI_ALLOC_STRUCT(ep)) == NULL) { return (NNG_ENOMEM); } + if (nni_strlcpy(ep->addr, url, sizeof(ep->addr)) >= sizeof(ep->addr)) { + NNI_FREE_STRUCT(ep); + return (NNG_EADDRINVAL); + } if ((rv = nni_plat_tcp_ep_init(&ep->tep, &lsa, &rsa, mode)) != 0) { NNI_FREE_STRUCT(ep); @@ -630,7 +636,6 @@ nni_tcp_ep_init(void **epp, const char *url, nni_sock *sock, int mode) nni_aio_init(&ep->aio, nni_tcp_ep_cb, ep); ep->proto = nni_sock_proto(sock); - (void) snprintf(ep->addr, sizeof(ep->addr), "%s", url); *epp = ep; return (0); |
