From 7a6382f0b6869e10ea5b9cbded6977e7f4d62ea6 Mon Sep 17 00:00:00 2001 From: Angus Salkeld Date: Wed, 8 Feb 2012 20:32:11 +1100 Subject: [PATCH] Use safer versions of string functions (strcpy -> strlcpy) Signed-off-by: Angus Salkeld --- configure.ac | 8 ++++---- include/os_base.h | 10 +++++++++- lib/Makefile.am | 1 + lib/ipc_posix_mq.c | 4 ++-- lib/ipc_us.c | 6 +++--- lib/ipcc.c | 2 +- lib/ipcs.c | 2 +- lib/log.c | 6 +++--- lib/log_file.c | 4 ++-- lib/ringbuffer.c | 4 ++-- lib/strchrnul.c | 35 +++++++++++++++++++++++++++++++++++ lib/strlcat.c | 32 ++++++++++++++++++++++++++++++++ lib/strlcpy.c | 31 +++++++++++++++++++++++++++++++ lib/unix.c | 16 +--------------- lib/util_int.h | 4 ---- 15 files changed, 127 insertions(+), 38 deletions(-) create mode 100644 lib/strchrnul.c create mode 100644 lib/strlcat.c create mode 100644 lib/strlcpy.c diff --git a/configure.ac b/configure.ac index fd158aa..34b4a5a 100644 --- a/configure.ac +++ b/configure.ac @@ -138,17 +138,17 @@ AC_TYPE_UINT8_T # Checks for library functions. AC_FUNC_CHOWN -AC_FUNC_ERROR_AT_LINE AC_FUNC_FORK -AC_FUNC_MALLOC AC_FUNC_MMAP -AC_FUNC_REALLOC AC_CHECK_FUNCS([alarm clock_gettime ftruncate gettimeofday localtime localtime_r \ - memset munmap socket strchr strrchr strchrnul strdup strerror strstr \ + memset munmap socket strchr strrchr strdup strerror strstr \ poll epoll_create epoll_create1 random rand getrlimit sysconf \ pthread_spin_lock timerfd_create pthread_setschedparam \ sched_get_priority_max sched_setscheduler]) +AC_CONFIG_LIBOBJ_DIR(lib) +AC_REPLACE_FUNCS(strlcpy strlcat strchrnul) + ## local defines PACKAGE_FEATURES="" diff --git a/include/os_base.h b/include/os_base.h index 8c9b039..9ee3804 100644 --- a/include/os_base.h +++ b/include/os_base.h @@ -129,8 +129,16 @@ #endif /* _POSIX_THREAD_PROCESS_SHARED */ #endif /* DISABLE_POSIX_THREAD_PROCESS_SHARED */ -#ifdef QB_DARWIN +#ifndef HAVE_STRCHRNUL char *strchrnul (const char *s, int c_in); #endif +#ifndef HAVE_STRLCPY +size_t strlcpy(char *dest, const char *src, size_t maxlen); +#endif + +#ifndef HAVE_STRLCAT +size_t strlcat(char *dest, const char *src, size_t maxlen); +#endif + #endif /* QB_OS_BASE_H_DEFINED */ diff --git a/lib/Makefile.am b/lib/Makefile.am index de4cd63..83bf77e 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -46,6 +46,7 @@ source_to_lint = util.c hdb.c ringbuffer.c ringbuffer_helper.c array.c \ map.c skiplist.c hashtable.c trie.c libqb_la_SOURCES = $(source_to_lint) unix.c +libqb_la_LIBADD = @LTLIBOBJS@ if HAVE_SYSV_MQ libqb_la_SOURCES+=ipc_sysv_mq.c diff --git a/lib/ipc_posix_mq.c b/lib/ipc_posix_mq.c index dfee34e..6ed29dd 100644 --- a/lib/ipc_posix_mq.c +++ b/lib/ipc_posix_mq.c @@ -88,7 +88,7 @@ posix_mq_open(struct qb_ipc_one_way *one_way, const char *name, size_t q_len) perror("mq_open"); return res; } - strcpy(one_way->u.pmq.name, name); + (void)strlcpy(one_way->u.pmq.name, name, NAME_MAX); q_space_used += one_way->max_msg_size * q_len; return 0; } @@ -130,7 +130,7 @@ try_smaller: q_space_used += max_msg_size * q_len; one_way->max_msg_size = max_msg_size; one_way->u.pmq.q = q; - strcpy(one_way->u.pmq.name, name); + (void)strlcpy(one_way->u.pmq.name, name, NAME_MAX); res = fchown((int)q, c->euid, c->egid); if (res == -1) { diff --git a/lib/ipc_us.c b/lib/ipc_us.c index 4b7b032..d56a17d 100644 --- a/lib/ipc_us.c +++ b/lib/ipc_us.c @@ -381,7 +381,7 @@ qb_ipcc_us_connect(struct qb_ipcc_connection *c, qb_util_perror(LOG_ERR, "couldn't open file for mmap"); return res; } - strcpy(c->request.u.us.shared_file_name, r->request); + (void)strlcpy(c->request.u.us.shared_file_name, r->request, NAME_MAX); c->request.u.us.shared_data = mmap(0, sizeof(struct ipc_us_control), PROT_READ | PROT_WRITE, MAP_SHARED, @@ -837,8 +837,8 @@ qb_ipcs_us_connect(struct qb_ipcs_service *s, qb_util_perror(LOG_ERR, "couldn't create file for mmap"); return res; } - strcpy(r->request, path); - strcpy(c->request.u.us.shared_file_name, r->request); + (void)strlcpy(r->request, path, PATH_MAX); + (void)strlcpy(c->request.u.us.shared_file_name, r->request, NAME_MAX); c->request.u.us.shared_data = mmap(0, sizeof(struct ipc_us_control), diff --git a/lib/ipcc.c b/lib/ipcc.c index 1ead2b9..e801538 100644 --- a/lib/ipcc.c +++ b/lib/ipcc.c @@ -41,7 +41,7 @@ qb_ipcc_connect(const char *name, size_t max_msg_size) } c->setup.max_msg_size = max_msg_size; - strcpy(c->name, name); + (void)strlcpy(c->name, name, NAME_MAX); res = qb_ipcc_us_setup_connect(c, &response); if (res < 0) { goto disconnect_and_cleanup; diff --git a/lib/ipcs.c b/lib/ipcs.c index 6bf77b4..0c630ba 100644 --- a/lib/ipcs.c +++ b/lib/ipcs.c @@ -50,7 +50,7 @@ qb_ipcs_create(const char *name, s->ref_count = 1; s->service_id = service_id; - strncpy(s->name, name, NAME_MAX); + (void)strlcpy(s->name, name, NAME_MAX); s->serv_fns.connection_accept = handlers->connection_accept; s->serv_fns.connection_created = handlers->connection_created; diff --git a/lib/log.c b/lib/log.c index 9dfb99e..b4b4f3e 100644 --- a/lib/log.c +++ b/lib/log.c @@ -670,7 +670,7 @@ qb_log_init(const char *name, int32_t facility, uint8_t priority) conf[i].pos = i; conf[i].debug = QB_FALSE; conf[i].state = QB_LOG_STATE_UNUSED; - strncpy(conf[i].name, name, PATH_MAX); + (void)strlcpy(conf[i].name, name, PATH_MAX); conf[i].facility = facility; qb_list_init(&conf[i].filter_head); qb_log_format_set(i, NULL); @@ -945,9 +945,9 @@ qb_log_format_set(int32_t t, const char *format) len += strlen(conf[t].name); conf[t].format = calloc(len + 1, sizeof(char)); strncpy(conf[t].format, format, ptr - format); - strcat(conf[t].format, conf[t].name); + (void)strlcat(conf[t].format, conf[t].name, len); ptr += 2; - strcat(conf[t].format, ptr); + (void)strlcat(conf[t].format, ptr, len); } else { conf[t].format = strdup(format ? format : "[%p] %b"); } diff --git a/lib/log_file.c b/lib/log_file.c index 6598566..7a77d8d 100644 --- a/lib/log_file.c +++ b/lib/log_file.c @@ -67,7 +67,7 @@ qb_log_stderr_open(struct qb_log_target *t) t->logger = _file_logger; t->reload = NULL; t->close = NULL; - strncpy(t->filename, "stderr", PATH_MAX); + (void)strlcpy(t->filename, "stderr", PATH_MAX); t->instance = stderr; return 0; } @@ -91,7 +91,7 @@ qb_log_file_open(const char *filename) return rc; } t->instance = fp; - strncpy(t->filename, filename, PATH_MAX); + (void)strlcpy(t->filename, filename, PATH_MAX); t->logger = _file_logger; t->reload = _file_reload; diff --git a/lib/ringbuffer.c b/lib/ringbuffer.c index 4259bf0..e76abcf 100644 --- a/lib/ringbuffer.c +++ b/lib/ringbuffer.c @@ -149,7 +149,7 @@ qb_rb_open(const char *name, size_t size, uint32_t flags, rb->shared_hdr->size = real_size / sizeof(uint32_t); rb->shared_hdr->write_pt = 0; rb->shared_hdr->read_pt = 0; - strncpy(rb->shared_hdr->hdr_path, path, PATH_MAX); + (void)strlcpy(rb->shared_hdr->hdr_path, path, PATH_MAX); } error = qb_rb_sem_create(rb, flags); if (error < 0) { @@ -165,7 +165,7 @@ qb_rb_open(const char *name, size_t size, uint32_t flags, fd_data = qb_sys_mmap_file_open(path, filename, real_size, file_flags); - strncpy(rb->shared_hdr->data_path, path, PATH_MAX); + (void)strlcpy(rb->shared_hdr->data_path, path, PATH_MAX); } else { fd_data = qb_sys_mmap_file_open(path, rb->shared_hdr->data_path, diff --git a/lib/strchrnul.c b/lib/strchrnul.c new file mode 100644 index 0000000..e404650 --- /dev/null +++ b/lib/strchrnul.c @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2012 Red Hat, Inc. + * + * All rights reserved. + * + * Author: Angus Salkeld + * + * libqb is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * libqb is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libqb. If not, see . + */ + +#include "os_base.h" + +/* Find the first occurrence of C in S or the final NUL byte. + */ +char * +strchrnul(const char *s, int c_in) +{ + char c = c_in; + while (*s && (*s != c)) + s++; + + return (char *) s; +} + diff --git a/lib/strlcat.c b/lib/strlcat.c new file mode 100644 index 0000000..56e0bb2 --- /dev/null +++ b/lib/strlcat.c @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2007 Alan Robertson + * This software licensed under the GNU LGPL. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#include "os_base.h" + +size_t +strlcat(char *dest, const char * src, size_t maxlen) +{ + size_t curlen = strlen(dest); + size_t addlen = strlen(src); + size_t appendlen = (maxlen-1) - curlen; + if (appendlen > 0) { + strlcpy(dest+curlen, src, maxlen-curlen); + } + return curlen + addlen; +} diff --git a/lib/strlcpy.c b/lib/strlcpy.c new file mode 100644 index 0000000..8949e3b --- /dev/null +++ b/lib/strlcpy.c @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2007 Alan Robertson + * This software licensed under the GNU LGPL. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#include "os_base.h" + +size_t +strlcpy(char *dest, const char * src, size_t maxlen) +{ + size_t srclen = strlen(src); + if (maxlen > 0) { + strncpy(dest, src, maxlen); + dest[maxlen-1] = '\0'; + } + return srclen; +} diff --git a/lib/unix.c b/lib/unix.c index a13955d..963096b 100644 --- a/lib/unix.c +++ b/lib/unix.c @@ -45,20 +45,6 @@ qb_strerror_r(int errnum, char *buf, size_t buflen) #endif /* QB_LINUX */ } -#ifndef HAVE_STRCHRNUL -/* Find the first occurrence of C in S or the final NUL byte. - */ -char * -qb_sys_strchrnul(const char *s, int c_in) -{ - char c = c_in; - while (*s && (*s != c)) - s++; - - return (char *) s; -} -#endif /* HAVE_STRCHRNUL */ - static int32_t open_mmap_file(char *path, uint32_t file_flags) { @@ -81,7 +67,7 @@ qb_sys_mmap_file_open(char *path, const char *file, size_t bytes, char *is_absolute = strchr(file, '/');; if (is_absolute) { - strcpy(path, file); + (void)strlcpy(path, file, PATH_MAX); } else { snprintf(path, PATH_MAX, "/dev/shm/%s", file); } diff --git a/lib/util_int.h b/lib/util_int.h index 9d23285..27c1ca7 100644 --- a/lib/util_int.h +++ b/lib/util_int.h @@ -83,8 +83,4 @@ int32_t qb_sys_circular_mmap(int32_t fd, void **buf, size_t bytes); */ int32_t qb_sys_fd_nonblock_cloexec_set(int32_t fd); -#ifndef HAVE_STRCHRNUL -#define strchrnul(s, c_in) qb_sys_strchrnul(s, c_in) -char * qb_sys_strchrnul(const char *s, int c_in); -#endif /* !HAVE_STRCHRNUL */ #endif /* QB_UTIL_INT_H_DEFINED */