[Bug 1250] CID 53: kod_init_kod_db() overruns kod_db malloc'd buffer.
[Bug 1251] CID 68: search_entry() mishandles dst argument.
[Bug 1252] CID 32: Quiet Coverity warning with assertion.
[Bug 1253] CID 50: gsoc_sntp/crypto.c auth_init() always returns a
list with one entry.
[Bug 1254] CID 56: tv_to_str() leaks a struct tm each call.
[Bug 1255] CID 55: pkt_output() leaks a copy of each packet.
[Bug 1256] CID 51: Coverity doesn't recognize our assertion macros as
terminal.
[Bug 1257] CID 57: gsoc_sntp auth_init() fails to fclose(keyfile).
[Bug 1258] CID 54: gsoc_sntp resolve_hosts() needs simplification.
[Bug 1259] CID 59: gsoc_sntp recv_bcast_data() fails to free(rdata)
on error paths.
[Bug 1260] CID 60: gsoc_sntp recvpkt() fails to free(rdata).
bk: 4a69578dPevRCr_Tbm2D5PQv6EEfQQ
+* [Bug 965] CID 42: ss_family uninitialized.
+* [Bug 1250] CID 53: kod_init_kod_db() overruns kod_db malloc'd buffer.
+* [Bug 1251] CID 68: search_entry() mishandles dst argument.
+* [Bug 1252] CID 32: Quiet Coverity warning with assertion.
+* [Bug 1253] CID 50: gsoc_sntp/crypto.c auth_init() always returns a
+ list with one entry.
+* [Bug 1254] CID 56: tv_to_str() leaks a struct tm each call.
+* [Bug 1255] CID 55: pkt_output() leaks a copy of each packet.
+* [Bug 1256] CID 51: Coverity doesn't recognize our assertion macros as
+ terminal.
+* [Bug 1257] CID 57: gsoc_sntp auth_init() fails to fclose(keyfile).
+* [Bug 1258] CID 54: gsoc_sntp resolve_hosts() needs simplification.
+* [Bug 1259] CID 59: gsoc_sntp recv_bcast_data() fails to free(rdata)
+ on error paths.
+* [Bug 1260] CID 60: gsoc_sntp recvpkt() fails to free(rdata).
(4.2.5p191) 2009/07/21 Released by Harlan Stenn <stenn@ntp.org>
* Updated to AutoGen-5.9.9pre1.
(4.2.5p190) 2009/07/20 Released by Harlan Stenn <stenn@ntp.org>
if(feof(keyf)) {
if(ENABLED_OPT(NORMALVERBOSE))
printf("sntp auth_init: Key file %s is empty!\n", keyfile);
+ fclose(keyf);
return -1;
}
struct key *act = (struct key *) malloc(sizeof(struct key));
line_limit = 0;
- fgets(kbuf, 96, keyf);
+ fgets(kbuf, sizeof(kbuf), keyf);
- for(a=0; a<strlen(kbuf) && a < 96; a++) {
+ for(a=0; a<strlen(kbuf) && a < sizeof(kbuf); a++) {
if(kbuf[a] == '#') {
line_limit = a;
break;
if((scan_cnt = sscanf(kbuf, "%i %c %16s", &act->key_id, &act->type, act->key_seq)) == 3) {
act->key_len = strlen(act->key_seq);
-
- if(act->type != 0) {
+ act->next = NULL;
+
+ if (NULL == prev)
*keys = act;
- prev = act;
- }
- else {
+ else
prev->next = act;
- act->next = NULL;
- prev = act;
- }
+ prev = act;
key_cnt++;
)
{
register int a, b, resc = 0;
- struct kod_entry *sptr = kod_db;
+ struct kod_entry *sptr;
- for(a=0; a<entryc && sptr; a++) {
- if(!strcmp(sptr->hostname, hostname))
+ sptr = kod_db;
+ for (a = 0; a < entryc && sptr; a++) {
+ if (!strcmp(sptr->hostname, hostname))
resc++;
sptr = sptr->next;
}
- dst = (struct kod_entry **) malloc(sizeof(struct kod_entry) * resc);
+ if (!resc)
+ return 0;
+
+ *dst = malloc(sizeof(struct kod_entry) * resc);
+ if (NULL == *dst)
+ return 0;
- b=0;
- for(a=0; a<entryc && sptr; a++) {
- if(!strcmp(sptr->hostname, hostname)) {
- dst[b] = sptr;
+ sptr = kod_db;
+ b = 0;
+ for (a = 0; a < entryc && sptr; a++) {
+ if (!strcmp(sptr->hostname, hostname)) {
+ (*dst)[b] = *sptr;
+ (*dst)[b].next = &((*dst)[b + 1]);
b++;
}
+
+ sptr = sptr->next;
}
+ if (b)
+ (*dst)[b - 1].next = NULL;
return resc;
}
+#if 0 /* presently useless */
int
kod_entry_exists (
char *search_str
else
return 1;
}
+#endif
void
add_entry (
const char *db_file
)
{
- if(kod_init)
- return;
-
-#ifdef DEBUG
- printf("Initializing KOD DB...\n");
-#endif
-
register int a, b;
/* Max. of 255 characters for hostname, 10 for timestamp, 4 for kisscode, 2 for format : and 1 for \n */
char fbuf[272];
char error = 0;
+ if (kod_init)
+ return;
+
+#ifdef DEBUG
+ printf("Initializing KOD DB...\n");
+#endif
db_s = fopen(db_file, "r");
/* First let's see how many entries there are and check for right syntax */
while(!feof(db_s)) {
- fgets(fbuf, 272, db_s);
-
int sepc = 0;
+
+ fgets(fbuf, sizeof(fbuf), db_s);
+
for(a=0; a<strlen(fbuf); a++) {
if(fbuf[a] == ':')
sepc++;
if(fbuf[a] == '\n') {
if(sepc != 2) {
char msg[80];
- snprintf(msg, 80, "Syntax error in KOD db file %s in line %i (missing :)", db_file, (entryc + 1));
+ snprintf(msg, sizeof(msg), "Syntax error in KOD db file %s in line %i (missing :)", db_file, (entryc + 1));
#ifdef DEBUG
debug_msg(msg);
kod_db = (struct kod_entry *) malloc(sizeof(struct kod_entry) * entryc);
/* Read contents of file and make a linked list */
- for(b=0; (!feof(db_s) || !ferror(db_s)) && b<entryc; b++) {
- char *str_ptr = fgets(fbuf, 272, db_s);
+ for(b=0; !feof(db_s) && !ferror(db_s) && b < entryc; b++) {
+ char *str_ptr;
+ int j;
- int j = sscanf(fbuf, "%255[^:]", (char *) &(kod_db[b].hostname));
- j += sscanf(fbuf + j, "%*[^:]:%i:%4s", &kod_db[b].timestamp, (char *) &(kod_db[b].type));
-
- if(str_ptr == NULL) {
- b = entryc;
+ str_ptr = fgets(fbuf, sizeof(fbuf), db_s);
+ if (NULL == str_ptr) {
error = 1;
- }
- else {
- if(b > 0)
- kod_db[b-1].next = &kod_db[b];
+ break;
}
- }
-#ifdef DEBUG
- for(a=0; a<entryc; a++)
- printf("KOD entry %i: %s at %i type %s\n", a, kod_db[a].hostname,
- kod_db[a].timestamp, kod_db[a].type);
+ j = sscanf(fbuf, "%255[^:]", (char *) &(kod_db[b].hostname));
+ /* sscanf returns count of fields, not characters, so this looks iffy */
+ /* also why not a single call to sscanf combining both of these? */
+ j += sscanf(fbuf + j, "%*[^:]:%i:%4s", &kod_db[b].timestamp, (char *) &(kod_db[b].type));
- printf("\n");
-#endif
+ kod_db[b].next = NULL;
+ if (b > 0)
+ kod_db[b-1].next = &kod_db[b];
+ }
- if(ferror(db_s) || error) {
+ if (ferror(db_s) || error) {
char msg[80];
- snprintf(msg, 80, "An error occured while parsing the KOD db file %s", db_file);
+ snprintf(msg, sizeof(msg), "An error occured while parsing the KOD db file %s", db_file);
#ifdef DEBUG
debug_msg(msg);
#endif
-
log_msg(msg, 2);
return;
}
+#ifdef DEBUG
+ for(a=0; a<entryc; a++)
+ printf("KOD entry %i: %s at %i type %s\n", a, kod_db[a].hostname,
+ kod_db[a].timestamp, kod_db[a].type);
+
+ printf("\n");
+#endif
- kod_db[b].next = NULL;
fclose(db_s);
)
{
register int c;
- struct kod_entry **reason = NULL;
+ struct kod_entry *reason = NULL;
+ int optct;
+ int sync_data_suc = 0;
+ struct addrinfo **resh = NULL;
+ int resc;
/* IPv6 available? */
if (isc_net_probeipv6() != ISC_R_SUCCESS) {
log_msg("Started sntp", 0);
- int optct = optionProcess(&sntpOptions, argc, argv);
+ optct = optionProcess(&sntpOptions, argc, argv);
argc -= optct;
argv += optct;
/* Parse config file if declared TODO */
/* Initialize logging system */
- if(HAVE_OPT(FILELOG)) {
+ if (HAVE_OPT(FILELOG))
init_log(OPT_ARG(FILELOG));
- }
/* If there's a specified KOD file init KOD system.
* If not and system may save to HD use default file.
*/
- if(HAVE_OPT(KOD)) {
+ if (HAVE_OPT(KOD))
kod_init_kod_db(OPT_ARG(KOD));
- }
- if(HAVE_OPT(KEYFILE)) {
+ if (HAVE_OPT(KEYFILE))
auth_init(OPT_ARG(KEYFILE), &keys);
- }
/* Considering employing a variable that prevents functions of doing anything until
* everything is initialized properly
*/
- struct addrinfo **resh = (struct addrinfo **) malloc(sizeof(struct addrinfo **));
-
- int resc = resolve_hosts(argv, argc, resh, ai_fam_pref);
+ resc = resolve_hosts(argv, argc, &resh, ai_fam_pref);
- if(resc < 1) {
- /* Error! Network down? */
+ if (resc < 1) {
+ printf("Unable to resolve hostname(s)\n");
+ return -1;
}
/* Select a certain ntp server according to simple criteria? For now
* let's just pay attention to previous KoDs.
*/
- int sync_data_suc = 0;
- for(c=0; c<resc && !sync_data_suc; c++) {
+ for (c = 0; c < resc && !sync_data_suc; c++) {
getnameinfo(resh[c]->ai_addr, resh[c]->ai_addrlen, adr_buf,
sizeof(adr_buf), NULL, 0, NI_NUMERICHOST);
int kodc;
char *hostname = addrinfo_to_str(resh[c]);
- if((kodc = search_entry(hostname, reason)) == 0 &&
- is_reachable(resh[c])) {
- int ow_ret = on_wire(resh[c]);
- if(ow_ret < 0) {
- printf("on_wire failed for server %s!\n", hostname);
- }
- else {
- sync_data_suc = 1;
+ if ((kodc = search_entry(hostname, &reason)) == 0) {
+ if (is_reachable(resh[c])) {
+ int ow_ret = on_wire(resh[c]);
+
+ if (ow_ret < 0)
+ printf("on_wire failed for server %s!\n", hostname);
+ else
+ sync_data_suc = 1;
}
- }
- else {
+ } else {
printf("KoD %i packages exists for %s, stopping any further communication.\n",
kodc, adr_buf);
-
+ free(reason);
}
freeaddrinfo(resh[c]);
free(hostname);
}
+ free(resh);
return 0;
}
resolve_hosts (
char **hosts,
int hostc,
- struct addrinfo **res,
+ struct addrinfo ***res,
int pref_family
)
{
- register unsigned int a, b;
- unsigned int entryc = 0;
+ register unsigned int a;
+ unsigned int resc;
+ struct addrinfo **tres;
- if(hostc < 1)
+ if (hostc < 1 || NULL == res)
return 0;
- struct addrinfo ***tres = (struct addrinfo ***) malloc(sizeof(struct addrinfo **) * hostc);
+ tres = malloc(sizeof(struct addrinfo *) * hostc);
- for(a=0; a<hostc; a++) {
- tres[a] = (struct addrinfo **) malloc(sizeof(struct addrinfo));
+ for (a = 0, resc = 0; a < hostc; a++) {
+ struct addrinfo hints;
+ int error;
+
+ tres[resc] = NULL;
#ifdef DEBUG
printf("sntp resolve_hosts: Starting host resolution for %s...\n", hosts[a]);
#endif
- struct addrinfo hints, *dres;
- int error;
-
memset(&hints, 0, sizeof(hints));
- if(pref_family == 0)
+ if (AF_UNSPEC == pref_family)
hints.ai_family = PF_UNSPEC;
else
hints.ai_family = pref_family;
hints.ai_socktype = SOCK_DGRAM;
- error = getaddrinfo(hosts[a], "123", &hints, tres[a]);
+ error = getaddrinfo(hosts[a], "123", &hints, &tres[resc]);
- if(error) {
+ if (error) {
size_t msg_length = strlen(hosts[a]) + 21;
char *logmsg = (char *) malloc(sizeof(char) * msg_length);
#endif
log_msg(logmsg, 1);
- res[a] = 0;
- }
- else {
- for(dres=*tres[a]; dres; dres=dres->ai_next) {
- entryc++;
-#ifdef DEBUG
+ } else {
+#ifdef DEBUG
+ for (dres = tres[resc]; dres; dres = dres->ai_next) {
getnameinfo(dres->ai_addr, dres->ai_addrlen, adr_buf, sizeof(adr_buf), NULL, 0, NI_NUMERICHOST);
STDLINE
- printf("Resolv No.: %i Result of getaddrinfo for %s:\n", entryc, hosts[a]);
+ printf("Resolv No.: %i Result of getaddrinfo for %s:\n", resc, hosts[a]);
printf("socktype: %i ", dres->ai_socktype);
printf("protocol: %i ", dres->ai_protocol);
printf("Prefered socktype: %i IP: %s\n", dres->ai_socktype, adr_buf);
STDLINE
-#endif
}
- }
- }
-
-#ifdef DEBUG
- printf("Retrieved %i DNS entries, continuing...\n", entryc);
#endif
-
- /* Make a list of the addrinfo list entries, start by counting them */
- struct addrinfo **result = (struct addrinfo **) malloc(sizeof(struct addrinfo**) * entryc);
-
- for(a=0, b=0; a<hostc; a++) {
- struct addrinfo *cur = *tres[a];
-
- if(cur->ai_next == NULL) {
- result[b] = *tres[a];
- }
- else {
- struct addrinfo *seek = *tres[a];
-
- for(; b<entryc && seek; b++) {
- result[b] = seek;
- seek = seek->ai_next;
- }
+ resc++;
}
}
-#ifdef DEBUG
- for(a=0; a<entryc; a++)
- getnameinfo(result[a]->ai_addr, result[a]->ai_addrlen, adr_buf, sizeof(adr_buf), NULL, 0, NI_NUMERICHOST);
-
- printf("%x: IP %s\n", (unsigned int) result[a], adr_buf);
-#endif
-
- *res = (struct addrinfo *) malloc(sizeof(struct addrinfo *) * entryc);
-
- for(a=0; a<entryc; a++)
- res[a] = result[a];
+ /* Make a list of the addrinfo list entries, start by counting them */
+ *res = realloc(tres, sizeof(struct addrinfo *) * resc);
- return entryc;
+ return resc;
}
/* Creates a socket and returns. */
{
GETSOCKNAME_SOCKLEN_TYPE slen;
int recvc;
- int saved_errno;
#ifdef DEBUG
printf("sntp recvdata: Trying to receive data from...\n");
int pkt_len = recv_bcst_data(rsock, rdata, 256, sas, &sender);
- if (pkt_len < 0)
+ if (pkt_len < 0) {
+ free(rdata);
+
return BROADCAST_FAILED;
+ }
/* No MAC, no authentication */
if (LEN_PKT_NOMAC == pkt_len)
else
if(ENABLED_OPT(NORMALVERBOSE)) {
printf("sntp recv_bcst_pkt: Funny packet length: %i. Discarding package.\n", pkt_len);
+ free(rdata);
+
return PACKET_UNUSEABLE;
}
if(ENABLED_OPT(NORMALVERBOSE))
printf("sntp recv_bcst_pkt: Received packet is too big (%i bytes), trying again to get a useFable packet\n",
pkt_len);
+ free(rdata);
return PACKET_UNUSEABLE;
}
else {
if (ENABLED_OPT(NORMALVERBOSE))
printf("sntp recvpkt: Funny packet length: %i. Discarding package.\n", pkt_len);
+ free(rdata);
- return PACKET_UNUSEABLE;
+ return PACKET_UNUSEABLE;
}
/* Packet too big */
if (ENABLED_OPT(NORMALVERBOSE))
printf("sntp recvpkt: Received packet is too big (%i bytes), trying again to get a useable packet\n",
pkt_len);
+ free(rdata);
return PACKET_UNUSEABLE;
}
else
((char *) rpkt)[a] = 0;
+ free(rdata);
+ rdata = NULL;
+
/* MAC could be useable for us */
if (has_mac) {
/* Two more things that the MAC must conform to */
/* From ntpdate.c */
int is_reachable (struct addrinfo *dst);
-int resolve_hosts (char **hosts, int hostc, struct addrinfo **res, int pref_family);
+int resolve_hosts (char **hosts, int hostc, struct addrinfo ***res, int pref_family);
void create_socket (SOCKET *rsock, sockaddr_u *dest);
unsigned char *cpy = (unsigned char *) malloc(sizeof(char) * pkt_length);
+ if (NULL == cpy)
+ return;
+
for(a=0; a<pkt_length; a++)
cpy[a] = ((unsigned char *) dpkg)[a];
fprintf(output, "\n");
fprintf(output, HLINE);
+
+ free(cpy);
}
/* Output a long floating point value in hex in the style described above
};
char *buf = (char *) malloc(sizeof(char) * 48);
-
time_t cur_time = time(NULL);
+ struct tm *tm_ptr;
+
+ if (NULL == buf)
+ return "tv_to_str() malloc(48) failed";
- struct tm *tm_ptr = (struct tm *) malloc(sizeof(struct tm));
tm_ptr = localtime(&cur_time);
/*
* ntp_assert.h - design by contract stuff
+ *
+ * example:
+ *
+ * int foo(char *a) {
+ * int result;
+ * int value;
+ *
+ * NTP_REQUIRE(a != NULL);
+ * ...
+ * bar(&value);
+ * NTP_INSIST(value > 2);
+ * ...
+ *
+ * NTP_ENSURE(result != 12);
+ * return result;
+ * }
+ *
+ * open question: when would we use NTP_INVARIANT()?
*/
-#ifndef NTP_ASSSERT_H
+#ifndef NTP_ASSERT_H
#define NTP_ASSERT_H
# ifdef CALYSTO
extern void calysto_assume(unsigned char cnd); /* assume this always holds */
extern void calysto_assert(unsigned char cnd); /* check whether this holds */
-#define NTP_REQUIRE(x) calysto_assert(x)
-#define NTP_INSIST(x) calysto_assume(x)
-#define NTP_INVARIANT(x) calysto_assume(x)
-#define NTP_ENSURE(x) calysto_assert(x)
-
-# else /* ~CALYSTO */
+#define NTP_REQUIRE(x) calysto_assert(x)
+#define NTP_INSIST(x) calysto_assume(x) /* DLH calysto_assert()? */
+#define NTP_INVARIANT(x) calysto_assume(x)
+#define NTP_ENSURE(x) calysto_assert(x)
+
+# elif defined(__COVERITY__)
+
+/*
+ * Coverity has special knowledge that assert(x) terminates the process
+ * if x is not true. Rather than teach it about our assertion macros,
+ * just use the one it knows about for Coverity Prevent scans. This
+ * means our assertion code (and ISC's) escapes Coverity analysis, but
+ * that seems to be a reasonable trade-off.
+ */
+
+#define NTP_REQUIRE(x) assert(x)
+#define NTP_INSIST(x) assert(x)
+#define NTP_INVARIANT(x) assert(x)
+#define NTP_ENSURE(x) assert(x)
+
+# else /* neither Coverity nor Calysto */
#include "isc/assertions.h"
-#define NTP_REQUIRE(x) ISC_REQUIRE(x)
-#define NTP_INSIST(x) ISC_INSIST(x)
-#define NTP_INVARIANT(x) ISC_INVARIANT(x)
-#define NTP_ENSURE(x) ISC_ENSURE(x)
+#define NTP_REQUIRE(x) ISC_REQUIRE(x)
+#define NTP_INSIST(x) ISC_INSIST(x)
+#define NTP_INVARIANT(x) ISC_INVARIANT(x)
+#define NTP_ENSURE(x) ISC_ENSURE(x)
-# endif /* ~CALYSTO */
-#endif
+# endif /* neither Coverity nor Calysto */
+#endif /* NTP_ASSERT_H */
return(0);
if ((p = getprotobyname("ip")) == NULL)
return(0);
+ memset(&so_addr, 0, sizeof(so_addr));
so_addr.sin_family = AF_INET;
so_addr.sin_port = htons(nmea_port);
so_addr.sin_addr = *((struct in_addr *) he->h_addr);
#include "ntp_select.h"
#include "ntp_io.h"
#include "ntp_stdlib.h"
+#include "ntp_assert.h"
#include "ntp_lineedit.h"
/* Don't include ISC's version of IPv6 variables and structures */
#define ISC_IPV6_H 1
return 0;
}
+ /*
+ * getaddrinfo() has returned without error so ai should not
+ * be NULL.
+ */
+ NTP_INSIST(ai != NULL);
+
if (ai->ai_canonname == NULL) {
strncpy(temphost, stoa((sockaddr_u *)ai->ai_addr),
LENHOSTNAME);
ai->ai_addrlen) == -1)
#endif /* SYS_VXWORKS */
error("connect", "", "");
- if (ai != NULL)
- freeaddrinfo(ai);
+
+ freeaddrinfo(ai);
havehost = 1;
req_pkt_size = REQ_LEN_NOMAC;
impl_ver = IMPL_XNTPD;
RelativePath="..\..\..\include\ntp.h"
>
</File>
+ <File
+ RelativePath="..\..\..\include\ntp_assert.h"
+ >
+ </File>
<File
RelativePath="..\..\..\include\ntp_calendar.h"
>
RelativePath="..\..\..\include\ntp.h"
>
</File>
+ <File
+ RelativePath="..\..\..\include\ntp_assert.h"
+ >
+ </File>
<File
RelativePath="..\..\..\include\ntp_calendar.h"
>
Name="Header Files"
Filter="h;hpp;hxx;hm;inl"
>
+ <File
+ RelativePath="..\..\..\include\ntp_assert.h"
+ >
+ </File>
<File
RelativePath="..\..\..\include\ntp_lineedit.h"
>