Backport several fixes for Coverity warnings from ntp-dev.
bk: 4e3085eekVdLxvStZswxGqUcK3dIyQ
* [Bug 1970] UNLINK_EXPR_SLIST() causes crash if list is empty.
* [Bug 1972] checking for struct rtattr fails.
* [Bug 1975] libntp/mktime.c won't work with 64-bit time_t
+* [Bug 1978] Ignore tentative IP addresses on Linux.
+* Backport several fixes for Coverity warnings from ntp-dev.
---
(4.2.6p4-RC1) 2011/07/10 Released by Harlan Stenn <stenn@ntp.org>
;;
esac
+case "$host" in
+ *-linux*)
+ AC_CHECK_HEADERS([linux/if_addr.h], [], [], [
+ #ifdef HAVE_SYS_SOCKET_H
+ # include <sys/socket.h>
+ #endif
+ ])
+esac
+
AC_CHECK_HEADERS([net/if.h], [], [],
[#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#include "ntp_types.h"
- /*
+/*
* If various macros are not defined we need to define them
*/
#endif /* !AI_PASSIVE */
#ifndef AI_NUMERICHOST /* such as AIX 4.3 */
-#define AI_NUMERICHOST 0
+# define Z_AI_NUMERICHOST 0
+#else
+# define Z_AI_NUMERICHOST AI_NUMERICHOST
+#endif
+
+#ifndef AI_NUMERICSERV /* not in RFC 2553 */
+# define Z_AI_NUMERICSERV 0
+#else
+# define Z_AI_NUMERICSERV AI_NUMERICSERV
#endif
#ifndef ISC_PLATFORM_HAVEIPV6
#endif
#include <net/if.h>
-#ifdef __linux
+#ifdef HAVE_LINUX_IF_ADDR_H
# include <linux/if_addr.h>
#endif
switch (family) {
case AF_INET:
memcpy(&dst->type.in,
- &((struct sockaddr_in *) src)->sin_addr,
+ &((struct sockaddr_in *)(void *)src)->sin_addr,
sizeof(struct in_addr));
break;
case AF_INET6:
- sa6 = (struct sockaddr_in6 *)src;
+ sa6 = (struct sockaddr_in6 *)(void *)src;
memcpy(&dst->type.in6, &sa6->sin6_addr,
sizeof(struct in6_addr));
#ifdef ISC_PLATFORM_HAVESCOPEID
** Ignore DAD addresses --
** we can't bind to them until they are resolved
*/
+#ifdef IFA_F_TENTATIVE
if (flags & IFA_F_TENTATIVE)
return (ISC_R_IGNORE);
+#endif
for (i = 0; i < 16; i++) {
unsigned char byte;
for (; *ca && isascii((int)*ca) && (isspace((int)*ca) || (*ca == '=')); ca++)
continue;
- if (!strncmp(cc, "IDEV", (size_t) 4)) {
- sscanf(ca, "%s", ab);
- strcpy(cf_i_dev, ab);
+ if (!strncmp(cc, "IDEV", 4) &&
+ 1 == sscanf(ca, "%99s", ab)) {
+ strncpy(cf_i_dev, ab, sizeof(cf_i_dev));
printf("idev <%s>\n", ab);
- } else if (!strncmp(cc, "CDEV", (size_t) 4)) {
- sscanf(ca, "%s", ab);
- strcpy(cf_c_dev, ab);
+ } else if (!strncmp(cc, "CDEV", 4) &&
+ 1 == sscanf(ca, "%99s", ab)) {
+ strncpy(cf_c_dev, ab, sizeof(cf_c_dev));
printf("cdev <%s>\n", ab);
- } else if (!strncmp(cc, "AGC", (size_t) 3)) {
- sscanf(ca, "%s", ab);
- strcpy(cf_agc, ab);
+ } else if (!strncmp(cc, "AGC", 3) &&
+ 1 == sscanf(ca, "%99s", ab)) {
+ strncpy(cf_agc, ab, sizeof(cf_agc));
printf("agc <%s> %d\n", ab, i);
- } else if (!strncmp(cc, "MONITOR", (size_t) 7)) {
- sscanf(ca, "%s", ab);
- strcpy(cf_monitor, ab);
+ } else if (!strncmp(cc, "MONITOR", 7) &&
+ 1 == sscanf(ca, "%99s", ab)) {
+ strncpy(cf_monitor, ab, sizeof(cf_monitor));
printf("monitor <%s> %d\n", ab, mixer_name(ab, -1));
}
}
printf("SOUND_MIXER_READ_RECMASK: %s\n", strerror(errno));
/* validate and set any specified config file stuff */
- if (*cf_agc) {
+ if (cf_agc[0] != '\0') {
int i;
i = mixer_name(cf_agc, devmask);
cf_agc, recmask);
}
- if (*cf_monitor) {
+ if (cf_monitor[0] != '\0') {
int i;
/* devmask */
r = 0 ; /* setting to zero nicely mutes the channel */
#endif
l |= r << 8;
- if ( cf_agc )
- rval = ioctl(ctl_fd, agc, &l);
- else
- if (port == 2) {
- rval = ioctl(ctl_fd, SOUND_MIXER_WRITE_LINE, &l);
- } else {
- rval = ioctl(ctl_fd, SOUND_MIXER_WRITE_MIC, &l);
- }
- if (rval == -1) {
+ if (cf_agc[0] != '\0')
+ rval = ioctl(ctl_fd, agc, &l);
+ else
+ if (2 == port)
+ rval = ioctl(ctl_fd, SOUND_MIXER_WRITE_LINE, &l);
+ else
+ rval = ioctl(ctl_fd, SOUND_MIXER_WRITE_MIC, &l);
+ if (-1 == rval) {
printf("audio_gain: agc write: %s\n", strerror(errno));
- return (rval);
+ return rval;
}
if (o_mongain != mongain) {
printf("audio_gain: mongain %d/%d\n", mongain, l);
# endif
l |= r << 8;
- if ( cf_monitor )
- rval = ioctl(ctl_fd, monitor, &l );
- else
- rval = ioctl(ctl_fd, SOUND_MIXER_WRITE_VOLUME, &l);
- if (rval == -1) {
+ if (cf_monitor[0] != '\0')
+ rval = ioctl(ctl_fd, monitor, &l );
+ else
+ rval = ioctl(ctl_fd, SOUND_MIXER_WRITE_VOLUME,
+ &l);
+ if (-1 == rval) {
printf("audio_gain: mongain write: %s\n",
strerror(errno));
return (rval);
#include <netinet/in.h>
#endif
+#include "ntp.h"
#include "ntp_stdlib.h"
#include "ntp_assert.h"
+/*
+ * decodenetnum convert text IP address and port to sockaddr_u
+ *
+ * Returns 0 for failure, 1 for success.
+ */
int
decodenetnum(
const char *num,
)
{
struct addrinfo hints, *ai = NULL;
- register int err;
- register const char *cp;
- char name[80];
+ int err;
+ u_short port;
+ const char *cp;
+ const char *port_str;
+ char *pp;
char *np;
+ char name[80];
NTP_REQUIRE(num != NULL);
NTP_REQUIRE(strlen(num) < sizeof(name));
- if ('[' != num[0])
- cp = num;
- else {
+ port_str = NULL;
+ if ('[' != num[0]) {
+ /*
+ * to distinguish IPv6 embedded colons from a port
+ * specification on an IPv4 address, assume all
+ * legal IPv6 addresses have at least two colons.
+ */
+ pp = strchr(num, ':');
+ if (NULL == pp)
+ cp = num; /* no colons */
+ else if (NULL != strchr(pp + 1, ':'))
+ cp = num; /* two or more colons */
+ else { /* one colon */
+ strncpy(name, num, sizeof(name));
+ name[sizeof(name) - 1] = '\0';
+ cp = name;
+ pp = strchr(cp, ':');
+ *pp = '\0';
+ port_str = pp + 1;
+ }
+ } else {
cp = num + 1;
np = name;
while (*cp && ']' != *cp)
*np++ = *cp++;
*np = 0;
+ if (']' == cp[0] && ':' == cp[1] && '\0' != cp[2])
+ port_str = &cp[2];
cp = name;
}
- memset(&hints, 0, sizeof(hints));
- hints.ai_flags = AI_NUMERICHOST;
- err = getaddrinfo(cp, NULL, &hints, &ai);
+ ZERO(hints);
+ hints.ai_flags = Z_AI_NUMERICHOST;
+ err = getaddrinfo(cp, "ntp", &hints, &ai);
if (err != 0)
return 0;
- memcpy(netnum, ai->ai_addr, ai->ai_addrlen);
+ NTP_INSIST(ai->ai_addrlen <= sizeof(*netnum));
+ memcpy(netnum, ai->ai_addr, ai->ai_addrlen);
freeaddrinfo(ai);
+ if (NULL == port_str || 1 != sscanf(port_str, "%hu", &port))
+ port = NTP_PORT;
+ SET_PORT(netnum, port);
return 1;
}
* distribution. The only function provided is to load the radio
* frequency. All other parameters must be manually set before use.
*/
+#include <config.h>
#include "icom.h"
#include <unistd.h>
#include <stdio.h>
#include "ntp_tty.h"
#include "l_stdlib.h"
+#ifdef SYS_WINNT
+#undef write /* ports/winnt/include/config.h: #define write _write */
+extern int async_write(int, const void *, unsigned int);
+#define write(fd, data, octets) async_write(fd, data, octets)
+#endif
+
/*
* Packet routines
*
u_char cmd[] = {PAD, PR, PR, 0, TX, V_SFREQ, 0, 0, 0, 0, FI,
FI};
int temp;
- cmd[3] = ident;
+
+ cmd[3] = (char)ident;
if (ident == IC735)
temp = 4;
else
temp = 5;
doublefreq(freq * 1e6, &cmd[6], temp);
temp = write(fd, cmd, temp + 7);
+
return (0);
}
)
{
int i;
- char s1[11];
+ char s1[16];
char *y;
- sprintf(s1, " %10.0f", freq);
+ snprintf(s1, sizeof(s1), " %10.0f", freq);
y = s1 + 10;
i = 0;
while (*y != ' ') {
x[i] = x[i] | ((*y-- & 0x0f) << 4);
i++;
}
- for (; i < len; i++)
+ for ( ; i < len; i++)
x[i] = 0;
x[i] = FI;
}
/*
- * icom_open() - open and initialize serial interface
+ * icom_init() - open and initialize serial interface
*
* This routine opens the serial interface for raw transmission; that
* is, character-at-a-time, no stripping, checking or monkeying with the
int trace /* trace flags */ )
{
TTY ttyb;
- int fd, flags;
+ int fd;
+ int flags;
+ int rc;
+ int saved_errno;
flags = trace;
- fd = open(device, O_RDWR, 0777);
+ fd = tty_open(device, O_RDWR, 0777);
if (fd < 0)
- return (fd);
+ return -1;
- tcgetattr(fd, &ttyb);
+ rc = tcgetattr(fd, &ttyb);
+ if (rc < 0) {
+ saved_errno = errno;
+ close(fd);
+ errno = saved_errno;
+ return -1;
+ }
ttyb.c_iflag = 0; /* input modes */
ttyb.c_oflag = 0; /* output modes */
ttyb.c_cflag = IBAUD|CS8|CLOCAL; /* control modes (no read) */
ttyb.c_cc[VTIME] = 5; /* receive timeout */
cfsetispeed(&ttyb, (u_int)speed);
cfsetospeed(&ttyb, (u_int)speed);
- tcsetattr(fd, TCSANOW, &ttyb);
+ rc = tcsetattr(fd, TCSANOW, &ttyb);
+ if (rc < 0) {
+ saved_errno = errno;
+ close(fd);
+ errno = saved_errno;
+ return -1;
+ }
return (fd);
}
)
{
struct refclockproc *pp = peer->procptr;
- register struct arcunit *up = (struct arcunit *)pp->unitptr;
+ register struct arcunit *up = pp->unitptr;
int i;
char c;
#ifdef DEBUG
{
register struct arcunit *up;
struct refclockproc *pp;
+ int temp_fd;
int fd;
char device[20];
#ifdef HAVE_TERMIOS
struct termios arg;
#endif
- msyslog(LOG_NOTICE, "ARCRON: %s: opening unit %d", arc_version, unit);
-#ifdef DEBUG
- if(debug) {
- printf("arc: %s: attempt to open unit %d.\n", arc_version, unit);
- }
-#endif
-
- /* Prevent a ridiculous device number causing overflow of device[]. */
- if((unit < 0) || (unit > 255)) { return(0); }
+ msyslog(LOG_NOTICE, "MSF_ARCRON %s: opening unit %d",
+ arc_version, unit);
+ DPRINTF(1, ("arc: %s: attempt to open unit %d.\n", arc_version,
+ unit));
/*
* Open serial port. Use CLK line discipline, if available.
*/
snprintf(device, sizeof(device), DEVICE, unit);
- if (!(fd = refclock_open(device, SPEED, LDISC_CLK)))
- return(0);
-#ifdef DEBUG
- if(debug) { printf("arc: unit %d using open().\n", unit); }
-#endif
+ temp_fd = refclock_open(device, SPEED, LDISC_CLK);
+ if (temp_fd <= 0)
+ return 0;
+ DPRINTF(1, ("arc: unit %d using tty_open().\n", unit));
fd = tty_open(device, OPEN_FLAGS, 0777);
- if(fd < 0) {
-#ifdef DEBUG
- if(debug) { printf("arc: failed [tty_open()] to open %s.\n", device); }
-#endif
- return(0);
+ if (fd < 0) {
+ msyslog(LOG_ERR, "MSF_ARCRON(%d): failed second open(%s, 0777): %m.\n",
+ unit, device);
+ close(temp_fd);
+ return 0;
}
+ close(temp_fd);
+ temp_fd = -1;
#ifndef SYS_WINNT
fcntl(fd, F_SETFL, 0); /* clear the descriptor flags */
#endif
-#ifdef DEBUG
- if(debug)
- { printf("arc: opened RS232 port with file descriptor %d.\n", fd); }
-#endif
+ DPRINTF(1, ("arc: opened RS232 port with file descriptor %d.\n", fd));
#ifdef HAVE_TERMIOS
- tcgetattr(fd, &arg);
+ if (tcgetattr(fd, &arg) < 0) {
+ msyslog(LOG_ERR, "MSF_ARCRON(%d): tcgetattr(%s): %m.\n",
+ unit, device);
+ close(fd);
+ return 0;
+ }
arg.c_iflag = IGNBRK | ISTRIP;
arg.c_oflag = 0;
arg.c_cc[VMIN] = 1;
arg.c_cc[VTIME] = 0;
- tcsetattr(fd, TCSANOW, &arg);
+ if (tcsetattr(fd, TCSANOW, &arg) < 0) {
+ msyslog(LOG_ERR, "MSF_ARCRON(%d): tcsetattr(%s): %m.\n",
+ unit, device);
+ close(fd);
+ return 0;
+ }
#else
- msyslog(LOG_ERR, "ARCRON: termios not supported in this driver");
+ msyslog(LOG_ERR, "ARCRON: termios required by this driver");
(void)close(fd);
return 0;
#endif
- up = emalloc(sizeof(*up));
/* Set structure to all zeros... */
- memset(up, 0, sizeof(*up));
+ up = emalloc_zero(sizeof(*up));
pp = peer->procptr;
pp->io.clock_recv = arc_receive;
pp->io.srcclock = (caddr_t)peer;
free(up);
return(0);
}
- pp->unitptr = (caddr_t)up;
+ pp->unitptr = up;
/*
* Initialize miscellaneous variables
peer->action = dummy_event_handler;
pp = peer->procptr;
- up = (struct arcunit *)pp->unitptr;
+ up = pp->unitptr;
if (-1 != pp->io.fd)
io_closeclock(&pp->io);
if (NULL != up)
*/
peer = (struct peer *)rbufp->recv_srcclock;
pp = peer->procptr;
- up = (struct arcunit *)pp->unitptr;
+ up = pp->unitptr;
/*
)
{
struct refclockproc *pp = peer->procptr;
- register struct arcunit *up = (struct arcunit *)pp->unitptr;
+ register struct arcunit *up = pp->unitptr;
#ifdef DEBUG
if(debug) { printf("arc: unit %d: requesting time.\n", unit); }
#endif
int resync_needed; /* Should we start a resync? */
pp = peer->procptr;
- up = (struct arcunit *)pp->unitptr;
+ up = pp->unitptr;
#if 0
pp->lencode = 0;
memset(pp->a_lastcode, 0, sizeof(pp->a_lastcode));
hints.ai_family = ai_fam_templ;
hints.ai_protocol = IPPROTO_UDP;
hints.ai_socktype = SOCK_DGRAM;
- hints.ai_flags = AI_NUMERICHOST;
+ hints.ai_flags = Z_AI_NUMERICHOST;
a_info = getaddrinfo(hname, service, &hints, &ai);
if (a_info == EAI_NONAME
int af
)
{
- int sockaddr_len;
struct addrinfo hints, *ai = NULL;
- sockaddr_len = SIZEOF_SOCKADDR(af);
- memset((char *)&hints, 0, sizeof(struct addrinfo));
+ ZERO(hints);
hints.ai_flags = AI_CANONNAME;
#ifdef AI_ADDRCONFIG
hints.ai_flags |= AI_ADDRCONFIG;
#endif
- /* decodenetnum only works with addresses */
+ /*
+ * decodenetnum only works with addresses, but handles syntax
+ * that getaddrinfo doesn't: [2001::1]:1234
+ */
if (decodenetnum(hname, num)) {
- if (fullhost != 0) {
- getnameinfo(&num->sa, sockaddr_len,
- fullhost, sizeof(fullhost), NULL, 0,
- NI_NUMERICHOST);
- }
+ if (fullhost != NULL)
+ getnameinfo(&num->sa, SOCKLEN(num), fullhost,
+ LENHOSTNAME, NULL, 0, 0);
return 1;
} else if (getaddrinfo(hname, "ntp", &hints, &ai) == 0) {
- memmove((char *)num, ai->ai_addr, ai->ai_addrlen);
- if (fullhost != 0)
- (void) strcpy(fullhost, ai->ai_canonname);
+ NTP_INSIST(sizeof(*num) >= ai->ai_addrlen);
+ memcpy(num, ai->ai_addr, ai->ai_addrlen);
+ if (fullhost != NULL) {
+ if (ai->ai_canonname != NULL) {
+ strncpy(fullhost, ai->ai_canonname,
+ LENHOSTNAME);
+ fullhost[LENHOSTNAME - 1] = '\0';
+ } else {
+ getnameinfo(&num->sa, SOCKLEN(num),
+ fullhost, LENHOSTNAME, NULL,
+ 0, 0);
+ }
+ }
return 1;
- } else {
- (void) fprintf(stderr, "***Can't find host %s\n", hname);
- return 0;
}
- /*NOTREACHED*/
+ fprintf(stderr, "***Can't find host %s\n", hname);
+
+ return 0;
}
/*
hints.ai_family = ai_fam_templ;
hints.ai_protocol = IPPROTO_UDP;
hints.ai_socktype = SOCK_DGRAM;
- hints.ai_flags = AI_NUMERICHOST;
+ hints.ai_flags = Z_AI_NUMERICHOST;
a_info = getaddrinfo(hname, service, &hints, &ai);
if (a_info == EAI_NONAME
int af
)
{
- int sockaddr_len;
struct addrinfo hints, *ai = NULL;
- sockaddr_len = SIZEOF_SOCKADDR(af);
- memset(&hints, 0, sizeof(hints));
+ ZERO(hints);
hints.ai_flags = AI_CANONNAME;
#ifdef AI_ADDRCONFIG
hints.ai_flags |= AI_ADDRCONFIG;
#endif
- /* decodenetnum works with addresses only */
+ /*
+ * decodenetnum only works with addresses, but handles syntax
+ * that getaddrinfo doesn't: [2001::1]:1234
+ */
if (decodenetnum(hname, num)) {
- if (fullhost != 0) {
- getnameinfo((struct sockaddr *)num, sockaddr_len,
- fullhost, sizeof(fullhost), NULL, 0,
- NI_NUMERICHOST);
- }
+ if (fullhost != NULL)
+ getnameinfo(&num->sa, SOCKLEN(num), fullhost,
+ LENHOSTNAME, NULL, 0, 0);
return 1;
} else if (getaddrinfo(hname, "ntp", &hints, &ai) == 0) {
- memmove((char *)num, ai->ai_addr, ai->ai_addrlen);
- if (ai->ai_canonname != 0)
- (void) strcpy(fullhost, ai->ai_canonname);
+ NTP_INSIST(sizeof(*num) >= ai->ai_addrlen);
+ memcpy(num, ai->ai_addr, ai->ai_addrlen);
+ if (fullhost != NULL) {
+ if (ai->ai_canonname != NULL) {
+ strncpy(fullhost, ai->ai_canonname,
+ LENHOSTNAME);
+ fullhost[LENHOSTNAME - 1] = '\0';
+ } else {
+ getnameinfo(&num->sa, SOCKLEN(num),
+ fullhost, LENHOSTNAME, NULL,
+ 0, 0);
+ }
+ }
return 1;
- } else {
- (void) fprintf(stderr, "***Can't find host %s\n", hname);
- return 0;
}
- /*NOTREACHED*/
+ fprintf(stderr, "***Can't find host %s\n", hname);
+
+ return 0;
}
/*