Skip to content

Commit 2f89002

Browse files
committed
Silence malloc compilation warning
Check request size against PTRDIFF_MAX before calling malloc, calloc, and realloc. Otherwise, gcc 9 and later complain with thie warning message. In file included from var_getput.c:17: var_getput.c: In function 'ncmpi_mput_var': ../../../PnetCDF/src/drivers/include/common.h:83:26: warning: argument 1 range [18446744065119617024, 18446744073709551612] exceeds maximum object size 9223372036854775807 [-Walloc-size-larger-than=] 83 | #define NCI_Malloc(a) malloc(a) | ^~~~~~~~~ var_getput.c:20555:19: note: in expansion of macro 'NCI_Malloc' 20555 | reqs = (int*) NCI_Malloc(sizeof(int) * nvars); | ^~~~~~~~~~ In file included from var_getput.c:12: /usr/include/stdlib.h:539:14: note: in a call to allocation function 'malloc' declared here 539 | extern void *malloc (size_t __size) __THROW __attribute_malloc__ __wur; | ^~~~~~
1 parent 65f8be7 commit 2f89002

File tree

2 files changed

+74
-27
lines changed

2 files changed

+74
-27
lines changed

src/drivers/common/mem_alloc.c

Lines changed: 74 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,14 @@
2525
#include <stdlib.h>
2626
#include <stdio.h>
2727
#include <string.h> /* strcpy(), strlen() */
28+
29+
#ifdef HAVE_STDINT_H
30+
#include <stdint.h> /*PTRDIFF_MAX */
31+
#endif
32+
#ifndef PTRDIFF_MAX
33+
#define PTRDIFF_MAX SIZE_MAX
34+
#endif
35+
2836
#include <errno.h> /* EINVAL */
2937
#include <assert.h>
3038

