From 14b8946f493d3ac02c4468c57fd411b31c4c0894 Mon Sep 17 00:00:00 2001 From: Greg Hudson Date: Tue, 23 Sep 1997 01:58:26 +0000 Subject: From mhpower: avoid possible buffer overflows. --- zhm/queue.c | 6 ++++ zhm/zhm.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++------- zhm/zhm_client.c | 3 +- zhm/zhm_server.c | 19 +++++++----- 4 files changed, 98 insertions(+), 19 deletions(-) (limited to 'zhm') diff --git a/zhm/queue.c b/zhm/queue.c index 5e0ca3a..70de938 100644 --- a/zhm/queue.c +++ b/zhm/queue.c @@ -68,8 +68,14 @@ Code_t add_notice_to_queue(notice, packet, repl, len) DPR("Adding notice to queue...\n"); if (!find_notice_in_queue(notice)) { entry = (Queue *) malloc(sizeof(Queue)); + if (entry == NULL) + return(ZERR_NONOTICE); entry->retries = 0; entry->packet = (char *) malloc(Z_MAXPKTLEN); + if (entry->packet == NULL) { + free(entry); + return(ZERR_NONOTICE); + } memcpy(entry->packet, packet, Z_MAXPKTLEN); if (ZParseNotice(entry->packet, len, &entry->notice) != ZERR_NONE) { syslog(LOG_ERR, "ZParseNotice failed, but succeeded before"); diff --git a/zhm/zhm.c b/zhm/zhm.c index 51a67af..becf936 100644 --- a/zhm/zhm.c +++ b/zhm/zhm.c @@ -120,11 +120,17 @@ char *argv[]; if (optind < argc) { if ((hp = gethostbyname(argv[optind++])) == NULL) { printf("Unknown server name: %s\n", argv[optind-1]); - } else - strcpy(prim_serv, hp->h_name); + } else { + strncpy(prim_serv, hp->h_name, sizeof(prim_serv)); + prim_serv[sizeof(prim_serv) - 1] = '\0'; + } /* argc-optind is the # of other servers on the command line */ serv_list = (char **) malloc((argc - optind + 2) * sizeof(char *)); + if (serv_list == NULL) { + printf("Out of memory.\n"); + exit(-5); + } serv_list[numserv++] = prim_serv; for (; optind < argc; optind++) { if ((hp = gethostbyname(argv[optind])) == NULL) { @@ -267,8 +273,10 @@ static void choose_server() if ((c = strchr(*clust_info, ' ')) == 0) { printf("Hesiod error getting primary server info.\n"); - } else - strcpy(prim_serv, c+1); + } else { + strncpy(prim_serv, c+1, sizeof(prim_serv)); + prim_serv[sizeof(prim_serv) - 1] = '\0'; + } break; } if (!strncasecmp("ZCLUSTER", *clust_info, 9)) { @@ -292,6 +300,10 @@ static void choose_server() if (zcluster == NULL) { if ((zcluster = malloc((unsigned)(strlen("zephyr")+1))) != NULL) strcpy(zcluster, "zephyr"); + else { + printf("Out of memory.\n"); + exit(-5); + } } while ((serv_list = hes_resolve(zcluster, "sloc")) == (char **)NULL) { syslog(LOG_ERR, "No servers or no hesiod"); @@ -299,6 +311,10 @@ static void choose_server() sleep(30); } clust_info = (char **) malloc(2 * sizeof(char *)); + if (clust_info == NULL) { + printf("Out of memory.\n"); + exit(-5); + } if (prim_serv[0]) clust_info[numserv++] = prim_serv; for (i = 0; serv_list[i]; i++) @@ -307,6 +323,10 @@ static void choose_server() if (!prim_serv[0] || strcasecmp(prim_serv, serv_list[i])) { clust_info = (char **) realloc(clust_info, (numserv+2) * sizeof(char *)); + if (clust_info == NULL) { + printf("Out of memory.\n"); + exit(-5); + } clust_info[numserv++] = strsave(serv_list[i]); } clust_info[numserv] = NULL; @@ -316,7 +336,8 @@ static void choose_server() if (!prim_serv[0] && numserv) { srandom(time(NULL)); - strcpy(prim_serv, serv_list[random() % numserv]); + strncpy(prim_serv, serv_list[random() % numserv], sizeof(prim_serv)); + prim_serv[sizeof(prim_serv) - 1] = '\0'; } } @@ -341,8 +362,10 @@ static void init_hm() } init_queue(); - if (*prim_serv == '\0') - strcpy(prim_serv, *serv_list); + if (*prim_serv == '\0') { + strncpy(prim_serv, *serv_list, sizeof(prim_serv)); + prim_serv[sizeof(prim_serv) - 1] = '\0'; + } loopback[0] = 127; loopback[1] = 0; @@ -395,8 +418,9 @@ static void init_hm() find_next_server(NULL); } else { DPR2("Server = %s\n", prim_serv); - strcpy(cur_serv, prim_serv); - memcpy(&serv_sin.sin_addr, hp->h_addr, hp->h_length); + strncpy(cur_serv, prim_serv, sizeof(cur_serv)); + cur_serv[sizeof(cur_serv) - 1] = '\0'; + memcpy(&serv_sin.sin_addr, hp->h_addr, 4); } send_boot_notice(HM_BOOT); @@ -475,23 +499,57 @@ static void send_stats(notice, sin) newnotice.z_kind = HMACK; list[0] = (char *) malloc(MAXHOSTNAMELEN); + if (list[0] == NULL) { + printf("Out of memory.\n"); + exit(-5); + } strcpy(list[0], cur_serv); list[1] = (char *) malloc(64); + if (list[1] == NULL) { + printf("Out of memory.\n"); + exit(-5); + } sprintf(list[1], "%d", queue_len()); list[2] = (char *) malloc(64); + if (list[2] == NULL) { + printf("Out of memory.\n"); + exit(-5); + } sprintf(list[2], "%d", nclt); list[3] = (char *) malloc(64); + if (list[3] == NULL) { + printf("Out of memory.\n"); + exit(-5); + } sprintf(list[3], "%d", nserv); list[4] = (char *) malloc(64); + if (list[4] == NULL) { + printf("Out of memory.\n"); + exit(-5); + } sprintf(list[4], "%d", nservchang); list[5] = (char *) malloc(64); - strcpy(list[5], rcsid_hm_c); + if (list[5] == NULL) { + printf("Out of memory.\n"); + exit(-5); + } + strncpy(list[5], rcsid_hm_c, 64); + list[5][63] = '\0'; + list[6] = (char *) malloc(64); + if (list[6] == NULL) { + printf("Out of memory.\n"); + exit(-5); + } if (no_server) sprintf(list[6], "yes"); else sprintf(list[6], "no"); list[7] = (char *) malloc(64); + if (list[7] == NULL) { + printf("Out of memory.\n"); + exit(-5); + } sprintf(list[7], "%ld", time((time_t *)0) - starttime); #ifdef adjust_size size = (unsigned long)sbrk(0); @@ -500,9 +558,18 @@ static void send_stats(notice, sin) size = -1; #endif list[8] = (char *)malloc(64); + if (list[8] == NULL) { + printf("Out of memory.\n"); + exit(-5); + } sprintf(list[8], "%ld", size); list[9] = (char *)malloc(32); - strcpy(list[9], MACHINE_TYPE); + if (list[9] == NULL) { + printf("Out of memory.\n"); + exit(-5); + } + strncpy(list[9], MACHINE_TYPE, 32); + list[9][31] = '\0'; /* Since ZFormatRaw* won't change the version number on notices, we need to set the version number explicitly. This code is taken diff --git a/zhm/zhm_client.c b/zhm/zhm_client.c index ff7d3ea..d044c60 100644 --- a/zhm/zhm_client.c +++ b/zhm/zhm_client.c @@ -76,7 +76,8 @@ void transmission_tower(notice, packet, pak_len) com_err("hm", ret, "while sending raw notice"); } } - add_notice_to_queue(notice, packet, &gsin, pak_len); + if (add_notice_to_queue(notice, packet, &gsin, pak_len) != ZERR_NONE) + syslog(LOG_INFO, "Hey! Insufficient memory to add notice to queue!"); } Code_t diff --git a/zhm/zhm_server.c b/zhm/zhm_server.c index 760d4c7..0b99253 100644 --- a/zhm/zhm_server.c +++ b/zhm/zhm_server.c @@ -113,7 +113,8 @@ char *sugg_serv; if (done) { if ((hp = gethostbyname(sugg_serv)) != NULL) { DPR2 ("Server = %s\n", sugg_serv); - (void)strcpy(cur_serv, sugg_serv); + (void)strncpy(cur_serv, sugg_serv, MAXHOSTNAMELEN); + cur_serv[MAXHOSTNAMELEN - 1] = '\0'; if (hmdebug) syslog(LOG_DEBUG, "Suggested server: %s\n", sugg_serv); } else { @@ -125,7 +126,8 @@ char *sugg_serv; serv_loop = 0; if ((hp = gethostbyname(prim_serv)) != NULL) { DPR2 ("Server = %s\n", prim_serv); - (void)strcpy(cur_serv, prim_serv); + (void)strncpy(cur_serv, prim_serv, MAXHOSTNAMELEN); + cur_serv[MAXHOSTNAMELEN - 1] = '\0'; done = 1; break; } @@ -135,7 +137,8 @@ char *sugg_serv; case 1: if ((hp = gethostbyname(*serv_list)) != NULL) { DPR2 ("Server = %s\n", *serv_list); - (void)strcpy(cur_serv, *serv_list); + (void)strncpy(cur_serv, *serv_list, MAXHOSTNAMELEN); + cur_serv[MAXHOSTNAMELEN - 1] = '\0'; done = 1; break; } @@ -153,7 +156,8 @@ char *sugg_serv; if ((hp = gethostbyname(new_serv)) != NULL) { DPR2 ("Server = %s\n", new_serv); - (void)strcpy(cur_serv, new_serv); + (void)strncpy(cur_serv, new_serv, MAXHOSTNAMELEN); + cur_serv[MAXHOSTNAMELEN - 1] = '\0'; done = 1; } else sleep(1); @@ -161,7 +165,7 @@ char *sugg_serv; break; } } - (void) memcpy((char *)&serv_sin.sin_addr, hp->h_addr, hp->h_length); + (void) memcpy((char *)&serv_sin.sin_addr, hp->h_addr, 4); nservchang++; } @@ -199,7 +203,7 @@ ZNotice_t *notice; { Code_t ret; struct hostent *hp; - char suggested_server[64]; + char suggested_server[MAXHOSTNAMELEN]; unsigned long addr; DPR("Control message!\n"); @@ -208,7 +212,8 @@ ZNotice_t *notice; addr = inet_addr(notice->z_message); hp = gethostbyaddr((char *) &addr, sizeof(addr), AF_INET); if (hp != NULL) { - strcpy(suggested_server, hp->h_name); + strncpy(suggested_server, hp->h_name, sizeof(suggested_server)); + suggested_server[sizeof(suggested_server) - 1] = '\0'; new_server(suggested_server); } else { new_server(NULL); -- cgit v1.2.3