summaryrefslogtreecommitdiffstats
path: root/ax25/mheard.c
diff options
context:
space:
mode:
authorThomas Osterried <ax25@x-berg.in-berlin.de>2016-07-18 09:39:06 +0200
committerThomas Osterried <ax25@x-berg.in-berlin.de>2016-07-18 09:39:06 +0200
commit123c0266eb95f7a63453d057932b8c56529fc039 (patch)
tree41351449363a3fe7f07fba8d755f65252ef9ee04 /ax25/mheard.c
parentb0fb676d39b3be6e231b86edf348d47888bb26f7 (diff)
fix for segfault issue:
port record data can be garbled. We cannot trust the data. i.e., ctime() returns NULL at time_t 2^33 (72057594037927936). char lh[] was size 30. This is not enough for year > 999999999. also assure that pr->entry.type is < sizeof(types), and in 'case 4:', only up to 8 digipeaters are copied. Thanks to Guido Trentalancia <iz6rdb@trentalancia.net> for the patch. Also changed printf to %u (because mheard's struct has unsigned int values) and enhanced formating (%8 instead of %5). Signed-off-by: Thomas Osterried <ax25@x-berg.in-berlin.de>
Diffstat (limited to 'ax25/mheard.c')
-rw-r--r--ax25/mheard.c82
1 files changed, 60 insertions, 22 deletions
diff --git a/ax25/mheard.c b/ax25/mheard.c
index 92fcf75..2c611e8 100644
--- a/ax25/mheard.c
+++ b/ax25/mheard.c
@@ -41,38 +41,51 @@ static void PrintHeader(int data)
{
switch (data) {
case 0:
- printf("Callsign Port Packets Last Heard\n");
+ printf("Callsign Port Packets Last Heard\n");
break;
case 1:
printf("Callsign Port\n");
break;
case 2:
- printf("Callsign Port #I #S #U First Heard Last Heard\n");
+ printf("Callsign Port #I #S #U First Heard Last Heard\n");
break;
case 3:
- printf("Callsign Port Packets Type PIDs\n");
+ printf("Callsign Port Packets Type PIDs\n");
break;
case 4:
- printf("Callsign Port #I #S #U First Heard Last Heard Packets Type PIDs Targets\n");
+ printf("Callsign Port #I #S #U First Heard Last Heard Packets Type PIDs Targets\n");
break;
}
}
static void PrintPortEntry(struct PortRecord *pr, int data)
{
- char lh[30], fh[30], *call, *s;
+ char *lh, *fh, *call, *s;
char buffer[80];
int i;
+ /* port record data can be garbled. We cannot trust the data.
+ i.e., ctime() returns NULL at time_t 2^33 (72057594037927936).
+ char lh[] was size 30. This is not enough for year > 999999999.
+ also assure that pr->entry.type is < sizeof(types), and in 'case 4:',
+ only up to 8 digipeaters are copied.
+ */
+
switch (data) {
case 0:
- strcpy(lh, ctime(&pr->entry.last_heard));
- lh[19] = 0;
+ if (!pr->entry.count)
+ return;
+ if (pr->entry.last_heard < 0)
+ return;
+ if ((lh = strndup(ctime(&pr->entry.last_heard), 33)) == NULL)
+ return;
+ if (*lh) lh[strlen(lh)-1] = '\0';
call = ax25_ntoa(&pr->entry.from_call);
if ((s = strstr(call, "-0")) != NULL)
*s = '\0';
- printf("%-9s %-5s %5d %s\n",
+ printf("%-9s %-5s %8u %s\n",
call, pr->entry.portname, pr->entry.count, lh);
+ free(lh);
break;
case 1:
buffer[0] = '\0';
@@ -98,21 +111,33 @@ static void PrintPortEntry(struct PortRecord *pr, int data)
buffer, pr->entry.portname);
break;
case 2:
- strcpy(lh, ctime(&pr->entry.last_heard));
- lh[19] = 0;
- strcpy(fh, ctime(&pr->entry.first_heard));
- fh[19] = 0;
+ if (pr->entry.last_heard < 0 || pr->entry.first_heard < 0)
+ return;
+ if ((lh = strndup(ctime(&pr->entry.last_heard), 33)) == NULL)
+ return;
+ if (*lh) lh[strlen(lh)-1] = '\0';
+ if ((fh = strndup(ctime(&pr->entry.first_heard), 33)) == NULL) {
+ free(lh);
+ return;
+ }
+ if (*fh) fh[strlen(fh)-1] = '\0';
call = ax25_ntoa(&pr->entry.from_call);
if ((s = strstr(call, "-0")) != NULL)
*s = '\0';
- printf("%-9s %-5s %5d %5d %5d %s %s\n",
+ printf("%-9s %-5s %8u %8u %8u %s %s\n",
call, pr->entry.portname, pr->entry.iframes, pr->entry.sframes, pr->entry.uframes, fh, lh);
+ free(lh);
+ free(fh);
break;
case 3:
+ if (!pr->entry.count)
+ return;
call = ax25_ntoa(&pr->entry.from_call);
if ((s = strstr(call, "-0")) != NULL)
*s = '\0';
- printf("%-9s %-5s %5d %5s ",
+ if (pr->entry.type < 0 || pr->entry.type > sizeof(types))
+ return;
+ printf("%-9s %-5s %8u %5s ",
call, pr->entry.portname, pr->entry.count, types[pr->entry.type]);
if (pr->entry.mode & MHEARD_MODE_ARP)
printf(" ARP");
@@ -141,16 +166,25 @@ static void PrintPortEntry(struct PortRecord *pr, int data)
printf("\n");
break;
case 4:
- strcpy(lh, ctime(&pr->entry.last_heard));
- lh[19] = 0;
- strcpy(fh, ctime(&pr->entry.first_heard));
- fh[19] = 0;
+ if (!pr->entry.count)
+ return;
+ if (pr->entry.type < 0 || pr->entry.type > sizeof(types))
+ return;
+ if (pr->entry.last_heard < 0 || pr->entry.first_heard < 0)
+ return;
+ if ((lh = strndup(ctime(&pr->entry.last_heard), 33)) == NULL)
+ return;
+ if (*lh) lh[strlen(lh)-1] = '\0';
+ if ((fh = strndup(ctime(&pr->entry.first_heard), 33)) == NULL) {
+ free(lh);
+ return;
+ }
+ if (*fh) fh[strlen(fh)-1] = '\0';
call = ax25_ntoa(&pr->entry.from_call);
if ((s = strstr(call, "-0")) != NULL)
*s = '\0';
- printf("%-9s %-5s %5d %5d %5d %s %s",
- call, pr->entry.portname, pr->entry.iframes, pr->entry.sframes, pr->entry.uframes, fh, lh);
- printf("%5d %5s ", pr->entry.count, types[pr->entry.type]);
+ printf("%-9s %-5s %8u %8u %8u %s %s %8u %5s ",
+ call, pr->entry.portname, pr->entry.iframes, pr->entry.sframes, pr->entry.uframes, fh, lh, pr->entry.count, types[pr->entry.type]);
if (pr->entry.mode & MHEARD_MODE_ARP)
printf(" ARP ");
if (pr->entry.mode & MHEARD_MODE_FLEXNET)
@@ -179,7 +213,7 @@ static void PrintPortEntry(struct PortRecord *pr, int data)
printf(" ");
buffer[0] = '\0';
- for (i = 0; i < pr->entry.ndigis; i++) {
+ for (i = 0; i < pr->entry.ndigis && i < 8; i++) {
if (i)
strcat(buffer, ",");
call = ax25_ntoa(&pr->entry.digis[i]);
@@ -188,6 +222,8 @@ static void PrintPortEntry(struct PortRecord *pr, int data)
strcat(buffer, call);
}
printf("%s\n", buffer);
+ free(lh);
+ free(fh);
break;
}
}
@@ -223,6 +259,8 @@ static void LoadPortData(void)
while (fread(&mheard, sizeof(struct mheard_struct), 1, fp) == 1) {
pr = malloc(sizeof(struct PortRecord));
pr->entry = mheard;
+ /* assure 0-terminated portname in case the record is garbled */
+ pr->entry.portname[19] = '\0';
pr->Next = PortList;
PortList = pr;
}