Package: procps / 2:3.3.9-9+deb8u1

0035-proc-alloc.-Use-size_t-not-unsigned-int.patch Patch series | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
From e445551927c8b1cac3b6b10af59cd7793688ddb9 Mon Sep 17 00:00:00 2001
From: Qualys Security Advisory <qsa@qualys.com>
Date: Thu, 1 Jan 1970 00:00:00 +0000
Subject: [PATCH 035/126] proc/alloc.*: Use size_t, not unsigned int.

Otherwise this can truncate sizes on 64-bit platforms, and is one of the
reasons the integer overflows in file2strvec() are exploitable at all.
Also: catch potential integer overflow in xstrdup() (should never
happen, but better safe than sorry), and use memcpy() instead of
strcpy() (faster).

Warnings:

- in glibc, realloc(ptr, 0) is equivalent to free(ptr), but not here,
  because of the ++size;

- here, xstrdup() can return NULL (if str is NULL), which goes against
  the idea of the xalloc wrappers.

We were tempted to call exit() or xerrx() in those cases, but decided
against it, because it might break things in unexpected places; TODO?
---
 proc/alloc.c | 20 ++++++++++++--------
 proc/alloc.h |  4 ++--
 2 files changed, 14 insertions(+), 10 deletions(-)

diff --git a/proc/alloc.c b/proc/alloc.c
index 3cdb60f..0efd5a7 100644
--- a/proc/alloc.c
+++ b/proc/alloc.c
@@ -37,14 +37,14 @@ static void xdefault_error(const char *restrict fmts, ...) {
 message_fn xalloc_err_handler = xdefault_error;
 
 
-void *xcalloc(unsigned int size) {
+void *xcalloc(size_t size) {
     void * p;
 
     if (size == 0)
         ++size;
     p = calloc(1, size);
     if (!p) {
-        xalloc_err_handler("%s failed to allocate %u bytes of memory", __func__, size);
+        xalloc_err_handler("%s failed to allocate %zu bytes of memory", __func__, size);
         exit(EXIT_FAILURE);
     }
     return p;
@@ -57,20 +57,20 @@ void *xmalloc(size_t size) {
         ++size;
     p = malloc(size);
     if (!p) {
-	xalloc_err_handler("%s failed to allocate %zu bytes of memory", __func__, size);
+        xalloc_err_handler("%s failed to allocate %zu bytes of memory", __func__, size);
         exit(EXIT_FAILURE);
     }
     return(p);
 }
 
-void *xrealloc(void *oldp, unsigned int size) {
+void *xrealloc(void *oldp, size_t size) {
     void *p;
 
     if (size == 0)
         ++size;
     p = realloc(oldp, size);
     if (!p) {
-        xalloc_err_handler("%s failed to allocate %u bytes of memory", __func__, size);
+        xalloc_err_handler("%s failed to allocate %zu bytes of memory", __func__, size);
         exit(EXIT_FAILURE);
     }
     return(p);
@@ -80,13 +80,17 @@ char *xstrdup(const char *str) {
     char *p = NULL;
 
     if (str) {
-        unsigned int size = strlen(str) + 1;
+        size_t size = strlen(str) + 1;
+        if (size < 1) {
+            xalloc_err_handler("%s refused to allocate %zu bytes of memory", __func__, size);
+            exit(EXIT_FAILURE);
+        }
         p = malloc(size);
         if (!p) {
-            xalloc_err_handler("%s failed to allocate %u bytes of memory", __func__, size);
+            xalloc_err_handler("%s failed to allocate %zu bytes of memory", __func__, size);
             exit(EXIT_FAILURE);
         }
-        strcpy(p, str);
+        memcpy(p, str, size);
     }
     return(p);
 }
diff --git a/proc/alloc.h b/proc/alloc.h
index eedbb2b..12abb84 100644
--- a/proc/alloc.h
+++ b/proc/alloc.h
@@ -10,9 +10,9 @@ typedef void (*message_fn)(const char *__restrict, ...) __attribute__((format(pr
  /* change xalloc_err_handler to override the default fprintf(stderr... */
 extern message_fn xalloc_err_handler;
 
-extern void *xcalloc(unsigned int size) MALLOC;
+extern void *xcalloc(size_t size) MALLOC;
 extern void *xmalloc(size_t size) MALLOC;
-extern void *xrealloc(void *oldp, unsigned int size) MALLOC;
+extern void *xrealloc(void *oldp, size_t size) MALLOC;
 extern char *xstrdup(const char *str) MALLOC;
 
 EXTERN_C_END