Skip to content

Commit 3ed4915

Browse files
authored
Merge pull request networkupstools#3253 from jimklimov/fix-strcpy
Further removal of unbounded `strcpy()` usage
2 parents e06b8ae + 028827c commit 3ed4915

30 files changed

+325
-291
lines changed

NEWS.adoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ https://github.com/networkupstools/nut/milestone/12
5858
other too. [issue #3136]
5959
* Improved high-verbosity debug tracing of NUT `libhid` and `usbhid-ups`
6060
to help make sense of data processing issues (HID paths, strings). [#3201]
61+
* Further removal of unbounded `strcpy()` and `sprintf()` usage. [#3253]
6162
* For state tree methods, introduced `difftime_st_tree_timespec()` to
6263
abstract platform-dependent definitions of `st_tree_timespec_t`. [PR #3156]
6364
* Introduced global variables for last changed timestamp and value of

clients/upsmon.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -233,19 +233,21 @@ static void wall(const char *text)
233233
pclose(wf);
234234
#else /* WIN32 */
235235
# define MESSAGE_CMD "message.exe"
236-
char * command;
236+
char *command;
237237

238238
/* first +1 is for the space between message and text
239239
second +1 is for trailing 0
240240
+2 is for "" */
241-
command = malloc (strlen(MESSAGE_CMD) + 1 + 2 + strlen(text) + 1);
242-
if( command == NULL ) {
241+
size_t commandsz = strlen(MESSAGE_CMD) + 1 + 2 + strlen(text) + 1;
242+
243+
command = malloc (commandsz);
244+
if (command == NULL) {
243245
upslog_with_errno(LOG_NOTICE, "Not enough memory for wall");
244246
return;
245247
}
246248

247-
sprintf(command,"%s \"%s\"",MESSAGE_CMD,text);
248-
if ( system(command) != 0 ) {
249+
snprintf(command, commandsz, "%s \"%s\"", MESSAGE_CMD, text);
250+
if (system(command) != 0) {
249251
upslog_with_errno(LOG_NOTICE, "Can't invoke wall");
250252
}
251253
free(command);

clients/upsstats.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -633,7 +633,7 @@ static void do_ifeq(const char *s)
633633

634634
upsdebug_call_starting_for_str1(s);
635635

636-
strcpy(var, s);
636+
strncpy(var, s, sizeof(var) - 1);
637637

638638
nargs = breakargs(var, aa);
639639
if(nargs != 2) {
@@ -659,7 +659,7 @@ static void do_ifbetween(const char *s)
659659

660660
upsdebug_call_starting_for_str1(s);
661661

662-
strcpy(var, s);
662+
strncpy(var, s, sizeof(var) - 1);
663663

664664
nargs = breakargs(var, aa);
665665
if (nargs != 3) {

common/setenv.c

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
/* setenv.c Ben Collver <collver@softhome.net> */
1+
/* fallback setenv.c Ben Collver <collver@softhome.net>
2+
* tightened by Jim Klimov <jimklimov+nut@gmail.com>
3+
*/
24
#include "config.h" /* must be first */
35

46
#ifndef HAVE_SETENV
@@ -10,6 +12,7 @@ int nut_setenv(const char *name, const char *value, int overwrite)
1012
{
1113
char *val;
1214
char *buffer;
15+
size_t buflen = 0;
1316
int rv;
1417

1518
if (overwrite == 0) {
@@ -19,10 +22,15 @@ int nut_setenv(const char *name, const char *value, int overwrite)
1922
}
2023
}
2124

22-
buffer = xmalloc(strlen(value) + strlen(name) + 2);
23-
strcpy(buffer, name);
24-
strcat(buffer, "=");
25-
strcat(buffer, value);
25+
buflen = strlen(value) + strlen(name) + 2;
26+
buffer = xmalloc(buflen);
27+
/* TOTHINK: is this stack more portable than one command?
28+
* snprintf(buffer, buflen, "%s=%s", name, value);
29+
* (also can easily check that we got (buflen-1) as return value)
30+
*/
31+
strncpy(buffer, name, buflen);
32+
strncat(buffer, "=", buflen);
33+
strncat(buffer, value, buflen);
2634
rv = putenv(buffer); /* man putenv, do not free(buffer) */
2735
return (rv);
2836
}

docs/nut.dict

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
personal_ws-1.1 en 3626 utf-8
1+
personal_ws-1.1 en 3627 utf-8
22
AAC
33
AAS
44
ABI
@@ -3183,6 +3183,7 @@ spellcheck
31833183
spellchecked
31843184
splitaddr
31853185
splitname
3186+
sprintf
31863187
squasher
31873188
sr
31883189
src

drivers/adelsystem_cbi.c

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
#endif
3535

3636
#define DRIVER_NAME "NUT ADELSYSTEM DC-UPS CB/CBI driver (libmodbus link type: " NUT_MODBUS_LINKTYPE_STR ")"
37-
#define DRIVER_VERSION "0.06"
37+
#define DRIVER_VERSION "0.07"
3838

3939
/* variables */
4040
static modbus_t *mbctx = NULL; /* modbus memory context */
@@ -951,18 +951,20 @@ int get_dev_state(devreg_t regindx, devstate_t **dvstat)
951951
case LVDC: /* "output.voltage" */
952952
case LCUR: /* "output.current" */
953953
if (reg_val != 0) {
954-
char *fval_s;
955954
double fval;
955+
char *fval_s;
956+
size_t fval_sz;
956957

957958
state->reg.val.ui16 = reg_val;
958959
fval = reg_val / 1000.00; /* convert mV to V, mA to A */
959960
n = snprintf(NULL, 0, "%.2f", fval);
960961
if (ptr != NULL) {
961962
free(ptr);
962963
}
963-
fval_s = (char *)xmalloc(sizeof(char) * (n + 1));
964+
fval_sz = sizeof(char) * (n + 1);
965+
fval_s = (char *)xmalloc(fval_sz);
964966
ptr = fval_s;
965-
sprintf(fval_s, "%.2f", fval);
967+
snprintf(fval_s, fval_sz, "%.2f", fval);
966968
state->reg.strval = fval_s;
967969
} else {
968970
state->reg.val.ui16 = 0;
@@ -976,15 +978,17 @@ int get_dev_state(devreg_t regindx, devstate_t **dvstat)
976978
case VAC: /* "input.voltage" */
977979
if (reg_val != 0) {
978980
char *reg_val_s;
981+
size_t reg_val_sz;
979982

980983
state->reg.val.ui16 = reg_val;
981984
n = snprintf(NULL, 0, "%u", reg_val);
982985
if (ptr != NULL) {
983986
free(ptr);
984987
}
985-
reg_val_s = (char *)xmalloc(sizeof(char) * (n + 1));
988+
reg_val_sz = sizeof(char) * (n + 1);
989+
reg_val_s = (char *)xmalloc(reg_val_sz);
986990
ptr = reg_val_s;
987-
sprintf(reg_val_s, "%u", reg_val);
991+
snprintf(reg_val_s, reg_val_sz, "%u", reg_val);
988992
state->reg.strval = reg_val_s;
989993
} else {
990994
state->reg.val.ui16 = 0;
@@ -996,16 +1000,18 @@ int get_dev_state(devreg_t regindx, devstate_t **dvstat)
9961000
if (reg_val != 0) {
9971001
double fval;
9981002
char *fval_s;
1003+
size_t fval_sz;
9991004

10001005
state->reg.val.ui16 = reg_val;
10011006
fval = (double )reg_val * regs[BSOC].scale;
10021007
n = snprintf(NULL, 0, "%.2f", fval);
10031008
if (ptr != NULL) {
10041009
free(ptr);
10051010
}
1006-
fval_s = (char *)xmalloc(sizeof(char) * (n + 1));
1011+
fval_sz = sizeof(char) * (n + 1);
1012+
fval_s = (char *)xmalloc(fval_sz);
10071013
ptr = fval_s;
1008-
sprintf(fval_s, "%.2f", fval);
1014+
snprintf(fval_s, fval_sz, "%.2f", fval);
10091015
state->reg.strval = fval_s;
10101016
} else {
10111017
state->reg.val.ui16 = 0;
@@ -1018,16 +1024,18 @@ int get_dev_state(devreg_t regindx, devstate_t **dvstat)
10181024
{ /* scoping */
10191025
double fval;
10201026
char *fval_s;
1027+
size_t fval_sz;
10211028

10221029
state->reg.val.ui16 = reg_val;
10231030
fval = reg_val - 273.15;
10241031
n = snprintf(NULL, 0, "%.2f", fval);
1025-
fval_s = (char *)xmalloc(sizeof(char) * (n + 1));
1032+
fval_sz = sizeof(char) * (n + 1);
1033+
fval_s = (char *)xmalloc(fval_sz);
10261034
if (ptr != NULL) {
10271035
free(ptr);
10281036
}
10291037
ptr = fval_s;
1030-
sprintf(fval_s, "%.2f", fval);
1038+
snprintf(fval_s, fval_sz, "%.2f", fval);
10311039
state->reg.strval = fval_s;
10321040
}
10331041
upsdebugx(3, "get_dev_state: variable: %s", state->reg.strval);
@@ -1221,14 +1229,17 @@ int get_dev_state(devreg_t regindx, devstate_t **dvstat)
12211229
default:
12221230
{ /* scoping */
12231231
char *reg_val_s;
1232+
size_t reg_val_sz;
1233+
12241234
state->reg.val.ui16 = reg_val;
12251235
n = snprintf(NULL, 0, "%u", reg_val);
12261236
if (ptr != NULL) {
12271237
free(ptr);
12281238
}
1229-
reg_val_s = (char *)xmalloc(sizeof(char) * (n + 1));
1239+
reg_val_sz = sizeof(char) * (n + 1);
1240+
reg_val_s = (char *)xmalloc(reg_val_sz);
12301241
ptr = reg_val_s;
1231-
sprintf(reg_val_s, "%u", reg_val);
1242+
snprintf(reg_val_s, reg_val_sz, "%u", reg_val);
12321243
state->reg.strval = reg_val_s;
12331244
}
12341245
break;
@@ -1326,7 +1337,7 @@ modbus_t *modbus_new(const char *port)
13261337
}
13271338
} else if ((sp = strchr(port, ':')) != NULL) {
13281339
char *tcp_port = xmalloc(sizeof(sp));
1329-
strcpy(tcp_port, sp + 1);
1340+
strncpy(tcp_port, sp + 1, sizeof(sp));
13301341
*sp = '\0';
13311342
mb = modbus_new_tcp(port, (int)strtoul(tcp_port, NULL, 10));
13321343
if (mb == NULL) {

drivers/bcmxcp_usb.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
#include <unistd.h>
1212

1313
#define SUBDRIVER_NAME "USB communication subdriver"
14-
#define SUBDRIVER_VERSION "0.27"
14+
#define SUBDRIVER_VERSION "0.28"
1515

1616
/* communication driver description structure */
1717
upsdrv_info_t comm_upsdrv_info = {
@@ -448,7 +448,7 @@ static usb_dev_handle *open_powerware_usb(void)
448448
libusb_free_device_list(devlist, 1);
449449
fatal_with_errno(EXIT_FAILURE, "Out of memory");
450450
}
451-
sprintf(curDevice.Bus, "%03d", bus_num);
451+
snprintf(curDevice.Bus, 4, "%03d", bus_num);
452452

453453
/* FIXME: we should also retrieve
454454
* dev->descriptor.iManufacturer

drivers/belkinunv.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@
9494
#include "serial.h"
9595

9696
#define DRIVER_NAME "Belkin 'Universal UPS' driver"
97-
#define DRIVER_VERSION "0.13"
97+
#define DRIVER_VERSION "0.14"
9898

9999
/* driver description structure */
100100
upsdrv_info_t upsdrv_info = {
@@ -759,7 +759,7 @@ static void updatestatus(int smode, const char *fmt, ...) {
759759
if (strcmp(oldbuf, buf)==0) {
760760
return;
761761
}
762-
strcpy(oldbuf, buf);
762+
strncpy(oldbuf, buf, sizeof(oldbuf));
763763

764764
if (smode==2) {
765765
/* "dumbterm" version just prints a new line each time */

drivers/generic_gpio_libgpiod.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
#endif
3232

3333
#define DRIVER_NAME "GPIO UPS driver (API " WITH_LIBGPIO_VERSION_STR ")"
34-
#define DRIVER_VERSION "1.05"
34+
#define DRIVER_VERSION "1.06"
3535

3636
/* driver description structure */
3737
upsdrv_info_t upsdrv_info = {
@@ -128,9 +128,10 @@ void gpio_open(struct gpioups_t *gpioupsfdlocal) {
128128
libgpiod_data->gpioChipHandle = gpiod_chip_open_by_name(gpioupsfdlocal->chipName);
129129
#else /* #if WITH_LIBGPIO_VERSION >= 0x00020000 */
130130
if(!strchr(gpioupsfdlocal->chipName, '/')) {
131-
char *pathName = xcalloc(strlen(gpioupsfdlocal->chipName)+6, sizeof(char));
132-
strcpy(pathName, "/dev/");
133-
strcat(pathName, gpioupsfdlocal->chipName);
131+
size_t pathNameLen = strlen(gpioupsfdlocal->chipName)+6;
132+
char *pathName = xcalloc(pathNameLen, sizeof(char));
133+
strncpy(pathName, "/dev/", pathNameLen);
134+
strncat(pathName, gpioupsfdlocal->chipName, pathNameLen);
134135
libgpiod_data->gpioChipHandle = gpiod_chip_open(pathName);
135136
free(pathName);
136137
} else {

drivers/generic_modbus.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
#endif
3232

3333
#define DRIVER_NAME "NUT Generic Modbus driver (libmodbus link type: " NUT_MODBUS_LINKTYPE_STR ")"
34-
#define DRIVER_VERSION "0.08"
34+
#define DRIVER_VERSION "0.09"
3535

3636
/* variables */
3737
static modbus_t *mbctx = NULL; /* modbus memory context */
@@ -1069,7 +1069,7 @@ modbus_t *modbus_new(const char *port)
10691069
}
10701070
} else if ((sp = strchr(port, ':')) != NULL) {
10711071
char *tcp_port = xmalloc(sizeof(sp));
1072-
strcpy(tcp_port, sp + 1);
1072+
strncpy(tcp_port, sp + 1, sizeof(sp));
10731073
*sp = '\0';
10741074
mb = modbus_new_tcp(port, (int)strtoul(tcp_port, NULL, 10));
10751075
if (mb == NULL) {

0 commit comments

Comments
 (0)