From 7467d9b40f2e388a1e1939f3d2914d74e1fddd45 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Wed, 26 Mar 2014 12:48:27 +0100 Subject: [PATCH] Red Hat issue 1022048: strncpy hardening --- CHANGES | 3 +++ sysutils.c | 32 +++++++++++++++-------------- utils.c | 12 ++++++----- xio-ip.c | 54 ++++++++++++++++++++++++++++++------------------- xio-ip6.c | 43 +++++++++++++++++++++++---------------- xio-progcall.c | 4 ++-- xio-pty.c | 4 ++-- xio-readline.c | 4 ++-- xio-socket.c | 22 ++++++++++---------- xio-socks.c | 6 +++--- xio-socks5.c | 8 ++++---- xio-tun.c | 4 ++-- xio-unix.c | 6 +++--- xioopen.c | 5 ++--- xioopts.c | 2 +- xioparam.c | 5 +++-- xiosocketpair.c | 6 +++--- 17 files changed, 124 insertions(+), 96 deletions(-) diff --git a/CHANGES b/CHANGES index bbcc7a5..9b39db8 100644 --- a/CHANGES +++ b/CHANGES @@ -26,6 +26,9 @@ corrections: On big endian platforms with type long >32bit the range option applied a bad base address. Thanks to hejia hejia for reporting and fixing this bug. + Red Hat issue 1022048: strncpy hardening: corrected suspicious strncpy() + uses + Red Hat issue 1021958: fixed a bug with faulty buffer/data length calculation in xio-ascii.c:_xiodump() diff --git a/sysutils.c b/sysutils.c index 3dfda60..9a7b01e 100644 --- a/sysutils.c +++ b/sysutils.c @@ -163,6 +163,9 @@ socklen_t socket_init(int af, union sockaddr_union *sa) { #endif #if _WITH_SOCKET +/* writes a textual human readable representation of the sockaddr contents to buff and returns a pointer to buff + writes at most blen bytes to buff including the terminating \0 byte +*/ char *sockaddr_info(const struct sockaddr *sa, socklen_t salen, char *buff, size_t blen) { union sockaddr_union *sau = (union sockaddr_union *)sa; char *lbuff = buff; @@ -244,8 +247,6 @@ char *sockaddr_unix_info(const struct sockaddr_un *sa, socklen_t salen, char *bu nextc = sanitize_string(sa->sun_path, salen-XIOUNIXSOCKOVERHEAD, ubuff, XIOSAN_DEFAULT_BACKSLASH_OCT_3); - *nextc = '\0'; - strncpy(buff, ubuff, blen); } else #endif /* WITH_ABSTRACT_UNIXSOCKET */ { @@ -257,9 +258,9 @@ char *sockaddr_unix_info(const struct sockaddr_un *sa, socklen_t salen, char *bu MIN(UNIX_PATH_MAX, strlen(sa->sun_path)), ubuff, XIOSAN_DEFAULT_BACKSLASH_OCT_3); } - *nextc = '\0'; - strncpy(buff, ubuff, blen); } + *nextc = '\0'; + buff[0] = '\0'; strncat(buff, ubuff, blen-1); return buff; } #endif /* WITH_UNIX */ @@ -575,7 +576,7 @@ int ifindexbyname(const char *ifname, int anysock) { return -1; } - strncpy(ifr.ifr_name, ifname, IFNAMSIZ); + strncpy(ifr.ifr_name, ifname, IFNAMSIZ); /* ok */ if (Ioctl(s, SIOCGIFINDEX, &ifr) < 0) { Info3("ioctl(%d, SIOCGIFINDEX, {\"%s\"}): %s", s, ifr.ifr_name, strerror(errno)); @@ -638,11 +639,12 @@ int xiosetenv(const char *varname, const char *value, int overwrite) { size_t i, l; progname = diag_get_string('p'); - strncpy(envname, progname, XIO_ENVNAMELEN-1); + envname[0] = '\0'; strncat(envname, progname, XIO_ENVNAMELEN-1); l = strlen(progname); - strncpy(envname+l, "_", XIO_ENVNAMELEN-1-l); for (i = 0; i < l; ++i) envname[i] = toupper(envname[i]); - strncpy(envname+l+1, varname, XIO_ENVNAMELEN-1-l); + strncat(envname+l, "_", XIO_ENVNAMELEN-l-1); + l += 1; + strncat(envname+l, varname, XIO_ENVNAMELEN-l-1); if (Setenv(envname, value, overwrite) < 0) { Warn3("setenv(\"%s\", \"%s\", 1): %s", envname, value, strerror(errno)); @@ -663,16 +665,16 @@ int xiosetenv2(const char *varname, const char *varname2, const char *value, size_t i, l; progname = diag_get_string('p'); - strncpy(envname, progname, XIO_ENVNAMELEN-1); + envname[0] = '\0'; strncat(envname, progname, XIO_ENVNAMELEN-1); l = strlen(progname); - strncpy(envname+l, "_", XIO_ENVNAMELEN-1-l); + strncat(envname+l, "_", XIO_ENVNAMELEN-l-1); l += 1; - strncpy(envname+l, varname, XIO_ENVNAMELEN-1-l); - l += strlen(varname); - strncpy(envname+l, "_", XIO_ENVNAMELEN-1-l); + strncat(envname+l, varname, XIO_ENVNAMELEN-l-1); + l += strlen(varname+l); + strncat(envname+l, "_", XIO_ENVNAMELEN-l-1); l += 1; - strncpy(envname+l, varname2, XIO_ENVNAMELEN-1-l); - l += strlen(varname2); + strncat(envname+l, varname2, XIO_ENVNAMELEN-l-1); + l += strlen(varname+l); for (i = 0; i < l; ++i) envname[i] = toupper(envname[i]); if (Setenv(envname, value, overwrite) < 0) { Warn3("setenv(\"%s\", \"%s\", 1): %s", diff --git a/utils.c b/utils.c index 6f578e2..a08ba16 100644 --- a/utils.c +++ b/utils.c @@ -1,5 +1,5 @@ /* source: utils.c */ -/* Copyright Gerhard Rieger 2001-2009 */ +/* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ /* useful additions to C library */ @@ -90,9 +90,9 @@ int setenv(const char *name, const char *value, int overwrite) { -/* sanitize an "untrusted" character. output buffer must provide at least 5 +/* sanitizes an "untrusted" character. output buffer must provide at least 4 characters space. - Does not append null. returns length out output (currently: max 4) */ + Does not append \0. returns length out output (currently: max 4) */ static size_t sanitize_char(char c, char *o, int style) { int hn; /* high nibble */ int ln; /* low nibble */ @@ -126,10 +126,12 @@ static size_t sanitize_char(char c, char *o, int style) { return n; } -/* sanitize "untrusted" text, replacing special control characters with the C - string version ("\x"), and replacing unprintable chars with ".". +/* sanitizes "untrusted" text, replacing special control characters with the C + string version (eg."\n"), and replacing unprintable chars with hex + representation ("\xAB"). text can grow to four times of input, so keep output buffer long enough! returns a pointer to the first untouched byte of the output buffer. + Output is not \0 terminated. */ char *sanitize_string(const char *data, /* input data */ size_t bytes, /* length of input data, >=0 */ diff --git a/xio-ip.c b/xio-ip.c index 8db8f6d..8a74d4e 100644 --- a/xio-ip.c +++ b/xio-ip.c @@ -1,5 +1,5 @@ /* source: xio-ip.c */ -/* Copyright Gerhard Rieger 2001-2012 */ +/* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains the source for IP related functions */ @@ -199,7 +199,7 @@ int xiogetaddrinfo(const char *node, const char *service, #endif return STAT_NORETRY; } - strncpy(numnode, node+1, nodelen-2); + strncpy(numnode, node+1, nodelen-2); /* ok */ numnode[nodelen-2] = '\0'; node = numnode; #if HAVE_GETADDRINFO @@ -445,7 +445,17 @@ int xiogetaddrinfo(const char *node, const char *service, #if defined(HAVE_STRUCT_CMSGHDR) && defined(CMSG_DATA) -/* these are valid for IPv4 and IPv6 */ +/* converts the ancillary message in *cmsg into a form useable for further + processing. knows the specifics of common message types. + these are valid for IPv4 and IPv6 + returns the number of resulting syntax elements in *num + returns a sequence of \0 terminated type strings in *typbuff + returns a sequence of \0 terminated name strings in *nambuff + returns a sequence of \0 terminated value strings in *valbuff + the respective len parameters specify the available space in the buffers + returns STAT_OK on success + returns STAT_WARNING if a buffer was too short and data truncated. + */ int xiolog_ancillary_ip(struct cmsghdr *cmsg, int *num, char *typbuff, int typlen, char *nambuff, int namlen, @@ -458,13 +468,14 @@ int xiolog_ancillary_ip(struct cmsghdr *cmsg, int *num, char scratch2[16]; char scratch3[16]; #endif + int rc = 0; msglen = cmsg->cmsg_len-((char *)CMSG_DATA(cmsg)-(char *)cmsg); envbuff[0] = '\0'; switch (cmsg->cmsg_type) { default: *num = 1; - strncpy(typbuff, "IP", typlen); + typbuff[0] = '\0'; strncat(typbuff, "IP", typlen-1); snprintf(nambuff, namlen, "type_%u", cmsg->cmsg_type); xiodump(CMSG_DATA(cmsg), msglen, valbuff, vallen, 0); return STAT_OK; @@ -473,7 +484,7 @@ int xiolog_ancillary_ip(struct cmsghdr *cmsg, int *num, case IP_PKTINFO: { struct in_pktinfo *pktinfo = (struct in_pktinfo *)CMSG_DATA(cmsg); *num = 3; - strncpy(typbuff, "IP_PKTINFO", typlen); + typbuff[0] = '\0'; strncat(typbuff, "IP_PKTINFO", typlen-1); snprintf(nambuff, namlen, "%s%c%s%c%s", "if", '\0', "locaddr", '\0', "dstaddr"); snprintf(envbuff, envlen, "%s%c%s%c%s", "IP_IF", '\0', "IP_LOCADDR", '\0', "IP_DSTADDR"); @@ -497,7 +508,7 @@ int xiolog_ancillary_ip(struct cmsghdr *cmsg, int *num, struct sock_extended_err *err = (struct sock_extended_err *)CMSG_DATA(cmsg); *num = 6; - strncpy(typbuff, "IP_RECVERR", typlen); + typbuff[0] = '\0'; strncat(typbuff, "IP_RECVERR", typlen-1); snprintf(nambuff, namlen, "%s%c%s%c%s%c%s%c%s%c%s", "errno", '\0', "origin", '\0', "type", '\0', "code", '\0', "info", '\0', "data"); @@ -516,11 +527,12 @@ int xiolog_ancillary_ip(struct cmsghdr *cmsg, int *num, /* spec in FreeBSD: /usr/include/net/if_dl.h */ struct sockaddr_dl *sadl = (struct sockaddr_dl *)CMSG_DATA(cmsg); *num = 1; - strncpy(typbuff, "IP_RECVIF", typlen); - strncpy(nambuff, "if", namlen); - strncpy(envbuff, "IP_IF", envlen); - strncpy(valbuff, - xiosubstr(scratch1, sadl->sdl_data, 0, sadl->sdl_nlen), vallen); + typbuff[0] = '\0'; strncat(typbuff, "IP_RECVIF", typlen-1); + nambuff[0] = '\0'; strncat(nambuff, "if", namlen-1); + envbuff[0] = '\0'; strncat(envbuff, "IP_IF", envlen-1); + valbuff[0] = '\0'; + strncat(valbuff, + xiosubstr(scratch1, sadl->sdl_data, 0, sadl->sdl_nlen), vallen-1); return STAT_OK; } #endif /* defined(IP_RECVIF) */ @@ -528,9 +540,9 @@ int xiolog_ancillary_ip(struct cmsghdr *cmsg, int *num, #ifdef IP_RECVDSTADDR case IP_RECVDSTADDR: *num = 1; - strncpy(typbuff, "IP_RECVDSTADDR", typlen); - strncpy(nambuff, "dstaddr", namlen); - strncpy(envbuff, "IP_DSTADDR", envlen); + typbuff[0] = '\0'; strncat(typbuff, "IP_RECVDSTADDR", typlen-1); + nambuff[0] = '\0'; strncat(nambuff, "dstaddr", namlen-1); + envbuff[0] = '\0'; strncat(envbuff, "IP_DSTADDR", envlen-1); inet4addr_info(ntohl(*(uint32_t *)CMSG_DATA(cmsg)), valbuff, vallen); return STAT_OK; #endif @@ -551,13 +563,13 @@ int xiolog_ancillary_ip(struct cmsghdr *cmsg, int *num, /* when we come here we provide a single parameter with type in cmsgtype, name in cmsgname, printf format in cmsgfmt */ *num = 1; - if (strlen(cmsgtype) >= typlen) Fatal("buff too short"); - strncpy(typbuff, cmsgtype, typlen); - if (strlen(cmsgname) >= namlen) Fatal("buff too short"); - strncpy(nambuff, cmsgname, namlen); + if (strlen(cmsgtype) >= typlen) rc = STAT_WARNING; + typbuff[0] = '\0'; strncat(typbuff, cmsgtype, typlen-1); + if (strlen(cmsgname) >= namlen) rc = STAT_WARNING; + nambuff[0] = '\0'; strncat(nambuff, cmsgname, namlen-1); if (cmsgenvn) { - if (strlen(cmsgenvn) >= envlen) Fatal("buff too short"); - strncpy(envbuff, cmsgenvn, envlen); + if (strlen(cmsgenvn) >= envlen) rc = STAT_WARNING; + envbuff[0] = '\0'; strncat(envbuff, cmsgenvn, envlen-1); } else { envbuff[0] = '\0'; } @@ -566,7 +578,7 @@ int xiolog_ancillary_ip(struct cmsghdr *cmsg, int *num, } else { xiodump(CMSG_DATA(cmsg), msglen, valbuff, vallen, 0); } - return STAT_OK; + return rc; } #endif /* defined(HAVE_STRUCT_CMSGHDR) && defined(CMSG_DATA) */ diff --git a/xio-ip6.c b/xio-ip6.c index 36c5ac5..2644c00 100644 --- a/xio-ip6.c +++ b/xio-ip6.c @@ -199,7 +199,16 @@ int xiocheckrange_ip6(struct sockaddr_in6 *pa, struct xiorange *range) { #if defined(HAVE_STRUCT_CMSGHDR) && defined(CMSG_DATA) -/* provides info about the ancillary message */ +/* provides info about the ancillary message: + converts the ancillary message in *cmsg into a form useable for further + processing. knows the specifics of common message types. + returns the number of resulting syntax elements in *num + returns a sequence of \0 terminated type strings in *typbuff + returns a sequence of \0 terminated name strings in *nambuff + returns a sequence of \0 terminated value strings in *valbuff + the respective len parameters specify the available space in the buffers + returns STAT_OK on success + */ int xiolog_ancillary_ip6(struct cmsghdr *cmsg, int *num, char *typbuff, int typlen, char *nambuff, int namlen, @@ -217,7 +226,7 @@ int xiolog_ancillary_ip6(struct cmsghdr *cmsg, int *num, case IPV6_PKTINFO: { struct in6_pktinfo *pktinfo = (struct in6_pktinfo *)CMSG_DATA(cmsg); *num = 2; - strncpy(typbuff, "IPV6_PKTINFO", typlen); + typbuff[0] = '\0'; strncat(typbuff, "IPV6_PKTINFO", typlen-1); snprintf(nambuff, namlen, "%s%c%s", "dstaddr", '\0', "if"); snprintf(envbuff, envlen, "%s%c%s", "IPV6_DSTADDR", '\0', "IPV6_IF"); snprintf(valbuff, vallen, "%s%c%s", @@ -228,8 +237,8 @@ int xiolog_ancillary_ip6(struct cmsghdr *cmsg, int *num, #endif /* defined(IPV6_PKTINFO) */ #ifdef IPV6_HOPLIMIT case IPV6_HOPLIMIT: - strncpy(typbuff, "IPV6_HOPLIMIT", typlen); - strncpy(nambuff, "hoplimit", namlen); + typbuff[0] = '\0'; strncat(typbuff, "IPV6_HOPLIMIT", typlen-1); + nambuff[0] = '\0'; strncat(nambuff, "hoplimit", namlen-1); { int *intp = (int *)CMSG_DATA(cmsg); snprintf(valbuff, vallen, "%d", *intp); @@ -238,49 +247,49 @@ int xiolog_ancillary_ip6(struct cmsghdr *cmsg, int *num, #endif /* defined(IPV6_HOPLIMIT) */ #ifdef IPV6_RTHDR case IPV6_RTHDR: - strncpy(typbuff, "IPV6_RTHDR", typlen); - strncpy(nambuff, "rthdr", namlen); + typbuff[0] = '\0'; strncat(typbuff, "IPV6_RTHDR", typlen-1); + nambuff[0] = '\0'; strncat(nambuff, "rthdr", namlen-1); xiodump(CMSG_DATA(cmsg), msglen, valbuff, vallen, 0); return STAT_OK; #endif /* defined(IPV6_RTHDR) */ #ifdef IPV6_AUTHHDR case IPV6_AUTHHDR: - strncpy(typbuff, "IPV6_AUTHHDR", typlen); - strncpy(nambuff, "authhdr", namlen); + typbuff[0] = '\0'; strncat(typbuff, "IPV6_AUTHHDR", typlen-1); + nambuff[0] = '\0'; strncat(nambuff, "authhdr", namlen-1); xiodump(CMSG_DATA(cmsg), msglen, valbuff, vallen, 0); return STAT_OK; #endif #ifdef IPV6_DSTOPTS case IPV6_DSTOPTS: - strncpy(typbuff, "IPV6_DSTOPTS", typlen); - strncpy(nambuff, "dstopts", namlen); + typbuff[0] = '\0'; strncat(typbuff, "IPV6_DSTOPTS", typlen-1); + nambuff[0] = '\0'; strncat(nambuff, "dstopts", namlen-1); xiodump(CMSG_DATA(cmsg), msglen, valbuff, vallen, 0); return STAT_OK; #endif /* defined(IPV6_DSTOPTS) */ #ifdef IPV6_HOPOPTS case IPV6_HOPOPTS: - strncpy(typbuff, "IPV6_HOPOPTS", typlen); - strncpy(nambuff, "hopopts", namlen); + typbuff[0] = '\0'; strncat(typbuff, "IPV6_HOPOPTS", typlen-1); + nambuff[0] = '\0'; strncat(nambuff, "hopopts", namlen-1); xiodump(CMSG_DATA(cmsg), msglen, valbuff, vallen, 0); return STAT_OK; #endif /* defined(IPV6_HOPOPTS) */ #ifdef IPV6_FLOWINFO case IPV6_FLOWINFO: - strncpy(typbuff, "IPV6_FLOWINFO", typlen); - strncpy(nambuff, "flowinfo", namlen); + typbuff[0] = '\0'; strncat(typbuff, "IPV6_FLOWINFO", typlen-1); + nambuff[0] = '\0'; strncat(nambuff, "flowinfo", namlen-1); xiodump(CMSG_DATA(cmsg), msglen, valbuff, vallen, 0); return STAT_OK; #endif #ifdef IPV6_TCLASS case IPV6_TCLASS: - strncpy(typbuff, "IPV6_TCLASS", typlen); - strncpy(nambuff, "tclass", namlen); + typbuff[0] = '\0'; strncat(typbuff, "IPV6_TCLASS", typlen-1); + nambuff[0] = '\0'; strncat(nambuff, "tclass", namlen-1); xiodump(CMSG_DATA(cmsg), msglen, valbuff, vallen, 0); return STAT_OK; #endif default: snprintf(typbuff, typlen, "IPV6.%u", cmsg->cmsg_type); - strncpy(nambuff, "data", namlen); + nambuff[0] = '\0'; strncat(nambuff, "data", namlen-1); xiodump(CMSG_DATA(cmsg), msglen, valbuff, vallen, 0); return STAT_OK; } diff --git a/xio-progcall.c b/xio-progcall.c index 11cfb51..e5627d4 100644 --- a/xio-progcall.c +++ b/xio-progcall.c @@ -1,5 +1,5 @@ /* source: xio-progcall.c */ -/* Copyright Gerhard Rieger 2001-2012 */ +/* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains common code dealing with program calls (exec, system) */ @@ -148,7 +148,7 @@ int _xioopen_progcall(int xioflags, /* XIO_RDONLY etc. */ #endif ); if (usepipes && usepty) { - Warn("_xioopen_foxec(): options \"pipes\" and \"pty\" must not be specified together; ignoring \"pipes\""); + Warn("_xioopen_progcall(): options \"pipes\" and \"pty\" must not be specified together; ignoring \"pipes\""); usepipes = false; } #endif /* HAVE_PTY */ diff --git a/xio-pty.c b/xio-pty.c index 27c8de4..dce78e2 100644 --- a/xio-pty.c +++ b/xio-pty.c @@ -1,5 +1,5 @@ /* source: xio-pty.c */ -/* Copyright Gerhard Rieger 2002-2012 */ +/* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains the source for creating pty addresses */ @@ -145,7 +145,7 @@ static int xioopen_pty(const char *linkname, struct opt *opts, int xioflags, xio Warn2("ttyname(%d): %s", ptyfd, strerror(errno)); } } - strncpy(ptyname, tn, MAXPTYNAMELEN); + ptyname[0] = '\0'; strncat(ptyname, tn, MAXPTYNAMELEN-1); } } #endif /* HAVE_DEV_PTMX || HAVE_DEV_PTC */ diff --git a/xio-readline.c b/xio-readline.c index 29351c1..9fa7a93 100644 --- a/xio-readline.c +++ b/xio-readline.c @@ -1,5 +1,5 @@ /* source: xio-readline.c */ -/* Copyright Gerhard Rieger 2002-2012 */ +/* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains the source for opening the readline address */ @@ -210,7 +210,7 @@ ssize_t xioread_readline(struct single *pipe, void *buff, size_t bufsiz) { #endif /* _WITH_TERMIOS */ Add_history(line); bytes = strlen(line); - strncpy(buff, line, bufsiz); + ((char *)buff)[0] = '\0'; strncat(buff, line, bufsiz-1); free(line); if ((size_t)bytes < bufsiz) { strcat(buff, "\n"); ++bytes; diff --git a/xio-socket.c b/xio-socket.c index 4b7d8a4..527cecc 100644 --- a/xio-socket.c +++ b/xio-socket.c @@ -1871,7 +1871,7 @@ int xiocheckpeer(xiosingle_t *xfd, #if HAVE_STRUCT_CMSGHDR /* converts the ancillary message in *cmsg into a form useable for further processing. knows the specifics of common message types. - returns the number of resulting syntax elements is *num + returns the number of resulting syntax elements in *num returns a sequence of \0 terminated type strings in *typbuff returns a sequence of \0 terminated name strings in *nambuff returns a sequence of \0 terminated value strings in *valbuff @@ -1887,6 +1887,7 @@ xiolog_ancillary_socket(struct cmsghdr *cmsg, int *num, const char *cmsgtype, *cmsgname, *cmsgenvn; size_t msglen; struct timeval *tv; + int rc = STAT_OK; #if defined(CMSG_DATA) @@ -1902,7 +1903,7 @@ xiolog_ancillary_socket(struct cmsghdr *cmsg, int *num, #endif default: /* binary data */ snprintf(typbuff, typlen, "SOCKET.%u", cmsg->cmsg_type); - strncpy(nambuff, "data", namlen); + nambuff[0] = '\0'; strncat(nambuff, "data", namlen-1); xiodump(CMSG_DATA(cmsg), msglen, valbuff, vallen, 0); return STAT_OK; #ifdef SO_TIMESTAMP @@ -1931,14 +1932,13 @@ xiolog_ancillary_socket(struct cmsghdr *cmsg, int *num, with type in cmsgtype, name in cmsgname, and value already in valbuff */ *num = 1; - if (strlen(cmsgtype) >= typlen) Fatal("buff too short"); - strncpy(typbuff, cmsgtype, typlen); - if (strlen(cmsgname) >= namlen) Fatal("buff too short"); - strncpy(nambuff, cmsgname, namlen); - if (strlen(cmsgenvn) >= envlen) Fatal("buff too short"); - strncpy(envbuff, cmsgenvn, envlen); - return STAT_OK; - + if (strlen(cmsgtype) >= typlen) rc = STAT_WARNING; + typbuff[0] = '\0'; strncat(typbuff, cmsgtype, typlen-1); + if (strlen(cmsgname) >= namlen) rc = STAT_WARNING; + nambuff[0] = '\0'; strncat(nambuff, cmsgname, namlen-1); + if (strlen(cmsgenvn) >= envlen) rc = STAT_WARNING; + envbuff[0] = '\0'; strncat(envbuff, cmsgenvn, envlen-1); + return rc; #else /* !defined(CMSG_DATA) */ return STAT_NORETRY; @@ -2022,7 +2022,7 @@ int xioparsenetwork(const char *rangename, int pf, struct xiorange *range) { if ((addrname = Malloc(maskname-rangename)) == NULL) { return STAT_NORETRY; } - strncpy(addrname, rangename, maskname-rangename-1); + strncpy(addrname, rangename, maskname-rangename-1); /* ok */ addrname[maskname-rangename-1] = '\0'; result = dalan(addrname, (char *)&range->netaddr.soa.sa_data, &addrlen, diff --git a/xio-socks.c b/xio-socks.c index eb22c66..e1fe20f 100644 --- a/xio-socks.c +++ b/xio-socks.c @@ -1,5 +1,5 @@ /* source: xio-socks.c */ -/* Copyright Gerhard Rieger 2001-2012 */ +/* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains the source for opening addresses of socks4 type */ @@ -282,7 +282,7 @@ int _xioopen_socks4_prepare(const char *targetport, struct opt *opts, char **soc } } } - strncpy(sockhead->userid, userid, *headlen-SIZEOF_STRUCT_SOCKS4); + sockhead->userid[0] = '\0'; strncat(sockhead->userid, userid, *headlen-SIZEOF_STRUCT_SOCKS4-1); *headlen = SIZEOF_STRUCT_SOCKS4+strlen(userid)+1; return STAT_OK; } @@ -325,7 +325,7 @@ int after the user name's trailing 0 byte. */ char* insert_position = (char*) sockhead + *headlen; - strncpy(insert_position, hostname, BUFF_LEN-*headlen); + insert_position[0] = '\0'; strncat(insert_position, hostname, BUFF_LEN-*headlen-1); ((char *)sockhead)[BUFF_LEN-1] = 0; *headlen += strlen(hostname) + 1; if (*headlen > BUFF_LEN) { diff --git a/xio-socks5.c b/xio-socks5.c index 7c08862..3c234d5 100644 --- a/xio-socks5.c +++ b/xio-socks5.c @@ -1,5 +1,5 @@ /* source: xio-socks5.c */ -/* Copyright Gerhard Rieger 2004-2009 */ +/* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains the source for opening addresses of socks5 type */ @@ -296,7 +296,7 @@ int _xioopen_socks5_connect(struct single *xfd, targetname); } sendrequest->destaddr[0] = strlen(targetname); - strncpy(sendrequest->destaddr+1, targetname, sizeof(sendbuff)-5); + *(sendrequest->destaddr+1) = '\0'; strncat(sendrequest->destaddr+1, targetname, sizeof(sendbuff)-5); break; case SOCKS5_ADDRTYPE_IPV6: break; @@ -431,10 +431,10 @@ int xio_socks5_username_password(int level, struct opt *opts, pos = sendbuff; *pos++ = SOCKS5_USERPASS_VERSION; *pos++ = strlen(username); - strncpy(pos, username, 255); + *pos = '\0'; strncat(pos, username, 255); pos += strlen(username); *pos++ = strlen(password); - strncpy(pos, password, 255); + *pos = '\0'; strncat(pos, password, 255); pos += strlen(password); result = diff --git a/xio-tun.c b/xio-tun.c index 0fd92ac..0628d27 100644 --- a/xio-tun.c +++ b/xio-tun.c @@ -1,5 +1,5 @@ /* source: xio-tun.c */ -/* Copyright Gerhard Rieger 2007-2012 */ +/* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains the source for opening addresses of tun/tap type */ @@ -112,7 +112,7 @@ static int xioopen_tun(int argc, const char *argv[], struct opt *opts, int xiofl memset(&ifr, 0,sizeof(ifr)); if (retropt_string(opts, OPT_TUN_NAME, &tunname) == 0) { - strncpy(ifr.ifr_name, tunname, IFNAMSIZ); + strncpy(ifr.ifr_name, tunname, IFNAMSIZ); /* ok */ free(tunname); } else { ifr.ifr_name[0] = '\0'; diff --git a/xio-unix.c b/xio-unix.c index 2026dd7..7a35ca6 100644 --- a/xio-unix.c +++ b/xio-unix.c @@ -1,5 +1,5 @@ /* source: xio-unix.c */ -/* Copyright Gerhard Rieger 2001-2012 */ +/* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains the source for opening addresses of UNIX socket type */ @@ -99,7 +99,7 @@ xiosetunix(int pf, pathlen+1, sizeof(saun->sun_path)); } saun->sun_path[0] = '\0'; /* so it's abstract */ - strncpy(saun->sun_path+1, path, sizeof(saun->sun_path)-1); + strncpy(saun->sun_path+1, path, sizeof(saun->sun_path)-1); /* ok */ if (tight) { len = sizeof(struct sockaddr_un)-sizeof(saun->sun_path)+ MIN(pathlen+1, sizeof(saun->sun_path)); @@ -117,7 +117,7 @@ xiosetunix(int pf, Warn2("unix socket address "F_Zu" characters long, truncating to "F_Zu"", pathlen, sizeof(saun->sun_path)); } - strncpy(saun->sun_path, path, sizeof(saun->sun_path)); + strncpy(saun->sun_path, path, sizeof(saun->sun_path)); /* ok */ if (tight) { len = sizeof(struct sockaddr_un)-sizeof(saun->sun_path)+ MIN(pathlen, sizeof(saun->sun_path)); diff --git a/xioopen.c b/xioopen.c index 3308194..1c341cc 100644 --- a/xioopen.c +++ b/xioopen.c @@ -1,5 +1,5 @@ /* source: xioopen.c */ -/* Copyright Gerhard Rieger 2001-2009 */ +/* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this is the source file of the extended open function */ @@ -1071,8 +1071,7 @@ static xiosingle_t * sfd->argc = 0; /* for error messages */ - strncpy(addr0, *addr, sizeof(addr0)-1); - addr0[sizeof(addr0)-1] = '\0'; + addr0[0] = '\0'; strncat(addr0, *addr, sizeof(addr0)-1); len = sizeof(token); tokp = token; if (nestlex(addr, &tokp, &len, ends, hquotes, squotes, nests, diff --git a/xioopts.c b/xioopts.c index b05f3ab..8df97a6 100644 --- a/xioopts.c +++ b/xioopts.c @@ -2325,7 +2325,7 @@ int parseopts_table(const char **a, struct opt **opts, #if HAVE_STRUCT_IP_MREQN if (*tokp++ == ':') { - strncpy((*opts)[i].value.u_ip_mreq.ifindex, tokp, IF_NAMESIZE); + strncpy((*opts)[i].value.u_ip_mreq.ifindex, tokp, IF_NAMESIZE); /* ok */ Info4("setting option \"%s\" to {\"%s\",\"%s\",\"%s\"}", ent->desc->defname, (*opts)[i].value.u_ip_mreq.multiaddr, diff --git a/xioparam.c b/xioparam.c index 5218bd6..2ab8e77 100644 --- a/xioparam.c +++ b/xioparam.c @@ -1,5 +1,5 @@ /* source: xioparam.c */ -/* Copyright Gerhard Rieger 2001-2007 */ +/* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains the source for xio options handling */ @@ -67,7 +67,8 @@ int xiosetopt(char what, const char *arg) { int xioinqopt(char what, char *arg, size_t n) { switch (what) { case 's': return xioopts.strictopts; - case 'p': strncpy(arg, xioopts.pipesep, n); + case 'p': + arg[0] = '\0'; strncat(arg, xioopts.pipesep, n-1); return 0; case 'o': return xioopts.ip4portsep; case 'l': return xioopts.logopt; diff --git a/xiosocketpair.c b/xiosocketpair.c index ef74235..53be147 100644 --- a/xiosocketpair.c +++ b/xiosocketpair.c @@ -1,5 +1,5 @@ -/* $Id$ */ -/* Copyright Gerhard Rieger 2007-2009 */ +/* xiosocketpair.c */ +/* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this is the source of the internal xiosocketpair function */ @@ -61,7 +61,7 @@ int xiopty(int useptmx, int *ttyfdp, int *ptyfdp) { Warn2("ttyname(%d): %s", ptyfd, strerror(errno)); } } - strncpy(ptyname, tn, MAXPTYNAMELEN); + ptyname[0] = '\0'; strncat(ptyname, tn, MAXPTYNAMELEN-1); #endif if ((ttyfd = Open(tn, O_RDWR|O_NOCTTY, 0620)) < 0) { Warn2("open(\"%s\", O_RDWR|O_NOCTTY, 0620): %s", tn, strerror(errno));