From 48358c3cec881ad3b75e7bfcf10a1f680e9eed7e Mon Sep 17 00:00:00 2001 From: Alex 'AdUser' Z Date: Fri, 18 Mar 2016 17:48:14 +1000 Subject: [PATCH] + add src/strlfuncs.[ch] * use strlcpy() instead strncpy() --- src/CMakeLists.txt | 6 ++-- src/common.h | 2 ++ src/config.c | 20 +++++------ src/ipaddr.c | 2 +- src/jail.c | 8 ++--- src/logfile.c | 2 +- src/main.c | 9 ++--- src/strlfuncs.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++ src/strlfuncs.h | 25 ++++++++++++++ t/CMakeLists.txt | 8 ++--- 10 files changed, 134 insertions(+), 31 deletions(-) create mode 100644 src/strlfuncs.c create mode 100644 src/strlfuncs.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1a9b3ac..9b0b8d7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,15 +1,15 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON) -set(SOURCES "main.c" "logfile.c" "log.c" "matches.c" "ipaddr.c" "filelist.c" "filter.c" "config.c" "jail.c" "backend.c") +set(SOURCES "main.c" "strlfuncs.c" "logfile.c" "log.c" "matches.c" "ipaddr.c" "filelist.c" "filter.c" "config.c" "jail.c" "backend.c") add_executable("f2b" ${SOURCES}) target_link_libraries(f2b "dl") -set(SOURCES "backend-test.c" "log.c" "config.c" "backend.c") +set(SOURCES "strlfuncs.c" "backend-test.c" "log.c" "config.c" "backend.c") add_executable("backend-test" ${SOURCES}) target_link_libraries("backend-test" "dl") -set(SOURCES "filter-test.c" "log.c" "config.c" "filter.c") +set(SOURCES "strlfuncs.c" "filter-test.c" "log.c" "config.c" "filter.c") add_executable("filter-test" ${SOURCES}) target_link_libraries("filter-test" "dl") diff --git a/src/common.h b/src/common.h index 14ff8d6..48c7a15 100644 --- a/src/common.h +++ b/src/common.h @@ -24,6 +24,8 @@ #include #include +#include "strlfuncs.h" + #define UNUSED(x) (void)(x) #define FREE(x) free(x), x = NULL diff --git a/src/config.c b/src/config.c index 17a4860..dde949f 100644 --- a/src/config.c +++ b/src/config.c @@ -17,8 +17,7 @@ f2b_config_param_create(const char *src) { char *p, *key, *value; size_t len; - strncpy(line, src, sizeof(line)); - line[CONFIG_LINE_MAX - 1] = '\0'; + strlcpy(line, src, sizeof(line)); /* strip spaces before key */ key = line; @@ -61,10 +60,8 @@ f2b_config_param_create(const char *src) { return NULL; if ((param = calloc(1, sizeof(f2b_config_param_t))) != NULL) { - strncpy(param->name, key, sizeof(param->name)); - strncpy(param->value, value, sizeof(param->value)); - param->name [CONFIG_KEY_MAX - 1] = '\0'; - param->value[CONFIG_VAL_MAX - 1] = '\0'; + strlcpy(param->name, key, sizeof(param->name)); + strlcpy(param->value, value, sizeof(param->value)); return param; } @@ -92,7 +89,7 @@ f2b_config_param_append(f2b_config_param_t *list, f2b_config_param_t *param, boo if (replace && (p = f2b_config_param_find(list, param->name)) != NULL) { /* found param with same name */ - strncpy(p->value, param->value, sizeof(p->value)); + strlcpy(p->value, param->value, sizeof(p->value)); free(param); return list; } @@ -114,8 +111,7 @@ f2b_config_section_create(const char *src) { assert(*src == '['); src++; - strncpy(line, src, sizeof(line)); - line[CONFIG_LINE_MAX - 1] = '\0'; + strlcpy(line, src, sizeof(line)); if ((end = strchr(line, ']')) == NULL) return NULL; @@ -139,21 +135,21 @@ f2b_config_section_create(const char *src) { name = "backend:"; if (strncmp(line, name, strlen(name)) == 0) { section->type = t_backend; - strncpy(section->name, line + strlen(name), sizeof(section->name)); + strlcpy(section->name, line + strlen(name), sizeof(section->name)); return section; } name = "filter:"; if (strncmp(line, name, strlen(name)) == 0) { section->type = t_filter; - strncpy(section->name, line + strlen(name), sizeof(section->name)); + strlcpy(section->name, line + strlen(name), sizeof(section->name)); return section; } name = "jail:"; if (strncmp(line, name, strlen(name)) == 0) { section->type = t_jail; - strncpy(section->name, line + strlen(name), sizeof(section->name)); + strlcpy(section->name, line + strlen(name), sizeof(section->name)); return section; } diff --git a/src/ipaddr.c b/src/ipaddr.c index 089bc5f..d40964e 100644 --- a/src/ipaddr.c +++ b/src/ipaddr.c @@ -15,7 +15,7 @@ f2b_ipaddr_create(const char *addr, size_t matches) { assert(matches != 0); if ((a = calloc(1, sizeof(f2b_ipaddr_t))) != NULL) { - strncpy(a->text, addr, sizeof(a->text)); + strlcpy(a->text, addr, sizeof(a->text)); if (strchr(addr, ':') == NULL) { a->type = AF_INET; if (inet_pton(a->type, addr, &a->binary.v4) < 1) diff --git a/src/jail.c b/src/jail.c index 9f2ce3e..7d2bb02 100644 --- a/src/jail.c +++ b/src/jail.c @@ -26,7 +26,7 @@ f2b_jail_parse_compound_value(const char *value, char *name, char *init) { if ((p = strchr(value, ':')) == NULL) { /* param = name */ - strncpy(name, value, CONFIG_KEY_MAX); + strlcpy(name, value, CONFIG_KEY_MAX); return; } @@ -37,8 +37,8 @@ f2b_jail_parse_compound_value(const char *value, char *name, char *init) { return; } - strncpy(name, value, len); - strncpy(init, (p + 1), CONFIG_VAL_MAX); + strlcpy(name, value, len); + strlcpy(init, (p + 1), CONFIG_VAL_MAX); return; } @@ -175,7 +175,7 @@ f2b_jail_create(f2b_config_section_t *section) { } memcpy(jail, &defaults, sizeof(f2b_jail_t)); - strncpy(jail->name, section->name, sizeof(jail->name)); + strlcpy(jail->name, section->name, sizeof(jail->name)); f2b_jail_apply_config(jail, section); return jail; diff --git a/src/logfile.c b/src/logfile.c index 46154ea..8261db1 100644 --- a/src/logfile.c +++ b/src/logfile.c @@ -22,7 +22,7 @@ f2b_logfile_open(f2b_logfile_t *file, const char *filename) { if (!(S_ISREG(st.st_mode) || S_ISFIFO(st.st_mode))) return false; - strncpy(file->path, filename, sizeof(file->path)); + strlcpy(file->path, filename, sizeof(file->path)); memcpy(&file->st, &st, sizeof(st)); if ((file->fd = fopen(filename, "r")) == NULL) diff --git a/src/main.c b/src/main.c index 7a309f8..c25b9a5 100644 --- a/src/main.c +++ b/src/main.c @@ -83,7 +83,7 @@ update_opts_from_config(f2b_config_section_t *section) { } if ((pa = f2b_config_param_find(section->param, "pidfile")) != NULL) { - strncpy(opts.pidfile_path, pa->value, sizeof(opts.pidfile_path)); + strlcpy(opts.pidfile_path, pa->value, sizeof(opts.pidfile_path)); opts.pidfile_path[sizeof(opts.pidfile_path) - 1] = '\0'; } @@ -98,9 +98,7 @@ update_opts_from_config(f2b_config_section_t *section) { f2b_log_to_stderr(); } else if (strcmp(pa->value, "file") == 0) { if (pb && *pb->value != '\0') { - size_t len = sizeof(opts.logfile_path); - strncpy(opts.logfile_path, pb->value, len - 1); - opts.logfile_path[len - 1] = '\0'; + strlcpy(opts.logfile_path, pb->value, sizeof(opts.logfile_path)); f2b_log_to_file(opts.logfile_path); } else { f2b_log_msg(log_warn, "you must set 'logfile' option with 'logdest = file'"); @@ -125,8 +123,7 @@ int main(int argc, char *argv[]) { while ((opt = getopt(argc, argv, "c:dh")) != -1) { switch (opt) { case 'c': - strncpy(opts.config_path, optarg, sizeof(opts.config_path)); - opts.config_path[sizeof(opts.config_path) - 1] = '\0'; + strlcpy(opts.config_path, optarg, sizeof(opts.config_path)); break; case 'd': opts.daemon = true; diff --git a/src/strlfuncs.c b/src/strlfuncs.c new file mode 100644 index 0000000..809d21d --- /dev/null +++ b/src/strlfuncs.c @@ -0,0 +1,83 @@ +/* $OpenBSD: strlcpy.c,v 1.13 2015/08/31 02:53:57 guenther Exp $ */ + +/* + * Copyright (c) 1998, 2015 Todd C. Miller + * + * 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 +#include + +/* + * 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 */ +} + +/* + * 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/src/strlfuncs.h b/src/strlfuncs.h new file mode 100644 index 0000000..36ec07e --- /dev/null +++ b/src/strlfuncs.h @@ -0,0 +1,25 @@ +#ifndef HAS_STRLFUNCS_ +#define HAS_STRLFUNCS_ + +/* $OpenBSD: strlcpy.c,v 1.13 2015/08/31 02:53:57 guenther Exp $ */ + +/* + * Copyright (c) 1998, 2015 Todd C. Miller + * + * 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. + */ + +size_t strlcat(char *dst, const char *src, size_t dsize); +size_t strlcpy(char *dst, const char *src, size_t dsize); + +#endif /* HAS_STRLFUNCS_ */ diff --git a/t/CMakeLists.txt b/t/CMakeLists.txt index 405f1b1..109f3f1 100644 --- a/t/CMakeLists.txt +++ b/t/CMakeLists.txt @@ -2,10 +2,10 @@ enable_testing() set(SRC_DIR "../src") -add_executable("t_logfile" "t_logfile.c" "${SRC_DIR}/logfile.c") -add_executable("t_matches" "t_matches.c" "${SRC_DIR}/matches.c") -add_executable("t_ipaddr" "t_ipaddr.c" "${SRC_DIR}/ipaddr.c" "${SRC_DIR}/matches.c") -add_executable("t_config_param" "t_config_param.c" "${SRC_DIR}/config.c" "${SRC_DIR}/log.c") +add_executable("t_logfile" "t_logfile.c" "${SRC_DIR}/strlfuncs.c" "${SRC_DIR}/logfile.c") +add_executable("t_matches" "t_matches.c" "${SRC_DIR}/strlfuncs.c" "${SRC_DIR}/matches.c") +add_executable("t_ipaddr" "t_ipaddr.c" "${SRC_DIR}/strlfuncs.c" "${SRC_DIR}/matches.c" "${SRC_DIR}/ipaddr.c") +add_executable("t_config_param" "t_config_param.c" "${SRC_DIR}/strlfuncs.c" "${SRC_DIR}/config.c" "${SRC_DIR}/log.c") add_test("tests/f2b_logfile_*" "t_logfile") add_test("tests/f2b_matches_*" "t_matches")