SCP: Avoid potential buffer overruns by using strlcpy() and strlcat()

This commit is contained in:
Mark Pizzolato 2019-03-08 12:31:01 -08:00
parent 72451ba202
commit c7b0928b33
5 changed files with 35 additions and 33 deletions

4
scp.c
View file

@ -2587,7 +2587,7 @@ setenv ("SIM_REGEX_TYPE", "REGEX", 1); /* Publish regex type */
if (*argv[0]) { /* sim name arg? */ if (*argv[0]) { /* sim name arg? */
char *np; /* "path.ini" */ char *np; /* "path.ini" */
strncpy (nbuf, argv[0], PATH_MAX + 1); /* copy sim name */ strlcpy (nbuf, argv[0], PATH_MAX + 2); /* copy sim name */
if ((np = (char *)match_ext (nbuf, "EXE"))) /* remove .exe */ if ((np = (char *)match_ext (nbuf, "EXE"))) /* remove .exe */
*np = 0; *np = 0;
np = strrchr (nbuf, '/'); /* stript path and try again in cwd */ np = strrchr (nbuf, '/'); /* stript path and try again in cwd */
@ -2618,7 +2618,7 @@ if (*cbuf) /* cmd file arg? */
else if (*argv[0]) { /* sim name arg? */ else if (*argv[0]) { /* sim name arg? */
char *np; /* "path.ini" */ char *np; /* "path.ini" */
nbuf[0] = '"'; /* starting " */ nbuf[0] = '"'; /* starting " */
strncpy (nbuf + 1, argv[0], PATH_MAX + 1); /* copy sim name */ strlcpy (nbuf + 1, argv[0], PATH_MAX + 2); /* copy sim name */
if ((np = (char *)match_ext (nbuf, "EXE"))) /* remove .exe */ if ((np = (char *)match_ext (nbuf, "EXE"))) /* remove .exe */
*np = 0; *np = 0;
strlcat (nbuf, ".ini\"", sizeof (nbuf)); /* add .ini" */ strlcat (nbuf, ".ini\"", sizeof (nbuf)); /* add .ini" */

View file

@ -1489,8 +1489,7 @@ if (sim_switches & SWMASK ('C')) { /* create vhd disk & cop
if (r == SCPE_OK) { if (r == SCPE_OK) {
created = TRUE; created = TRUE;
copied = TRUE; copied = TRUE;
tbuf[sizeof(tbuf)-1] = '\0'; strlcpy (tbuf, gbuf, sizeof(tbuf)-1);
strncpy (tbuf, gbuf, sizeof(tbuf)-1);
cptr = tbuf; cptr = tbuf;
sim_disk_set_fmt (uptr, 0, "VHD", NULL); sim_disk_set_fmt (uptr, 0, "VHD", NULL);
sim_switches = saved_sim_switches; sim_switches = saved_sim_switches;
@ -1564,7 +1563,7 @@ uptr->filename = (char *) calloc (CBUFSIZE, sizeof (char));/* alloc name buf */
uptr->disk_ctx = ctx = (struct disk_context *)calloc(1, sizeof(struct disk_context)); uptr->disk_ctx = ctx = (struct disk_context *)calloc(1, sizeof(struct disk_context));
if ((uptr->filename == NULL) || (uptr->disk_ctx == NULL)) if ((uptr->filename == NULL) || (uptr->disk_ctx == NULL))
return _err_return (uptr, SCPE_MEM); return _err_return (uptr, SCPE_MEM);
strncpy (uptr->filename, cptr, CBUFSIZE); /* save name */ strlcpy (uptr->filename, cptr, CBUFSIZE); /* save name */
ctx->sector_size = (uint32)sector_size; /* save sector_size */ ctx->sector_size = (uint32)sector_size; /* save sector_size */
ctx->capac_factor = ((dptr->dwidth / dptr->aincr) == 16) ? 2 : 1; /* save capacity units (word: 2, byte: 1) */ ctx->capac_factor = ((dptr->dwidth / dptr->aincr) == 16) ? 2 : 1; /* save capacity units (word: 2, byte: 1) */
ctx->xfer_element_size = (uint32)xfer_element_size; /* save xfer_element_size */ ctx->xfer_element_size = (uint32)xfer_element_size; /* save xfer_element_size */
@ -3489,8 +3488,10 @@ if ((sDynamic) &&
if ((0 == memcmp (sDynamic->ParentUniqueID, sParentFooter.UniqueID, sizeof (sParentFooter.UniqueID))) && if ((0 == memcmp (sDynamic->ParentUniqueID, sParentFooter.UniqueID, sizeof (sParentFooter.UniqueID))) &&
((sDynamic->ParentTimeStamp == ParentModificationTime) || ((sDynamic->ParentTimeStamp == ParentModificationTime) ||
((NtoHl(sDynamic->ParentTimeStamp)-NtoHl(ParentModificationTime)) == 3600) || ((NtoHl(sDynamic->ParentTimeStamp)-NtoHl(ParentModificationTime)) == 3600) ||
(sim_switches & SWMASK ('O')))) (sim_switches & SWMASK ('O')))) {
strncpy (szParentVHDPath, CheckPath, ParentVHDPathSize); memset (szParentVHDPath, 0, ParentVHDPathSize);
strlcpy (szParentVHDPath, CheckPath, ParentVHDPathSize);
}
else { else {
if (0 != memcmp (sDynamic->ParentUniqueID, sParentFooter.UniqueID, sizeof (sParentFooter.UniqueID))) if (0 != memcmp (sDynamic->ParentUniqueID, sParentFooter.UniqueID, sizeof (sParentFooter.UniqueID)))
sim_printf ("Error Invalid Parent VHD '%s' for Differencing VHD: %s\n", CheckPath, szVHDPath); sim_printf ("Error Invalid Parent VHD '%s' for Differencing VHD: %s\n", CheckPath, szVHDPath);
@ -4092,7 +4093,7 @@ char *wd = getcwd(buffer, PATH_MAX);
if ((szFileSpec[0] != '/') || (strchr (szFileSpec, ':'))) if ((szFileSpec[0] != '/') || (strchr (szFileSpec, ':')))
snprintf (szFullFileSpecBuffer, BufferSize, "%s/%s", wd, szFileSpec); snprintf (szFullFileSpecBuffer, BufferSize, "%s/%s", wd, szFileSpec);
else else
strncpy (szFullFileSpecBuffer, szFileSpec, BufferSize); strlcpy (szFullFileSpecBuffer, szFileSpec, BufferSize);
if ((c = strstr (szFullFileSpecBuffer, "]/"))) if ((c = strstr (szFullFileSpecBuffer, "]/")))
memmove (c+1, c+2, strlen(c+2)+1); memmove (c+1, c+2, strlen(c+2)+1);
memset (szFullFileSpecBuffer + strlen (szFullFileSpecBuffer), 0, BufferSize - strlen (szFullFileSpecBuffer)); memset (szFullFileSpecBuffer + strlen (szFullFileSpecBuffer), 0, BufferSize - strlen (szFullFileSpecBuffer));
@ -4106,7 +4107,8 @@ HostPathToVhdPath (const char *szHostPath,
{ {
char *c, *d; char *c, *d;
strncpy (szVhdPath, szHostPath, VhdPathSize-1); memset (szVhdPath, 0, VhdPathSize);
strlcpy (szVhdPath, szHostPath, VhdPathSize-1);
if ((szVhdPath[1] == ':') && islower(szVhdPath[0])) if ((szVhdPath[1] == ':') && islower(szVhdPath[0]))
szVhdPath[0] = toupper(szVhdPath[0]); szVhdPath[0] = toupper(szVhdPath[0]);
szVhdPath[VhdPathSize-1] = '\0'; szVhdPath[VhdPathSize-1] = '\0';

View file

@ -416,14 +416,14 @@ t_stat eth_mac_scan_ex (ETH_MAC* mac, const char* strmac, UNIT *uptr)
memset (&state, 0, sizeof(state)); memset (&state, 0, sizeof(state));
_eth_get_system_id (state.system_id, sizeof(state.system_id)); _eth_get_system_id (state.system_id, sizeof(state.system_id));
strncpy (state.sim, sim_name, sizeof(state.sim)); strlcpy (state.sim, sim_name, sizeof(state.sim));
getcwd (state.cwd, sizeof(state.cwd)); getcwd (state.cwd, sizeof(state.cwd));
if (uptr) if (uptr)
strncpy (state.uname, sim_uname (uptr), sizeof(state.uname)-1); strlcpy (state.uname, sim_uname (uptr), sizeof(state.uname));
cptr = strchr (strmac, '>'); cptr = strchr (strmac, '>');
if (cptr) { if (cptr) {
state.file[sizeof(state.file)-1] = '\0'; state.file[sizeof(state.file)-1] = '\0';
strncpy (state.file, cptr + 1, sizeof(state.file)-1); strlcpy (state.file, cptr + 1, sizeof(state.file));
if ((f = fopen (state.file, "r"))) { if ((f = fopen (state.file, "r"))) {
filebuf[sizeof(filebuf)-1] = '\0'; filebuf[sizeof(filebuf)-1] = '\0';
fgets (filebuf, sizeof(filebuf)-1, f); fgets (filebuf, sizeof(filebuf)-1, f);
@ -2014,7 +2014,7 @@ if (0 == strncmp("tap:", savname, 4)) {
/* Send interface requests to TUN/TAP driver. */ /* Send interface requests to TUN/TAP driver. */
if (ioctl(tun, TUNSETIFF, &ifr) >= 0) { if (ioctl(tun, TUNSETIFF, &ifr) >= 0) {
if (ioctl(tun, FIONBIO, &on)) { if (ioctl(tun, FIONBIO, &on)) {
strncpy(errbuf, strerror(errno), PCAP_ERRBUF_SIZE-1); strlcpy(errbuf, strerror(errno), PCAP_ERRBUF_SIZE);
close(tun); close(tun);
} }
else { else {
@ -2023,10 +2023,10 @@ if (0 == strncmp("tap:", savname, 4)) {
} }
} }
else else
strncpy(errbuf, strerror(errno), PCAP_ERRBUF_SIZE-1); strlcpy(errbuf, strerror(errno), PCAP_ERRBUF_SIZE);
} }
else else
strncpy(errbuf, strerror(errno), PCAP_ERRBUF_SIZE-1); strlcpy(errbuf, strerror(errno), PCAP_ERRBUF_SIZE);
#elif defined(HAVE_BSDTUNTAP) && defined(HAVE_TAP_NETWORK) #elif defined(HAVE_BSDTUNTAP) && defined(HAVE_TAP_NETWORK)
if (1) { if (1) {
char dev_name[64] = ""; char dev_name[64] = "";
@ -2036,7 +2036,7 @@ if (0 == strncmp("tap:", savname, 4)) {
if ((tun = open(dev_name, O_RDWR)) >= 0) { if ((tun = open(dev_name, O_RDWR)) >= 0) {
if (ioctl(tun, FIONBIO, &on)) { if (ioctl(tun, FIONBIO, &on)) {
strncpy(errbuf, strerror(errno), PCAP_ERRBUF_SIZE-1); strlcpy(errbuf, strerror(errno), PCAP_ERRBUF_SIZE);
close(tun); close(tun);
} }
else { else {
@ -2050,12 +2050,12 @@ if (0 == strncmp("tap:", savname, 4)) {
memset (&ifr, 0, sizeof(ifr)); memset (&ifr, 0, sizeof(ifr));
ifr.ifr_addr.sa_family = AF_INET; ifr.ifr_addr.sa_family = AF_INET;
strncpy(ifr.ifr_name, savname, sizeof(ifr.ifr_name)); strlcpy(ifr.ifr_name, savname, sizeof(ifr.ifr_name));
if ((s = socket(AF_INET, SOCK_DGRAM, 0)) >= 0) { if ((s = socket(AF_INET, SOCK_DGRAM, 0)) >= 0) {
if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) >= 0) { if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) >= 0) {
ifr.ifr_flags |= IFF_UP; ifr.ifr_flags |= IFF_UP;
if (ioctl(s, SIOCSIFFLAGS, (caddr_t)&ifr)) { if (ioctl(s, SIOCSIFFLAGS, (caddr_t)&ifr)) {
strncpy(errbuf, strerror(errno), PCAP_ERRBUF_SIZE-1); strlcpy(errbuf, strerror(errno), PCAP_ERRBUF_SIZE);
close(tun); close(tun);
} }
} }
@ -2065,10 +2065,10 @@ if (0 == strncmp("tap:", savname, 4)) {
#endif #endif
} }
else else
strncpy(errbuf, strerror(errno), PCAP_ERRBUF_SIZE-1); strlcpy(errbuf, strerror(errno), PCAP_ERRBUF_SIZE);
} }
#else #else
strncpy(errbuf, "No support for tap: devices", PCAP_ERRBUF_SIZE-1); strlcpy(errbuf, "No support for tap: devices", PCAP_ERRBUF_SIZE);
#endif /* !defined(__linux) && !defined(HAVE_BSDTUNTAP) */ #endif /* !defined(__linux) && !defined(HAVE_BSDTUNTAP) */
if (0 == errbuf[0]) { if (0 == errbuf[0]) {
*eth_api = ETH_API_TAP; *eth_api = ETH_API_TAP;
@ -2101,13 +2101,13 @@ else { /* !tap: */
} }
if (!(*handle = (void*) vde_open((char *)vdeswitch_s, (char *)"simh", &voa))) if (!(*handle = (void*) vde_open((char *)vdeswitch_s, (char *)"simh", &voa)))
strncpy(errbuf, strerror(errno), PCAP_ERRBUF_SIZE-1); strlcpy(errbuf, strerror(errno), PCAP_ERRBUF_SIZE);
else { else {
*eth_api = ETH_API_VDE; *eth_api = ETH_API_VDE;
*fd_handle = vde_datafd((VDECONN*)(*handle)); *fd_handle = vde_datafd((VDECONN*)(*handle));
} }
#else #else
strncpy(errbuf, "No support for vde: network devices", PCAP_ERRBUF_SIZE-1); strlcpy(errbuf, "No support for vde: network devices", PCAP_ERRBUF_SIZE);
#endif /* defined(HAVE_VDE_NETWORK) */ #endif /* defined(HAVE_VDE_NETWORK) */
} }
else { /* !vde: */ else { /* !vde: */
@ -2118,13 +2118,13 @@ else { /* !tap: */
while (isspace(*devname)) while (isspace(*devname))
++devname; ++devname;
if (!(*handle = (void*) sim_slirp_open(devname, opaque, &_slirp_callback, dptr, dbit))) if (!(*handle = (void*) sim_slirp_open(devname, opaque, &_slirp_callback, dptr, dbit)))
strncpy(errbuf, strerror(errno), PCAP_ERRBUF_SIZE-1); strlcpy(errbuf, strerror(errno), PCAP_ERRBUF_SIZE);
else { else {
*eth_api = ETH_API_NAT; *eth_api = ETH_API_NAT;
*fd_handle = 0; *fd_handle = 0;
} }
#else #else
strncpy(errbuf, "No support for nat: network devices", PCAP_ERRBUF_SIZE-1); strlcpy(errbuf, "No support for nat: network devices", PCAP_ERRBUF_SIZE);
#endif /* defined(HAVE_SLIRP_NETWORK) */ #endif /* defined(HAVE_SLIRP_NETWORK) */
} }
else { /* not nat: */ else { /* not nat: */
@ -2204,7 +2204,7 @@ else { /* !tap: */
#endif /* defined (__APPLE__) */ #endif /* defined (__APPLE__) */
#endif /* !defined (USE_READER_THREAD) */ #endif /* !defined (USE_READER_THREAD) */
#else #else
strncpy (errbuf, "Unknown or unsupported network device", PCAP_ERRBUF_SIZE-1); strlcpy (errbuf, "Unknown or unsupported network device", PCAP_ERRBUF_SIZE);
#endif /* defined(HAVE_PCAP_NETWORK) */ #endif /* defined(HAVE_PCAP_NETWORK) */
} /* not udp:, so attempt to open the parameter as if it were an explicit device name */ } /* not udp:, so attempt to open the parameter as if it were an explicit device name */
} /* !nat: */ } /* !nat: */
@ -4033,11 +4033,11 @@ else {
/* copy device list into the passed structure */ /* copy device list into the passed structure */
for (i=0, dev=alldevs; dev && (i < max); dev=dev->next, ++i) { for (i=0, dev=alldevs; dev && (i < max); dev=dev->next, ++i) {
if ((dev->flags & PCAP_IF_LOOPBACK) || (!strcmp("any", dev->name))) continue; if ((dev->flags & PCAP_IF_LOOPBACK) || (!strcmp("any", dev->name))) continue;
strncpy(list[i].name, dev->name, sizeof(list[i].name)-1); strlcpy(list[i].name, dev->name, sizeof(list[i].name));
if (dev->description) if (dev->description)
strncpy(list[i].desc, dev->description, sizeof(list[i].desc)-1); strlcpy(list[i].desc, dev->description, sizeof(list[i].desc));
else else
strncpy(list[i].desc, "No description available", sizeof(list[i].desc)-1); strlcpy(list[i].desc, "No description available", sizeof(list[i].desc));
} }
/* free device list */ /* free device list */

View file

@ -187,9 +187,9 @@ serial_open_devices = (struct open_serial_device *)realloc(serial_open_devices,
memset(&serial_open_devices[serial_open_device_count-1], 0, sizeof(serial_open_devices[serial_open_device_count-1])); memset(&serial_open_devices[serial_open_device_count-1], 0, sizeof(serial_open_devices[serial_open_device_count-1]));
serial_open_devices[serial_open_device_count-1].port = port; serial_open_devices[serial_open_device_count-1].port = port;
serial_open_devices[serial_open_device_count-1].line = line; serial_open_devices[serial_open_device_count-1].line = line;
strncpy(serial_open_devices[serial_open_device_count-1].name, name, sizeof(serial_open_devices[serial_open_device_count-1].name)-1); strlcpy(serial_open_devices[serial_open_device_count-1].name, name, sizeof(serial_open_devices[serial_open_device_count-1].name));
if (config) if (config)
strncpy(serial_open_devices[serial_open_device_count-1].config, config, sizeof(serial_open_devices[serial_open_device_count-1].config)-1); strlcpy(serial_open_devices[serial_open_device_count-1].config, config, sizeof(serial_open_devices[serial_open_device_count-1].config));
return &serial_open_devices[serial_open_device_count-1]; return &serial_open_devices[serial_open_device_count-1];
} }

View file

@ -1656,9 +1656,9 @@ if (vid_flags & SIM_VID_INPUTCAPTURED) {
char title[150]; char title[150];
memset (title, 0, sizeof(title)); memset (title, 0, sizeof(title));
strncpy (title, vid_title, sizeof(title)-1); strlcpy (title, vid_title, sizeof(title));
strncat (title, " ReleaseKey=", sizeof(title)-(1+strlen(title))); strlcat (title, " ReleaseKey=", sizeof(title));
strncat (title, vid_release_key, sizeof(title)-(1+strlen(title))); strlcat (title, vid_release_key, sizeof(title));
#if SDL_MAJOR_VERSION == 1 #if SDL_MAJOR_VERSION == 1
SDL_WM_SetCaption (title, title); SDL_WM_SetCaption (title, title);
#else #else