@@ -189,11 +197,28 @@ void *NCI_Malloc_fn(size_t size,
189197
const char *func,
190198
const char *filename)
191199
{
192-
void *buf = malloc(size);
200+
void *buf;
201+
202+
/* Many C library implementations, particularly those designed to work with
203+
* GCC and Clang, limit single malloc allocations to PTRDIFF_MAX - 1 bytes.
204+
* ptrdiff_t is a signed integer type used for the difference between two
205+
* pointers, and PTRDIFF_MAX is its maximum value. This limitation exists
206+
* because some compiler optimizations and internal library operations may
207+
* rely on pointer differences being representable within ptrdiff_t.
208+
*/
209+
if (size > PTRDIFF_MAX - 1) {
210+
fprintf(stderr, "NCI_Malloc(%zd) failed in file %s func %s line %d\n",
211+
size, filename, func, lineno);
212+
return NULL;
213+
}
193214

194-
if (size > 0 && buf == NULL)
195-
fprintf(stderr, "malloc(%zd) failed in file %s func %s line %d\n",
215+
buf = malloc(size);
216+
217+
if (size > 0 && buf == NULL) {
218+
fprintf(stderr, "NCI_Malloc(%zd) failed in file %s func %s line %d\n",
196219
size, filename, func, lineno);
220+
return NULL;
221+
}
197222

198223
#ifdef PNC_MALLOC_TRACE
199224
ncmpii_add_mem_entry(buf, size, lineno, func, filename);
@@ -216,16 +241,25 @@ void *NCI_Strdup_fn(const char *src,
216241

217242
if (src == NULL) return NULL;
218243

219-
len = strlen(src);
220-
buf = malloc(len + 1);
244+
len = strlen(src) + 1;
245+
246+
if (len > PTRDIFF_MAX - 1) {
247+
fprintf(stderr, "NCI_Strdup(%zd) failed in file %s func %s line %d\n",
248+
len, filename, func, lineno);
249+
return NULL;
250+
}
251+
252+
buf = malloc(len);
221253

222-
if (len >= 0 && buf == NULL)
223-
fprintf(stderr, "malloc(%zd) failed in file %s func %s line %d\n",
254+
if (buf == NULL) {
255+
fprintf(stderr, "NCI_Strdup(%zd) failed in file %s func %s line %d\n",
224256
len, filename, func, lineno);
257+
return NULL;
258+
}
225259

226-
if (len > 0) memcpy(buf, src, len);
260+
memcpy(buf, src, len - 1);
227261

228-
((char*)buf)[len] = '\0';
262+
((char*)buf)[len - 1] = '\0';
229263

230264
#ifdef PNC_MALLOC_TRACE
231265
ncmpii_add_mem_entry(buf, len, lineno, func, filename);
@@ -246,11 +280,22 @@ void *NCI_Calloc_fn(size_t nelem,
246280
const char *func,
247281
const char *filename)
248282
{
249-
void *buf = calloc(nelem, elsize);
283+
void *buf;
250284

251-
if (nelem > 0 && buf == NULL)
252-
fprintf(stderr, "calloc(%zd, %zd) failed in file %s func %s line %d\n",
285+
if (nelem * elsize > PTRDIFF_MAX - 1) {
286+
fprintf(stderr, "NCI_Calloc(%zd, %zd) failed in file %s func %s line %d\n",
253287
nelem, elsize, filename, func, lineno);
288+
return NULL;
289+
}
290+
291+
/* calloc() accepts zero size, to allow free() to be called later */
292+
buf = calloc(nelem, elsize);
293+
294+
if (nelem > 0 && buf == NULL) {
295+
fprintf(stderr, "NCI_Calloc(%zd, %zd) failed in file %s func %s line %d\n",
296+
nelem, elsize, filename, func, lineno);
297+
return NULL;
298+
}
254299

255300
#ifdef PNC_MALLOC_TRACE
256301
ncmpii_add_mem_entry(buf, nelem * elsize, lineno, func, filename);
@@ -277,6 +322,12 @@ void *NCI_Realloc_fn(void *ptr,
277322
{
278323
void *buf;
279324

325+
if (size > PTRDIFF_MAX - 1) {
326+
fprintf(stderr, "NCI_Realloc(_, %zd) failed in file %s func %s line %d\n",
327+
size, filename, func, lineno);
328+
return NULL;
329+
}
330+
280331
if (ptr == NULL) return NCI_Malloc_fn(size, lineno, func, filename);
281332

282333
if (size == 0) {
@@ -285,15 +336,19 @@ void *NCI_Realloc_fn(void *ptr,
285336
}
286337

287338
#ifdef PNC_MALLOC_TRACE
288-
if (ncmpii_del_mem_entry(ptr) != 0)
289-
fprintf(stderr, "realloc failed in file %s func %s line %d\n",
290-
filename, func, lineno);
339+
if (ncmpii_del_mem_entry(ptr) != 0) {
340+
fprintf(stderr, "NCI_Realloc(_, %zd) failed in file %s func %s line %d\n",
341+
size, filename, func, lineno);
342+
return NULL;
343+
}
291344
#endif
292345

293346
buf = (void *) realloc(ptr, size);
294-
if (buf == NULL)
295-
fprintf(stderr, "realloc failed in file %s func %s line %d\n",
296-
filename, func, lineno);
347+
if (buf == NULL) {
348+
fprintf(stderr, "NCI_Realloc(_, %zd) failed in file %s func %s line %d\n",
349+
size, filename, func, lineno);
350+
return NULL;
351+
}
297352

298353
#ifdef PNC_MALLOC_TRACE
299354
ncmpii_add_mem_entry(buf, size, lineno, func, filename);
@@ -319,7 +374,7 @@ void NCI_Free_fn(void *ptr,
319374

320375
#ifdef PNC_MALLOC_TRACE
321376
if (ncmpii_del_mem_entry(ptr) != 0)
322-
fprintf(stderr, "free failed in file %s func %s line %d\n",
377+
fprintf(stderr, "NCI_Free failed in file %s func %s line %d\n",
323378
filename, func, lineno);
324379
#endif
325380

src/drivers/include/common.h

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -73,19 +73,11 @@ extern void
7373
NCI_Free_fn(void *ptr, const int lineno, const char *func,
7474
const char *filename);
7575

76-
#if defined(PNETCDF_DEBUG) || defined(PNC_MALLOC_TRACE)
7776
#define NCI_Malloc(a) NCI_Malloc_fn(a,__LINE__,__func__,__FILE__)
7877
#define NCI_Strdup(a) NCI_Strdup_fn(a,__LINE__,__func__,__FILE__)
7978
#define NCI_Calloc(a,b) NCI_Calloc_fn(a,b,__LINE__,__func__,__FILE__)
8079
#define NCI_Realloc(a,b) NCI_Realloc_fn(a,b,__LINE__,__func__,__FILE__)
8180
#define NCI_Free(a) NCI_Free_fn(a,__LINE__,__func__,__FILE__)
82-
#else
83-
#define NCI_Malloc(a) malloc(a)
84-
#define NCI_Strdup(a) strdup(a)
85-
#define NCI_Calloc(a,b) calloc(a,b)
86-
#define NCI_Realloc(a,b) realloc(a,b)
87-
#define NCI_Free(a) free(a)
88-
#endif
8981

9082
extern int
9183
ncmpii_inq_malloc_size(size_t *size);

0 commit comments

Comments
 (0)