diff --git a/configure.ac b/configure.ac index 2f4d8d8..bf34d6a 100644 --- a/configure.ac +++ b/configure.ac @@ -25,6 +25,10 @@ if test x"$have_pamheader" != x"yes"; then AC_MSG_ERROR(You are missing PAM headers) fi +AC_CHECK_FUNC([memset_s], [ + AC_DEFINE([HAVE_MEMSET_S], [1], [Define if has memset_s]) +]) + case "$host" in (*-*-linux*) PAM_MODDIR="\$(slibdir)/security"; diff --git a/pam_shield.c b/pam_shield.c index e594fc3..dbabab6 100644 --- a/pam_shield.c +++ b/pam_shield.c @@ -98,7 +98,7 @@ static _pam_shield_db_rec_t *new_db_record(int window_size) { logmsg(LOG_CRIT, "new_db_record(): out of memory allocating %d bytes", size); return NULL; } - memset(record, 0, size); + memset_s(record, size, 0, size); record->max_entries = window_size; return record; } @@ -117,7 +117,7 @@ static struct addrinfo *get_addr_info(char *rhost) { struct addrinfo hints, *res; int err; - memset(&hints, 0, sizeof(struct addrinfo)); + memset_s(&hints, sizeof(struct addrinfo), 0, sizeof(struct addrinfo)); hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; diff --git a/pam_shield_lib.c b/pam_shield_lib.c index cc44099..321aea9 100644 --- a/pam_shield_lib.c +++ b/pam_shield_lib.c @@ -69,7 +69,7 @@ ip_list *new_ip_list(void) { if ((ip = (ip_list *)malloc(sizeof(ip_list))) == NULL) return NULL; - memset(ip, 0, sizeof(ip_list)); + memset_s(ip, sizeof(ip_list), 0, sizeof(ip_list)); return ip; } @@ -171,7 +171,7 @@ name_list *new_name_list(char *name) { if ((n = (name_list *)malloc(sizeof(name_list) + strlen(name))) == NULL) return NULL; - memset(n, 0, sizeof(name_list)); + memset_s(n, sizeof(name_list), 0, sizeof(name_list)); snprintf(n->name, sizeof(n->name), "%s", name); return n; } @@ -347,7 +347,7 @@ void ip_bitmask(int bits, unsigned char *mask, int size) { if (mask == NULL) return; - memset(mask, 0, size); + memset_s(mask, size, 0, size); if (bits < 0) bits = 0; @@ -397,7 +397,7 @@ int allow_ip(char *ipnum, int line_no) { /* try network address as IPv4 */ if (inet_pton(AF_INET, ipnum, &ip->ip.in) > 0) { if (netmask == NULL) { /* no netmask given, treat as host */ - memset(&ip->mask.in.s_addr, 0xff, sizeof(ip->mask.in.s_addr)); + memset_s(&ip->mask.in.s_addr, sizeof(ip->mask.in.s_addr), 0xff, sizeof(ip->mask.in.s_addr)); add_ip_list(&allow_ipv4_list, ip); return 0; } @@ -426,7 +426,7 @@ int allow_ip(char *ipnum, int line_no) { /* try network address as IPv6 */ if (inet_pton(AF_INET6, ipnum, &ip->ip.in6) > 0) { if (netmask == NULL) { /* no netmask given, treat as host */ - memset(ip->mask.in6.s6_addr, 0xff, sizeof(ip->mask.in6.s6_addr)); + memset_s(ip->mask.in6.s6_addr, sizeof(ip->mask.in6.s6_addr), 0xff, sizeof(ip->mask.in6.s6_addr)); add_ip_list(&allow_ipv6_list, ip); return 0; } @@ -758,4 +758,18 @@ void fatal_func(const char *str) { logmsg(LOG_ERR, "failed to create new gdbm file '%s' : %s", dbfile, gdbm_strerror(gdbm_errno)); } +#ifndef HAVE_MEMSET_S +void memset_s(void *dest, size_t destsz, int c, size_t count) { + if (count > destsz) { + fprintf(stderr, "Error: count exceeds destsz\n"); + exit(EXIT_FAILURE); + } + + unsigned char *p = (unsigned char *)dest; + while (count--) { + *p++ = (unsigned char)c; + } +} +#endif + #pragma GCC visibility pop diff --git a/pam_shield_lib.h b/pam_shield_lib.h index 3698ec8..576403b 100644 --- a/pam_shield_lib.h +++ b/pam_shield_lib.h @@ -165,4 +165,8 @@ int expire_record(_pam_shield_db_rec_t *record); /* gdbm has encountered a fatal error */ void fatal_func(const char *str); +#ifndef HAVE_MEMSET_S +void memset_s(void *dest, size_t destsz, int c, size_t count); +#endif + #pragma GCC visibility pop