Red Hat issue 1022048: strncpy hardening

This commit is contained in:
Gerhard Rieger 2014-03-26 12:48:27 +01:00
parent f81931a799
commit 7467d9b40f
17 changed files with 124 additions and 96 deletions

View file

@ -26,6 +26,9 @@ corrections:
On big endian platforms with type long >32bit the range option applied a 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. 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 Red Hat issue 1021958: fixed a bug with faulty buffer/data length
calculation in xio-ascii.c:_xiodump() calculation in xio-ascii.c:_xiodump()

View file

@ -163,6 +163,9 @@ socklen_t socket_init(int af, union sockaddr_union *sa) {
#endif #endif
#if _WITH_SOCKET #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) { char *sockaddr_info(const struct sockaddr *sa, socklen_t salen, char *buff, size_t blen) {
union sockaddr_union *sau = (union sockaddr_union *)sa; union sockaddr_union *sau = (union sockaddr_union *)sa;
char *lbuff = buff; char *lbuff = buff;
@ -244,8 +247,6 @@ char *sockaddr_unix_info(const struct sockaddr_un *sa, socklen_t salen, char *bu
nextc = nextc =
sanitize_string(sa->sun_path, salen-XIOUNIXSOCKOVERHEAD, sanitize_string(sa->sun_path, salen-XIOUNIXSOCKOVERHEAD,
ubuff, XIOSAN_DEFAULT_BACKSLASH_OCT_3); ubuff, XIOSAN_DEFAULT_BACKSLASH_OCT_3);
*nextc = '\0';
strncpy(buff, ubuff, blen);
} else } else
#endif /* WITH_ABSTRACT_UNIXSOCKET */ #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)), MIN(UNIX_PATH_MAX, strlen(sa->sun_path)),
ubuff, XIOSAN_DEFAULT_BACKSLASH_OCT_3); ubuff, XIOSAN_DEFAULT_BACKSLASH_OCT_3);
} }
*nextc = '\0';
strncpy(buff, ubuff, blen);
} }
*nextc = '\0';
buff[0] = '\0'; strncat(buff, ubuff, blen-1);
return buff; return buff;
} }
#endif /* WITH_UNIX */ #endif /* WITH_UNIX */
@ -575,7 +576,7 @@ int ifindexbyname(const char *ifname, int anysock) {
return -1; return -1;
} }
strncpy(ifr.ifr_name, ifname, IFNAMSIZ); strncpy(ifr.ifr_name, ifname, IFNAMSIZ); /* ok */
if (Ioctl(s, SIOCGIFINDEX, &ifr) < 0) { if (Ioctl(s, SIOCGIFINDEX, &ifr) < 0) {
Info3("ioctl(%d, SIOCGIFINDEX, {\"%s\"}): %s", Info3("ioctl(%d, SIOCGIFINDEX, {\"%s\"}): %s",
s, ifr.ifr_name, strerror(errno)); s, ifr.ifr_name, strerror(errno));
@ -638,11 +639,12 @@ int xiosetenv(const char *varname, const char *value, int overwrite) {
size_t i, l; size_t i, l;
progname = diag_get_string('p'); progname = diag_get_string('p');
strncpy(envname, progname, XIO_ENVNAMELEN-1); envname[0] = '\0'; strncat(envname, progname, XIO_ENVNAMELEN-1);
l = strlen(progname); l = strlen(progname);
strncpy(envname+l, "_", XIO_ENVNAMELEN-1-l);
for (i = 0; i < l; ++i) envname[i] = toupper(envname[i]); 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) { if (Setenv(envname, value, overwrite) < 0) {
Warn3("setenv(\"%s\", \"%s\", 1): %s", Warn3("setenv(\"%s\", \"%s\", 1): %s",
envname, value, strerror(errno)); envname, value, strerror(errno));
@ -663,16 +665,16 @@ int xiosetenv2(const char *varname, const char *varname2, const char *value,
size_t i, l; size_t i, l;
progname = diag_get_string('p'); progname = diag_get_string('p');
strncpy(envname, progname, XIO_ENVNAMELEN-1); envname[0] = '\0'; strncat(envname, progname, XIO_ENVNAMELEN-1);
l = strlen(progname); l = strlen(progname);
strncpy(envname+l, "_", XIO_ENVNAMELEN-1-l); strncat(envname+l, "_", XIO_ENVNAMELEN-l-1);
l += 1; l += 1;
strncpy(envname+l, varname, XIO_ENVNAMELEN-1-l); strncat(envname+l, varname, XIO_ENVNAMELEN-l-1);
l += strlen(varname); l += strlen(varname+l);
strncpy(envname+l, "_", XIO_ENVNAMELEN-1-l); strncat(envname+l, "_", XIO_ENVNAMELEN-l-1);
l += 1; l += 1;
strncpy(envname+l, varname2, XIO_ENVNAMELEN-1-l); strncat(envname+l, varname2, XIO_ENVNAMELEN-l-1);
l += strlen(varname2); l += strlen(varname+l);
for (i = 0; i < l; ++i) envname[i] = toupper(envname[i]); for (i = 0; i < l; ++i) envname[i] = toupper(envname[i]);
if (Setenv(envname, value, overwrite) < 0) { if (Setenv(envname, value, overwrite) < 0) {
Warn3("setenv(\"%s\", \"%s\", 1): %s", Warn3("setenv(\"%s\", \"%s\", 1): %s",

12
utils.c
View file

@ -1,5 +1,5 @@
/* source: utils.c */ /* source: utils.c */
/* Copyright Gerhard Rieger 2001-2009 */ /* Copyright Gerhard Rieger */
/* Published under the GNU General Public License V.2, see file COPYING */ /* Published under the GNU General Public License V.2, see file COPYING */
/* useful additions to C library */ /* 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. 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) { static size_t sanitize_char(char c, char *o, int style) {
int hn; /* high nibble */ int hn; /* high nibble */
int ln; /* low nibble */ int ln; /* low nibble */
@ -126,10 +126,12 @@ static size_t sanitize_char(char c, char *o, int style) {
return n; return n;
} }
/* sanitize "untrusted" text, replacing special control characters with the C /* sanitizes "untrusted" text, replacing special control characters with the C
string version ("\x"), and replacing unprintable chars with ".". 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! 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. 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 */ char *sanitize_string(const char *data, /* input data */
size_t bytes, /* length of input data, >=0 */ size_t bytes, /* length of input data, >=0 */

View file

@ -1,5 +1,5 @@
/* source: xio-ip.c */ /* source: xio-ip.c */
/* Copyright Gerhard Rieger 2001-2012 */ /* Copyright Gerhard Rieger */
/* Published under the GNU General Public License V.2, see file COPYING */ /* Published under the GNU General Public License V.2, see file COPYING */
/* this file contains the source for IP related functions */ /* this file contains the source for IP related functions */
@ -199,7 +199,7 @@ int xiogetaddrinfo(const char *node, const char *service,
#endif #endif
return STAT_NORETRY; return STAT_NORETRY;
} }
strncpy(numnode, node+1, nodelen-2); strncpy(numnode, node+1, nodelen-2); /* ok */
numnode[nodelen-2] = '\0'; numnode[nodelen-2] = '\0';
node = numnode; node = numnode;
#if HAVE_GETADDRINFO #if HAVE_GETADDRINFO
@ -445,7 +445,17 @@ int xiogetaddrinfo(const char *node, const char *service,
#if defined(HAVE_STRUCT_CMSGHDR) && defined(CMSG_DATA) #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, int xiolog_ancillary_ip(struct cmsghdr *cmsg, int *num,
char *typbuff, int typlen, char *typbuff, int typlen,
char *nambuff, int namlen, char *nambuff, int namlen,
@ -458,13 +468,14 @@ int xiolog_ancillary_ip(struct cmsghdr *cmsg, int *num,
char scratch2[16]; char scratch2[16];
char scratch3[16]; char scratch3[16];
#endif #endif
int rc = 0;
msglen = cmsg->cmsg_len-((char *)CMSG_DATA(cmsg)-(char *)cmsg); msglen = cmsg->cmsg_len-((char *)CMSG_DATA(cmsg)-(char *)cmsg);
envbuff[0] = '\0'; envbuff[0] = '\0';
switch (cmsg->cmsg_type) { switch (cmsg->cmsg_type) {
default: default:
*num = 1; *num = 1;
strncpy(typbuff, "IP", typlen); typbuff[0] = '\0'; strncat(typbuff, "IP", typlen-1);
snprintf(nambuff, namlen, "type_%u", cmsg->cmsg_type); snprintf(nambuff, namlen, "type_%u", cmsg->cmsg_type);
xiodump(CMSG_DATA(cmsg), msglen, valbuff, vallen, 0); xiodump(CMSG_DATA(cmsg), msglen, valbuff, vallen, 0);
return STAT_OK; return STAT_OK;
@ -473,7 +484,7 @@ int xiolog_ancillary_ip(struct cmsghdr *cmsg, int *num,
case IP_PKTINFO: { case IP_PKTINFO: {
struct in_pktinfo *pktinfo = (struct in_pktinfo *)CMSG_DATA(cmsg); struct in_pktinfo *pktinfo = (struct in_pktinfo *)CMSG_DATA(cmsg);
*num = 3; *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(nambuff, namlen, "%s%c%s%c%s", "if", '\0', "locaddr", '\0', "dstaddr");
snprintf(envbuff, envlen, "%s%c%s%c%s", "IP_IF", '\0', snprintf(envbuff, envlen, "%s%c%s%c%s", "IP_IF", '\0',
"IP_LOCADDR", '\0', "IP_DSTADDR"); "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 *err =
(struct sock_extended_err *)CMSG_DATA(cmsg); (struct sock_extended_err *)CMSG_DATA(cmsg);
*num = 6; *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", snprintf(nambuff, namlen, "%s%c%s%c%s%c%s%c%s%c%s",
"errno", '\0', "origin", '\0', "type", '\0', "errno", '\0', "origin", '\0', "type", '\0',
"code", '\0', "info", '\0', "data"); "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 */ /* spec in FreeBSD: /usr/include/net/if_dl.h */
struct sockaddr_dl *sadl = (struct sockaddr_dl *)CMSG_DATA(cmsg); struct sockaddr_dl *sadl = (struct sockaddr_dl *)CMSG_DATA(cmsg);
*num = 1; *num = 1;
strncpy(typbuff, "IP_RECVIF", typlen); typbuff[0] = '\0'; strncat(typbuff, "IP_RECVIF", typlen-1);
strncpy(nambuff, "if", namlen); nambuff[0] = '\0'; strncat(nambuff, "if", namlen-1);
strncpy(envbuff, "IP_IF", envlen); envbuff[0] = '\0'; strncat(envbuff, "IP_IF", envlen-1);
strncpy(valbuff, valbuff[0] = '\0';
xiosubstr(scratch1, sadl->sdl_data, 0, sadl->sdl_nlen), vallen); strncat(valbuff,
xiosubstr(scratch1, sadl->sdl_data, 0, sadl->sdl_nlen), vallen-1);
return STAT_OK; return STAT_OK;
} }
#endif /* defined(IP_RECVIF) */ #endif /* defined(IP_RECVIF) */
@ -528,9 +540,9 @@ int xiolog_ancillary_ip(struct cmsghdr *cmsg, int *num,
#ifdef IP_RECVDSTADDR #ifdef IP_RECVDSTADDR
case IP_RECVDSTADDR: case IP_RECVDSTADDR:
*num = 1; *num = 1;
strncpy(typbuff, "IP_RECVDSTADDR", typlen); typbuff[0] = '\0'; strncat(typbuff, "IP_RECVDSTADDR", typlen-1);
strncpy(nambuff, "dstaddr", namlen); nambuff[0] = '\0'; strncat(nambuff, "dstaddr", namlen-1);
strncpy(envbuff, "IP_DSTADDR", envlen); envbuff[0] = '\0'; strncat(envbuff, "IP_DSTADDR", envlen-1);
inet4addr_info(ntohl(*(uint32_t *)CMSG_DATA(cmsg)), valbuff, vallen); inet4addr_info(ntohl(*(uint32_t *)CMSG_DATA(cmsg)), valbuff, vallen);
return STAT_OK; return STAT_OK;
#endif #endif
@ -551,13 +563,13 @@ int xiolog_ancillary_ip(struct cmsghdr *cmsg, int *num,
/* when we come here we provide a single parameter /* when we come here we provide a single parameter
with type in cmsgtype, name in cmsgname, printf format in cmsgfmt */ with type in cmsgtype, name in cmsgname, printf format in cmsgfmt */
*num = 1; *num = 1;
if (strlen(cmsgtype) >= typlen) Fatal("buff too short"); if (strlen(cmsgtype) >= typlen) rc = STAT_WARNING;
strncpy(typbuff, cmsgtype, typlen); typbuff[0] = '\0'; strncat(typbuff, cmsgtype, typlen-1);
if (strlen(cmsgname) >= namlen) Fatal("buff too short"); if (strlen(cmsgname) >= namlen) rc = STAT_WARNING;
strncpy(nambuff, cmsgname, namlen); nambuff[0] = '\0'; strncat(nambuff, cmsgname, namlen-1);
if (cmsgenvn) { if (cmsgenvn) {
if (strlen(cmsgenvn) >= envlen) Fatal("buff too short"); if (strlen(cmsgenvn) >= envlen) rc = STAT_WARNING;
strncpy(envbuff, cmsgenvn, envlen); envbuff[0] = '\0'; strncat(envbuff, cmsgenvn, envlen-1);
} else { } else {
envbuff[0] = '\0'; envbuff[0] = '\0';
} }
@ -566,7 +578,7 @@ int xiolog_ancillary_ip(struct cmsghdr *cmsg, int *num,
} else { } else {
xiodump(CMSG_DATA(cmsg), msglen, valbuff, vallen, 0); xiodump(CMSG_DATA(cmsg), msglen, valbuff, vallen, 0);
} }
return STAT_OK; return rc;
} }
#endif /* defined(HAVE_STRUCT_CMSGHDR) && defined(CMSG_DATA) */ #endif /* defined(HAVE_STRUCT_CMSGHDR) && defined(CMSG_DATA) */

View file

@ -199,7 +199,16 @@ int xiocheckrange_ip6(struct sockaddr_in6 *pa, struct xiorange *range) {
#if defined(HAVE_STRUCT_CMSGHDR) && defined(CMSG_DATA) #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, int xiolog_ancillary_ip6(struct cmsghdr *cmsg, int *num,
char *typbuff, int typlen, char *typbuff, int typlen,
char *nambuff, int namlen, char *nambuff, int namlen,
@ -217,7 +226,7 @@ int xiolog_ancillary_ip6(struct cmsghdr *cmsg, int *num,
case IPV6_PKTINFO: { case IPV6_PKTINFO: {
struct in6_pktinfo *pktinfo = (struct in6_pktinfo *)CMSG_DATA(cmsg); struct in6_pktinfo *pktinfo = (struct in6_pktinfo *)CMSG_DATA(cmsg);
*num = 2; *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(nambuff, namlen, "%s%c%s", "dstaddr", '\0', "if");
snprintf(envbuff, envlen, "%s%c%s", "IPV6_DSTADDR", '\0', "IPV6_IF"); snprintf(envbuff, envlen, "%s%c%s", "IPV6_DSTADDR", '\0', "IPV6_IF");
snprintf(valbuff, vallen, "%s%c%s", snprintf(valbuff, vallen, "%s%c%s",
@ -228,8 +237,8 @@ int xiolog_ancillary_ip6(struct cmsghdr *cmsg, int *num,
#endif /* defined(IPV6_PKTINFO) */ #endif /* defined(IPV6_PKTINFO) */
#ifdef IPV6_HOPLIMIT #ifdef IPV6_HOPLIMIT
case IPV6_HOPLIMIT: case IPV6_HOPLIMIT:
strncpy(typbuff, "IPV6_HOPLIMIT", typlen); typbuff[0] = '\0'; strncat(typbuff, "IPV6_HOPLIMIT", typlen-1);
strncpy(nambuff, "hoplimit", namlen); nambuff[0] = '\0'; strncat(nambuff, "hoplimit", namlen-1);
{ {
int *intp = (int *)CMSG_DATA(cmsg); int *intp = (int *)CMSG_DATA(cmsg);
snprintf(valbuff, vallen, "%d", *intp); snprintf(valbuff, vallen, "%d", *intp);
@ -238,49 +247,49 @@ int xiolog_ancillary_ip6(struct cmsghdr *cmsg, int *num,
#endif /* defined(IPV6_HOPLIMIT) */ #endif /* defined(IPV6_HOPLIMIT) */
#ifdef IPV6_RTHDR #ifdef IPV6_RTHDR
case IPV6_RTHDR: case IPV6_RTHDR:
strncpy(typbuff, "IPV6_RTHDR", typlen); typbuff[0] = '\0'; strncat(typbuff, "IPV6_RTHDR", typlen-1);
strncpy(nambuff, "rthdr", namlen); nambuff[0] = '\0'; strncat(nambuff, "rthdr", namlen-1);
xiodump(CMSG_DATA(cmsg), msglen, valbuff, vallen, 0); xiodump(CMSG_DATA(cmsg), msglen, valbuff, vallen, 0);
return STAT_OK; return STAT_OK;
#endif /* defined(IPV6_RTHDR) */ #endif /* defined(IPV6_RTHDR) */
#ifdef IPV6_AUTHHDR #ifdef IPV6_AUTHHDR
case IPV6_AUTHHDR: case IPV6_AUTHHDR:
strncpy(typbuff, "IPV6_AUTHHDR", typlen); typbuff[0] = '\0'; strncat(typbuff, "IPV6_AUTHHDR", typlen-1);
strncpy(nambuff, "authhdr", namlen); nambuff[0] = '\0'; strncat(nambuff, "authhdr", namlen-1);
xiodump(CMSG_DATA(cmsg), msglen, valbuff, vallen, 0); xiodump(CMSG_DATA(cmsg), msglen, valbuff, vallen, 0);
return STAT_OK; return STAT_OK;
#endif #endif
#ifdef IPV6_DSTOPTS #ifdef IPV6_DSTOPTS
case IPV6_DSTOPTS: case IPV6_DSTOPTS:
strncpy(typbuff, "IPV6_DSTOPTS", typlen); typbuff[0] = '\0'; strncat(typbuff, "IPV6_DSTOPTS", typlen-1);
strncpy(nambuff, "dstopts", namlen); nambuff[0] = '\0'; strncat(nambuff, "dstopts", namlen-1);
xiodump(CMSG_DATA(cmsg), msglen, valbuff, vallen, 0); xiodump(CMSG_DATA(cmsg), msglen, valbuff, vallen, 0);
return STAT_OK; return STAT_OK;
#endif /* defined(IPV6_DSTOPTS) */ #endif /* defined(IPV6_DSTOPTS) */
#ifdef IPV6_HOPOPTS #ifdef IPV6_HOPOPTS
case IPV6_HOPOPTS: case IPV6_HOPOPTS:
strncpy(typbuff, "IPV6_HOPOPTS", typlen); typbuff[0] = '\0'; strncat(typbuff, "IPV6_HOPOPTS", typlen-1);
strncpy(nambuff, "hopopts", namlen); nambuff[0] = '\0'; strncat(nambuff, "hopopts", namlen-1);
xiodump(CMSG_DATA(cmsg), msglen, valbuff, vallen, 0); xiodump(CMSG_DATA(cmsg), msglen, valbuff, vallen, 0);
return STAT_OK; return STAT_OK;
#endif /* defined(IPV6_HOPOPTS) */ #endif /* defined(IPV6_HOPOPTS) */
#ifdef IPV6_FLOWINFO #ifdef IPV6_FLOWINFO
case IPV6_FLOWINFO: case IPV6_FLOWINFO:
strncpy(typbuff, "IPV6_FLOWINFO", typlen); typbuff[0] = '\0'; strncat(typbuff, "IPV6_FLOWINFO", typlen-1);
strncpy(nambuff, "flowinfo", namlen); nambuff[0] = '\0'; strncat(nambuff, "flowinfo", namlen-1);
xiodump(CMSG_DATA(cmsg), msglen, valbuff, vallen, 0); xiodump(CMSG_DATA(cmsg), msglen, valbuff, vallen, 0);
return STAT_OK; return STAT_OK;
#endif #endif
#ifdef IPV6_TCLASS #ifdef IPV6_TCLASS
case IPV6_TCLASS: case IPV6_TCLASS:
strncpy(typbuff, "IPV6_TCLASS", typlen); typbuff[0] = '\0'; strncat(typbuff, "IPV6_TCLASS", typlen-1);
strncpy(nambuff, "tclass", namlen); nambuff[0] = '\0'; strncat(nambuff, "tclass", namlen-1);
xiodump(CMSG_DATA(cmsg), msglen, valbuff, vallen, 0); xiodump(CMSG_DATA(cmsg), msglen, valbuff, vallen, 0);
return STAT_OK; return STAT_OK;
#endif #endif
default: default:
snprintf(typbuff, typlen, "IPV6.%u", cmsg->cmsg_type); 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); xiodump(CMSG_DATA(cmsg), msglen, valbuff, vallen, 0);
return STAT_OK; return STAT_OK;
} }

View file

@ -1,5 +1,5 @@
/* source: xio-progcall.c */ /* source: xio-progcall.c */
/* Copyright Gerhard Rieger 2001-2012 */ /* Copyright Gerhard Rieger */
/* Published under the GNU General Public License V.2, see file COPYING */ /* Published under the GNU General Public License V.2, see file COPYING */
/* this file contains common code dealing with program calls (exec, system) */ /* this file contains common code dealing with program calls (exec, system) */
@ -148,7 +148,7 @@ int _xioopen_progcall(int xioflags, /* XIO_RDONLY etc. */
#endif #endif
); );
if (usepipes && usepty) { 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; usepipes = false;
} }
#endif /* HAVE_PTY */ #endif /* HAVE_PTY */

View file

@ -1,5 +1,5 @@
/* source: xio-pty.c */ /* source: xio-pty.c */
/* Copyright Gerhard Rieger 2002-2012 */ /* Copyright Gerhard Rieger */
/* Published under the GNU General Public License V.2, see file COPYING */ /* Published under the GNU General Public License V.2, see file COPYING */
/* this file contains the source for creating pty addresses */ /* 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)); 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 */ #endif /* HAVE_DEV_PTMX || HAVE_DEV_PTC */

View file

@ -1,5 +1,5 @@
/* source: xio-readline.c */ /* source: xio-readline.c */
/* Copyright Gerhard Rieger 2002-2012 */ /* Copyright Gerhard Rieger */
/* Published under the GNU General Public License V.2, see file COPYING */ /* Published under the GNU General Public License V.2, see file COPYING */
/* this file contains the source for opening the readline address */ /* 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 */ #endif /* _WITH_TERMIOS */
Add_history(line); Add_history(line);
bytes = strlen(line); bytes = strlen(line);
strncpy(buff, line, bufsiz); ((char *)buff)[0] = '\0'; strncat(buff, line, bufsiz-1);
free(line); free(line);
if ((size_t)bytes < bufsiz) { if ((size_t)bytes < bufsiz) {
strcat(buff, "\n"); ++bytes; strcat(buff, "\n"); ++bytes;

View file

@ -1871,7 +1871,7 @@ int xiocheckpeer(xiosingle_t *xfd,
#if HAVE_STRUCT_CMSGHDR #if HAVE_STRUCT_CMSGHDR
/* converts the ancillary message in *cmsg into a form useable for further /* converts the ancillary message in *cmsg into a form useable for further
processing. knows the specifics of common message types. 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 type strings in *typbuff
returns a sequence of \0 terminated name strings in *nambuff returns a sequence of \0 terminated name strings in *nambuff
returns a sequence of \0 terminated value strings in *valbuff 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; const char *cmsgtype, *cmsgname, *cmsgenvn;
size_t msglen; size_t msglen;
struct timeval *tv; struct timeval *tv;
int rc = STAT_OK;
#if defined(CMSG_DATA) #if defined(CMSG_DATA)
@ -1902,7 +1903,7 @@ xiolog_ancillary_socket(struct cmsghdr *cmsg, int *num,
#endif #endif
default: /* binary data */ default: /* binary data */
snprintf(typbuff, typlen, "SOCKET.%u", cmsg->cmsg_type); 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); xiodump(CMSG_DATA(cmsg), msglen, valbuff, vallen, 0);
return STAT_OK; return STAT_OK;
#ifdef SO_TIMESTAMP #ifdef SO_TIMESTAMP
@ -1931,14 +1932,13 @@ xiolog_ancillary_socket(struct cmsghdr *cmsg, int *num,
with type in cmsgtype, name in cmsgname, with type in cmsgtype, name in cmsgname,
and value already in valbuff */ and value already in valbuff */
*num = 1; *num = 1;
if (strlen(cmsgtype) >= typlen) Fatal("buff too short"); if (strlen(cmsgtype) >= typlen) rc = STAT_WARNING;
strncpy(typbuff, cmsgtype, typlen); typbuff[0] = '\0'; strncat(typbuff, cmsgtype, typlen-1);
if (strlen(cmsgname) >= namlen) Fatal("buff too short"); if (strlen(cmsgname) >= namlen) rc = STAT_WARNING;
strncpy(nambuff, cmsgname, namlen); nambuff[0] = '\0'; strncat(nambuff, cmsgname, namlen-1);
if (strlen(cmsgenvn) >= envlen) Fatal("buff too short"); if (strlen(cmsgenvn) >= envlen) rc = STAT_WARNING;
strncpy(envbuff, cmsgenvn, envlen); envbuff[0] = '\0'; strncat(envbuff, cmsgenvn, envlen-1);
return STAT_OK; return rc;
#else /* !defined(CMSG_DATA) */ #else /* !defined(CMSG_DATA) */
return STAT_NORETRY; return STAT_NORETRY;
@ -2022,7 +2022,7 @@ int xioparsenetwork(const char *rangename, int pf, struct xiorange *range) {
if ((addrname = Malloc(maskname-rangename)) == NULL) { if ((addrname = Malloc(maskname-rangename)) == NULL) {
return STAT_NORETRY; return STAT_NORETRY;
} }
strncpy(addrname, rangename, maskname-rangename-1); strncpy(addrname, rangename, maskname-rangename-1); /* ok */
addrname[maskname-rangename-1] = '\0'; addrname[maskname-rangename-1] = '\0';
result = result =
dalan(addrname, (char *)&range->netaddr.soa.sa_data, &addrlen, dalan(addrname, (char *)&range->netaddr.soa.sa_data, &addrlen,

View file

@ -1,5 +1,5 @@
/* source: xio-socks.c */ /* source: xio-socks.c */
/* Copyright Gerhard Rieger 2001-2012 */ /* Copyright Gerhard Rieger */
/* Published under the GNU General Public License V.2, see file COPYING */ /* Published under the GNU General Public License V.2, see file COPYING */
/* this file contains the source for opening addresses of socks4 type */ /* 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; *headlen = SIZEOF_STRUCT_SOCKS4+strlen(userid)+1;
return STAT_OK; return STAT_OK;
} }
@ -325,7 +325,7 @@ int
after the user name's trailing 0 byte. */ after the user name's trailing 0 byte. */
char* insert_position = (char*) sockhead + *headlen; 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; ((char *)sockhead)[BUFF_LEN-1] = 0;
*headlen += strlen(hostname) + 1; *headlen += strlen(hostname) + 1;
if (*headlen > BUFF_LEN) { if (*headlen > BUFF_LEN) {

View file

@ -1,5 +1,5 @@
/* source: xio-socks5.c */ /* source: xio-socks5.c */
/* Copyright Gerhard Rieger 2004-2009 */ /* Copyright Gerhard Rieger */
/* Published under the GNU General Public License V.2, see file COPYING */ /* Published under the GNU General Public License V.2, see file COPYING */
/* this file contains the source for opening addresses of socks5 type */ /* this file contains the source for opening addresses of socks5 type */
@ -296,7 +296,7 @@ int _xioopen_socks5_connect(struct single *xfd,
targetname); targetname);
} }
sendrequest->destaddr[0] = strlen(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; break;
case SOCKS5_ADDRTYPE_IPV6: case SOCKS5_ADDRTYPE_IPV6:
break; break;
@ -431,10 +431,10 @@ int xio_socks5_username_password(int level, struct opt *opts,
pos = sendbuff; pos = sendbuff;
*pos++ = SOCKS5_USERPASS_VERSION; *pos++ = SOCKS5_USERPASS_VERSION;
*pos++ = strlen(username); *pos++ = strlen(username);
strncpy(pos, username, 255); *pos = '\0'; strncat(pos, username, 255);
pos += strlen(username); pos += strlen(username);
*pos++ = strlen(password); *pos++ = strlen(password);
strncpy(pos, password, 255); *pos = '\0'; strncat(pos, password, 255);
pos += strlen(password); pos += strlen(password);
result = result =

View file

@ -1,5 +1,5 @@
/* source: xio-tun.c */ /* source: xio-tun.c */
/* Copyright Gerhard Rieger 2007-2012 */ /* Copyright Gerhard Rieger */
/* Published under the GNU General Public License V.2, see file COPYING */ /* Published under the GNU General Public License V.2, see file COPYING */
/* this file contains the source for opening addresses of tun/tap type */ /* 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)); memset(&ifr, 0,sizeof(ifr));
if (retropt_string(opts, OPT_TUN_NAME, &tunname) == 0) { if (retropt_string(opts, OPT_TUN_NAME, &tunname) == 0) {
strncpy(ifr.ifr_name, tunname, IFNAMSIZ); strncpy(ifr.ifr_name, tunname, IFNAMSIZ); /* ok */
free(tunname); free(tunname);
} else { } else {
ifr.ifr_name[0] = '\0'; ifr.ifr_name[0] = '\0';

View file

@ -1,5 +1,5 @@
/* source: xio-unix.c */ /* source: xio-unix.c */
/* Copyright Gerhard Rieger 2001-2012 */ /* Copyright Gerhard Rieger */
/* Published under the GNU General Public License V.2, see file COPYING */ /* Published under the GNU General Public License V.2, see file COPYING */
/* this file contains the source for opening addresses of UNIX socket type */ /* 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)); pathlen+1, sizeof(saun->sun_path));
} }
saun->sun_path[0] = '\0'; /* so it's abstract */ 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) { if (tight) {
len = sizeof(struct sockaddr_un)-sizeof(saun->sun_path)+ len = sizeof(struct sockaddr_un)-sizeof(saun->sun_path)+
MIN(pathlen+1, 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"", Warn2("unix socket address "F_Zu" characters long, truncating to "F_Zu"",
pathlen, sizeof(saun->sun_path)); 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) { if (tight) {
len = sizeof(struct sockaddr_un)-sizeof(saun->sun_path)+ len = sizeof(struct sockaddr_un)-sizeof(saun->sun_path)+
MIN(pathlen, sizeof(saun->sun_path)); MIN(pathlen, sizeof(saun->sun_path));

View file

@ -1,5 +1,5 @@
/* source: xioopen.c */ /* source: xioopen.c */
/* Copyright Gerhard Rieger 2001-2009 */ /* Copyright Gerhard Rieger */
/* Published under the GNU General Public License V.2, see file COPYING */ /* Published under the GNU General Public License V.2, see file COPYING */
/* this is the source file of the extended open function */ /* this is the source file of the extended open function */
@ -1071,8 +1071,7 @@ static xiosingle_t *
sfd->argc = 0; sfd->argc = 0;
/* for error messages */ /* for error messages */
strncpy(addr0, *addr, sizeof(addr0)-1); addr0[0] = '\0'; strncat(addr0, *addr, sizeof(addr0)-1);
addr0[sizeof(addr0)-1] = '\0';
len = sizeof(token); tokp = token; len = sizeof(token); tokp = token;
if (nestlex(addr, &tokp, &len, ends, hquotes, squotes, nests, if (nestlex(addr, &tokp, &len, ends, hquotes, squotes, nests,

View file

@ -2325,7 +2325,7 @@ int parseopts_table(const char **a, struct opt **opts,
#if HAVE_STRUCT_IP_MREQN #if HAVE_STRUCT_IP_MREQN
if (*tokp++ == ':') { 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\"}", Info4("setting option \"%s\" to {\"%s\",\"%s\",\"%s\"}",
ent->desc->defname, ent->desc->defname,
(*opts)[i].value.u_ip_mreq.multiaddr, (*opts)[i].value.u_ip_mreq.multiaddr,

View file

@ -1,5 +1,5 @@
/* source: xioparam.c */ /* source: xioparam.c */
/* Copyright Gerhard Rieger 2001-2007 */ /* Copyright Gerhard Rieger */
/* Published under the GNU General Public License V.2, see file COPYING */ /* Published under the GNU General Public License V.2, see file COPYING */
/* this file contains the source for xio options handling */ /* 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) { int xioinqopt(char what, char *arg, size_t n) {
switch (what) { switch (what) {
case 's': return xioopts.strictopts; 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; return 0;
case 'o': return xioopts.ip4portsep; case 'o': return xioopts.ip4portsep;
case 'l': return xioopts.logopt; case 'l': return xioopts.logopt;

View file

@ -1,5 +1,5 @@
/* $Id$ */ /* xiosocketpair.c */
/* Copyright Gerhard Rieger 2007-2009 */ /* Copyright Gerhard Rieger */
/* Published under the GNU General Public License V.2, see file COPYING */ /* Published under the GNU General Public License V.2, see file COPYING */
/* this is the source of the internal xiosocketpair function */ /* 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)); Warn2("ttyname(%d): %s", ptyfd, strerror(errno));
} }
} }
strncpy(ptyname, tn, MAXPTYNAMELEN); ptyname[0] = '\0'; strncat(ptyname, tn, MAXPTYNAMELEN-1);
#endif #endif
if ((ttyfd = Open(tn, O_RDWR|O_NOCTTY, 0620)) < 0) { if ((ttyfd = Open(tn, O_RDWR|O_NOCTTY, 0620)) < 0) {
Warn2("open(\"%s\", O_RDWR|O_NOCTTY, 0620): %s", tn, strerror(errno)); Warn2("open(\"%s\", O_RDWR|O_NOCTTY, 0620): %s", tn, strerror(errno));