Fix several Coverity warnings in tftp

Some of the changes are in the libexec/tftpd directory, but to functions that
are only used by tftp(1) (they share some code).

* strcpy => strlcpy (1006793, 1006794, 1006796, 1006741)
* Unchecked return value and TOCTTOU (1009314)
* NULL pointer dereference (1018035, 1018036)

Reported by:	Coverity
CID:		1006793, 1006794, 1006796, 1006741, 1009314, 1018035
CID:		1018036
MFC after:	2 weeks
This commit is contained in:
asomers 2018-07-22 17:10:12 +00:00
parent d8db86d619
commit 1fe29e8908
4 changed files with 23 additions and 12 deletions

View File

@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$");
#include <errno.h> #include <errno.h>
#include <setjmp.h> #include <setjmp.h>
#include <signal.h> #include <signal.h>
#include <stddef.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -193,16 +194,16 @@ send_wrq(int peer, char *filename, char *mode)
tp = (struct tftphdr *)buf; tp = (struct tftphdr *)buf;
tp->th_opcode = htons((u_short)WRQ); tp->th_opcode = htons((u_short)WRQ);
size = 2; size = offsetof(struct tftphdr, th_stuff);
bp = tp->th_stuff; bp = tp->th_stuff;
strcpy(bp, filename); strlcpy(bp, filename, sizeof(buf) - size);
bp += strlen(filename); bp += strlen(filename);
*bp = 0; *bp = 0;
bp++; bp++;
size += strlen(filename) + 1; size += strlen(filename) + 1;
strcpy(bp, mode); strlcpy(bp, mode, sizeof(buf) - size);
bp += strlen(mode); bp += strlen(mode);
*bp = 0; *bp = 0;
bp++; bp++;
@ -241,16 +242,16 @@ send_rrq(int peer, char *filename, char *mode)
tp = (struct tftphdr *)buf; tp = (struct tftphdr *)buf;
tp->th_opcode = htons((u_short)RRQ); tp->th_opcode = htons((u_short)RRQ);
size = 2; size = offsetof(struct tftphdr, th_stuff);
bp = tp->th_stuff; bp = tp->th_stuff;
strcpy(bp, filename); strlcpy(bp, filename, sizeof(buf) - size);
bp += strlen(filename); bp += strlen(filename);
*bp = 0; *bp = 0;
bp++; bp++;
size += strlen(filename) + 1; size += strlen(filename) + 1;
strcpy(bp, mode); strlcpy(bp, mode, sizeof(buf) - size);
bp += strlen(mode); bp += strlen(mode);
*bp = 0; *bp = 0;
bp++; bp++;

View File

@ -237,14 +237,15 @@ const char *
debug_show(int d) debug_show(int d)
{ {
static char s[100]; static char s[100];
size_t space = sizeof(s);
int i = 0; int i = 0;
s[0] = '\0'; s[0] = '\0';
while (debugs[i].name != NULL) { while (debugs[i].name != NULL) {
if (d&debugs[i].value) { if (d&debugs[i].value) {
if (s[0] != '\0') if (s[0] != '\0')
strcat(s, " "); strlcat(s, " ", space);
strcat(s, debugs[i].name); strlcat(s, debugs[i].name, space);
} }
i++; i++;
} }

View File

@ -429,7 +429,7 @@ static void
settftpmode(const char *newmode) settftpmode(const char *newmode)
{ {
strcpy(mode, newmode); strlcpy(mode, newmode, sizeof(mode));
if (verbose) if (verbose)
printf("mode set to %s\n", mode); printf("mode set to %s\n", mode);
} }
@ -489,7 +489,10 @@ put(int argc, char *argv[])
return; return;
} }
stat(cp, &sb); if (fstat(fd, &sb) < 0) {
warn("%s", cp);
return;
}
asprintf(&options[OPT_TSIZE].o_request, "%ju", sb.st_size); asprintf(&options[OPT_TSIZE].o_request, "%ju", sb.st_size);
if (verbose) if (verbose)
@ -510,7 +513,10 @@ put(int argc, char *argv[])
continue; continue;
} }
stat(cp, &sb); if (fstat(fd, &sb) < 0) {
warn("%s", argv[n]);
continue;
}
asprintf(&options[OPT_TSIZE].o_request, "%ju", sb.st_size); asprintf(&options[OPT_TSIZE].o_request, "%ju", sb.st_size);
if (verbose) if (verbose)

View File

@ -50,6 +50,7 @@ __FBSDID("$FreeBSD$");
#include <arpa/tftp.h> #include <arpa/tftp.h>
#include <assert.h>
#include <err.h> #include <err.h>
#include <netdb.h> #include <netdb.h>
#include <stdio.h> #include <stdio.h>
@ -85,6 +86,7 @@ xmitfile(int peer, char *port, int fd, char *name, char *mode)
if (port == NULL) { if (port == NULL) {
struct servent *se; struct servent *se;
se = getservbyname("tftp", "udp"); se = getservbyname("tftp", "udp");
assert(se != NULL);
((struct sockaddr_in *)&peer_sock)->sin_port = se->s_port; ((struct sockaddr_in *)&peer_sock)->sin_port = se->s_port;
} else } else
((struct sockaddr_in *)&peer_sock)->sin_port = ((struct sockaddr_in *)&peer_sock)->sin_port =
@ -184,6 +186,7 @@ recvfile(int peer, char *port, int fd, char *name, char *mode)
if (port == NULL) { if (port == NULL) {
struct servent *se; struct servent *se;
se = getservbyname("tftp", "udp"); se = getservbyname("tftp", "udp");
assert(se != NULL);
((struct sockaddr_in *)&peer_sock)->sin_port = se->s_port; ((struct sockaddr_in *)&peer_sock)->sin_port = se->s_port;
} else } else
((struct sockaddr_in *)&peer_sock)->sin_port = ((struct sockaddr_in *)&peer_sock)->sin_port =