Skip to content

Commit bef56be

Browse files
committed
Refactor existing realloc code to use grow_array
The new grow_array function handles realloc failure properly without leaking the previous array pointer or changing the capacity.
1 parent 47b3776 commit bef56be

3 files changed

Lines changed: 46 additions & 32 deletions

File tree

lib/lsof.c

Lines changed: 3 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -772,8 +772,6 @@ enum lsof_error lsof_select_process_regex(struct lsof_context *ctx, char *x) {
772772
MALLOC_S xl;
773773
char *xp = (char *)NULL;
774774
enum lsof_error ret = LSOF_SUCCESS;
775-
lsof_rx_t *new_rx;
776-
int new_cmdrx_cap;
777775

778776
if (!ctx || ctx->frozen) {
779777
return LSOF_ERROR_INVALID_ARGUMENT;
@@ -897,13 +895,7 @@ enum lsof_error lsof_select_process_regex(struct lsof_context *ctx, char *x) {
897895
/*
898896
* More CmdRx[] space must be assigned.
899897
*/
900-
new_cmdrx_cap = NCmdRxA + 32;
901-
xl = (MALLOC_S)(new_cmdrx_cap * sizeof(lsof_rx_t));
902-
if (CmdRx)
903-
new_rx = (lsof_rx_t *)realloc((MALLOC_P *)CmdRx, xl);
904-
else
905-
new_rx = (lsof_rx_t *)malloc(xl);
906-
if (!new_rx) {
898+
if (grow_array((void **)&CmdRx, &NCmdRxA, sizeof(lsof_rx_t), 32)) {
907899
if (ctx->err) {
908900
(void)fprintf(ctx->err, "%s: no space for regexp: ", Pn);
909901
safestrprt(x, ctx->err, 1);
@@ -912,8 +904,6 @@ enum lsof_error lsof_select_process_regex(struct lsof_context *ctx, char *x) {
912904
ret = LSOF_ERROR_NO_MEMORY;
913905
goto cleanup;
914906
}
915-
CmdRx = new_rx;
916-
NCmdRxA = new_cmdrx_cap;
917907
}
918908
i = NCmdRxU;
919909
/*
@@ -977,15 +967,7 @@ enum lsof_error lsof_select_pid_pgid(struct lsof_context *ctx, int32_t id,
977967
* Allocate table table space.
978968
*/
979969
if (*size >= *cap) {
980-
*cap += 10;
981-
if (!(*sel))
982-
*sel = (struct int_lst *)malloc(
983-
(MALLOC_S)(sizeof(struct int_lst) * (*cap)));
984-
else
985-
*sel = (struct int_lst *)realloc(
986-
(MALLOC_P *)(*sel),
987-
(MALLOC_S)(sizeof(struct int_lst) * (*cap)));
988-
if (!(*sel)) {
970+
if (grow_array((void **)sel, cap, sizeof(struct int_lst), 10)) {
989971
if (ctx->err) {
990972
(void)fprintf(ctx->err, "%s: no space for %d process%s IDs", Pn,
991973
*cap, is_pid ? "" : " group");
@@ -1061,13 +1043,7 @@ enum lsof_error lsof_select_uid_login(struct lsof_context *ctx, uint32_t uid,
10611043
* Allocate space for User IDentifier.
10621044
*/
10631045
if (Nuid >= Mxuid) {
1064-
Mxuid += 10;
1065-
len = (MALLOC_S)(Mxuid * sizeof(struct seluid));
1066-
if (!Suid)
1067-
Suid = (struct seluid *)malloc(len);
1068-
else
1069-
Suid = (struct seluid *)realloc((MALLOC_P *)Suid, len);
1070-
if (!Suid) {
1046+
if (grow_array((void **)&Suid, &Mxuid, sizeof(struct seluid), 10)) {
10711047
if (ctx->err) {
10721048
(void)fprintf(ctx->err, "%s: no space for UIDs", Pn);
10731049
}

lib/misc.c

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@ static void closePipes(void);
5656
static int dolstat(char *path, char *buf, int len);
5757
static int dostat(char *path, char *buf, int len);
5858
static int doreadlink(char *path, char *buf, int len);
59-
static int doinchild(struct lsof_context *ctx, int (*fn)(char *path, char *buf, int len), char *fp,
59+
static int doinchild(struct lsof_context *ctx,
60+
int (*fn)(char *path, char *buf, int len), char *fp,
6061
char *rbuf, int rbln);
6162

6263
#if defined(HASINTSIGNAL)
@@ -259,10 +260,11 @@ void closefrom_shim(struct lsof_context *ctx, int low) {
259260
*/
260261

261262
static int doinchild(struct lsof_context *ctx,
262-
int (*fn)(char *path, char *buf, int len), /* function to perform */
263-
char *fp, /* function parameter */
264-
char *rbuf, /* response buffer */
265-
int rbln) /* response buffer length */
263+
int (*fn)(char *path, char *buf,
264+
int len), /* function to perform */
265+
char *fp, /* function parameter */
266+
char *rbuf, /* response buffer */
267+
int rbln) /* response buffer length */
266268
{
267269
int en, rv;
268270

@@ -1625,3 +1627,37 @@ char *x2dev(char *s, /* ASCII string */
16251627
*d = r;
16261628
return (s);
16271629
}
1630+
1631+
/*
1632+
* grow_array(): handle dynamic array growth
1633+
*/
1634+
int grow_array(void **array_ptr, int *cap, size_t elem_size, int growth_count) {
1635+
void *new_array;
1636+
1637+
/* Calculate new capacity */
1638+
int new_capacity = *cap + growth_count;
1639+
if (new_capacity < 0) {
1640+
return -1;
1641+
}
1642+
size_t new_size = (size_t)new_capacity * elem_size;
1643+
1644+
/* Check for overflow */
1645+
if (new_capacity < 0 || new_size / elem_size != (size_t)new_capacity) {
1646+
return -1;
1647+
}
1648+
1649+
if (*array_ptr) {
1650+
new_array = realloc((MALLOC_P *)*array_ptr, (MALLOC_S)new_size);
1651+
} else {
1652+
new_array = malloc((MALLOC_S)new_size);
1653+
}
1654+
1655+
if (!new_array) {
1656+
/* Allocation failed */
1657+
return -1;
1658+
}
1659+
1660+
*array_ptr = new_array;
1661+
*cap = new_capacity;
1662+
return 0;
1663+
}

lib/proto.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,8 @@ extern void usage(struct lsof_context *ctx, int err, int fh, int version);
214214
extern int util_strftime(char *fmtr, int fmtl, char *fmt);
215215
extern int vfy_dev(struct lsof_context *ctx, struct l_dev *dp);
216216
extern char *x2dev(char *s, dev_t *d);
217+
extern int grow_array(void **array_ptr, int *cap, size_t elem_size,
218+
int growth_count);
217219

218220
# if defined(HASBLKDEV)
219221
extern void find_bl_ino(struct lsof_context *ctx);

0 commit comments

Comments
 (0)