Browse code

Add NULL checks

Extra NULL checks were added after malloc() calls to display out-of-
memory error and try to exit gracefully.

Function msica_op_create_*() now return NULL in out-of-memory condition
too. Since their output is directly used in msica_op_seq_add_head() and
msica_op_seq_add_tail() functions, later were extended to check for NULL
pointer arguments.

This patch follows Gert's recommendations from [openvpn-devel].

Signed-off-by: Simon Rozman <simon@rozman.si>
Message-ID: <20190117155829.GA92142@greenie.muc.de>
Acked-by: Gert Doering <gert@greenie.muc.de>
Message-Id: <20190224181400.42524-1-simon@rozman.si
20190117155829.GA92142@greenie.muc.de>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg18231.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>

Simon Rozman authored on 2019/02/25 03:14:00
Showing 5 changed files
... ...
@@ -65,8 +65,12 @@ DllMain(
65 65
         case DLL_THREAD_ATTACH:
66 66
         {
67 67
             /* Create thread local storage data. */
68
-            struct openvpnmsica_thread_data *s = (struct openvpnmsica_thread_data *)malloc(sizeof(struct openvpnmsica_thread_data));
69
-            memset(s, 0, sizeof(struct openvpnmsica_thread_data));
68
+            struct openvpnmsica_thread_data *s = (struct openvpnmsica_thread_data *)calloc(1, sizeof(struct openvpnmsica_thread_data));
69
+            if (s == NULL)
70
+            {
71
+                return FALSE;
72
+            }
73
+
70 74
             TlsSetValue(openvpnmsica_thread_data_idx, s);
71 75
             break;
72 76
         }
... ...
@@ -128,9 +132,18 @@ x_msg_va(const unsigned int flags, const char *format, va_list arglist)
128 128
         {
129 129
             /* Allocate on heap and retry. */
130 130
             char *szMessage = (char *)malloc(++iResultLen * sizeof(char));
131
-            vsnprintf(szMessage, iResultLen, format, arglist);
132
-            MsiRecordSetStringA(hRecordProg, 2, szMessage);
133
-            free(szMessage);
131
+            if (szMessage != NULL)
132
+            {
133
+                vsnprintf(szMessage, iResultLen, format, arglist);
134
+                MsiRecordSetStringA(hRecordProg, 2, szMessage);
135
+                free(szMessage);
136
+            }
137
+            else
138
+            {
139
+                /* Use stack variant anyway, but make sure it's zero-terminated. */
140
+                szBufStack[_countof(szBufStack) - 1] = 0;
141
+                MsiRecordSetStringA(hRecordProg, 2, szBufStack);
142
+            }
134 143
         }
135 144
     }
136 145
 
... ...
@@ -85,6 +85,12 @@ msica_op_create_bool(
85 85
 
86 86
     /* Create and fill operation struct. */
87 87
     struct msica_op_bool *op = (struct msica_op_bool *)malloc(sizeof(struct msica_op_bool));
88
+    if (op == NULL)
89
+    {
90
+        msg(M_FATAL, "%s: malloc(%u) failed", __FUNCTION__, sizeof(struct msica_op_bool));
91
+        return NULL;
92
+    }
93
+
88 94
     op->base.type  = type;
89 95
     op->base.ticks = ticks;
90 96
     op->base.next  = next;
... ...
@@ -110,6 +116,12 @@ msica_op_create_string(
110 110
     /* Create and fill operation struct. */
111 111
     size_t value_size = (_tcslen(value) + 1) * sizeof(TCHAR);
112 112
     struct msica_op_string *op = (struct msica_op_string *)malloc(sizeof(struct msica_op_string) + value_size);
113
+    if (op == NULL)
114
+    {
115
+        msg(M_FATAL, "%s: malloc(%u) failed", __FUNCTION__, sizeof(struct msica_op_string) + value_size);
116
+        return NULL;
117
+    }
118
+
113 119
     op->base.type  = type;
114 120
     op->base.ticks = ticks;
115 121
     op->base.next  = next;
... ...
@@ -142,6 +154,12 @@ msica_op_create_multistring_va(
142 142
 
143 143
     /* Create and fill operation struct. */
144 144
     struct msica_op_multistring *op = (struct msica_op_multistring *)malloc(sizeof(struct msica_op_multistring) + value_size);
145
+    if (op == NULL)
146
+    {
147
+        msg(M_FATAL, "%s: malloc(%u) failed", __FUNCTION__, sizeof(struct msica_op_multistring) + value_size);
148
+        return NULL;
149
+    }
150
+
145 151
     op->base.type  = type;
146 152
     op->base.ticks = ticks;
147 153
     op->base.next  = next;
... ...
@@ -173,6 +191,12 @@ msica_op_create_guid(
173 173
 
174 174
     /* Create and fill operation struct. */
175 175
     struct msica_op_guid *op = (struct msica_op_guid *)malloc(sizeof(struct msica_op_guid));
176
+    if (op == NULL)
177
+    {
178
+        msg(M_FATAL, "%s: malloc(%u) failed", __FUNCTION__, sizeof(struct msica_op_guid));
179
+        return NULL;
180
+    }
181
+
176 182
     op->base.type  = type;
177 183
     op->base.ticks = ticks;
178 184
     op->base.next  = next;
... ...
@@ -199,6 +223,12 @@ msica_op_create_guid_string(
199 199
     /* Create and fill operation struct. */
200 200
     size_t value_str_size = (_tcslen(value_str) + 1) * sizeof(TCHAR);
201 201
     struct msica_op_guid_string *op = (struct msica_op_guid_string *)malloc(sizeof(struct msica_op_guid_string) + value_str_size);
202
+    if (op == NULL)
203
+    {
204
+        msg(M_FATAL, "%s: malloc(%u) failed", __FUNCTION__, sizeof(struct msica_op_guid_string) + value_str_size);
205
+        return NULL;
206
+    }
207
+
202 208
     op->base.type  = type;
203 209
     op->base.ticks = ticks;
204 210
     op->base.next  = next;
... ...
@@ -214,6 +244,11 @@ msica_op_seq_add_head(
214 214
     _Inout_ struct msica_op_seq *seq,
215 215
     _Inout_ struct msica_op *operation)
216 216
 {
217
+    if (seq == NULL || operation == NULL)
218
+    {
219
+        return;
220
+    }
221
+
217 222
     /* Insert list in the head. */
218 223
     struct msica_op *op;
219 224
     for (op = operation; op->next; op = op->next)
... ...
@@ -235,6 +270,11 @@ msica_op_seq_add_tail(
235 235
     _Inout_ struct msica_op_seq *seq,
236 236
     _Inout_ struct msica_op *operation)
237 237
 {
238
+    if (seq == NULL || operation == NULL)
239
+    {
240
+        return;
241
+    }
242
+
238 243
     /* Append list to the tail. */
239 244
     struct msica_op *op;
240 245
     for (op = operation; op->next; op = op->next)
... ...
@@ -324,6 +364,11 @@ msica_op_seq_load(
324 324
 {
325 325
     DWORD dwRead;
326 326
 
327
+    if (seq == NULL)
328
+    {
329
+        return ERROR_BAD_ARGUMENTS;
330
+    }
331
+
327 332
     seq->head = seq->tail = NULL;
328 333
 
329 334
     for (;;)
... ...
@@ -345,10 +390,18 @@ msica_op_seq_load(
345 345
             msg(M_NONFATAL, "%s: Incomplete ReadFile", __FUNCTION__);
346 346
             return ERROR_INVALID_DATA;
347 347
         }
348
+
348 349
         struct msica_op *op = (struct msica_op *)malloc(sizeof(struct msica_op) + hdr.size_data);
350
+        if (op == NULL)
351
+        {
352
+            msg(M_FATAL, "%s: malloc(%u) failed", __FUNCTION__, sizeof(struct msica_op) + hdr.size_data);
353
+            return ERROR_OUTOFMEMORY;
354
+        }
355
+
349 356
         op->type  = hdr.type;
350 357
         op->ticks = hdr.ticks;
351 358
         op->next  = NULL;
359
+
352 360
         if (!ReadFile(hFile, op + 1, hdr.size_data, &dwRead, NULL))
353 361
         {
354 362
             DWORD dwResult = GetLastError();
... ...
@@ -361,6 +414,7 @@ msica_op_seq_load(
361 361
             msg(M_NONFATAL, "%s: Incomplete ReadFile", __FUNCTION__);
362 362
             return ERROR_INVALID_DATA;
363 363
         }
364
+
364 365
         msica_op_seq_add_tail(seq, op);
365 366
     }
366 367
 }
... ...
@@ -753,6 +807,12 @@ msica_op_file_delete_exec(
753 753
     {
754 754
         size_t sizeNameBackupLenZ = _tcslen(op->value) + 7 /*" (orig "*/ + 10 /*maximum int*/ + 1 /*")"*/ + 1 /*terminator*/;
755 755
         LPTSTR szNameBackup = (LPTSTR)malloc(sizeNameBackupLenZ * sizeof(TCHAR));
756
+        if (szNameBackup == NULL)
757
+        {
758
+            msg(M_FATAL, "%s: malloc(%u) failed", __FUNCTION__, sizeNameBackupLenZ * sizeof(TCHAR));
759
+            return ERROR_OUTOFMEMORY;
760
+        }
761
+
756 762
         int count = 0;
757 763
 
758 764
         do
... ...
@@ -54,6 +54,12 @@ msi_get_string(
54 54
     {
55 55
         /* Copy from stack. */
56 56
         *pszValue = (LPTSTR)malloc(++dwLength * sizeof(TCHAR));
57
+        if (*pszValue == NULL)
58
+        {
59
+            msg(M_FATAL, "%s: malloc(%u) failed", dwLength * sizeof(TCHAR));
60
+            return ERROR_OUTOFMEMORY;
61
+        }
62
+
57 63
         memcpy(*pszValue, szBufStack, dwLength * sizeof(TCHAR));
58 64
         return ERROR_SUCCESS;
59 65
     }
... ...
@@ -61,6 +67,12 @@ msi_get_string(
61 61
     {
62 62
         /* Allocate on heap and retry. */
63 63
         LPTSTR szBufHeap = (LPTSTR)malloc(++dwLength * sizeof(TCHAR));
64
+        if (szBufHeap == NULL)
65
+        {
66
+            msg(M_FATAL, "%s: malloc(%u) failed", __FUNCTION__, dwLength * sizeof(TCHAR));
67
+            return ERROR_OUTOFMEMORY;
68
+        }
69
+
64 70
         uiResult = MsiGetProperty(hInstall, szName, szBufHeap, &dwLength);
65 71
         if (uiResult == ERROR_SUCCESS)
66 72
         {
... ...
@@ -100,6 +112,12 @@ msi_get_record_string(
100 100
     {
101 101
         /* Copy from stack. */
102 102
         *pszValue = (LPTSTR)malloc(++dwLength * sizeof(TCHAR));
103
+        if (*pszValue == NULL)
104
+        {
105
+            msg(M_FATAL, "%s: malloc(%u) failed", __FUNCTION__, dwLength * sizeof(TCHAR));
106
+            return ERROR_OUTOFMEMORY;
107
+        }
108
+
103 109
         memcpy(*pszValue, szBufStack, dwLength * sizeof(TCHAR));
104 110
         return ERROR_SUCCESS;
105 111
     }
... ...
@@ -107,6 +125,12 @@ msi_get_record_string(
107 107
     {
108 108
         /* Allocate on heap and retry. */
109 109
         LPTSTR szBufHeap = (LPTSTR)malloc(++dwLength * sizeof(TCHAR));
110
+        if (szBufHeap == NULL)
111
+        {
112
+            msg(M_FATAL, "%s: malloc(%u) failed", __FUNCTION__, dwLength * sizeof(TCHAR));
113
+            return ERROR_OUTOFMEMORY;
114
+        }
115
+
110 116
         uiResult = MsiRecordGetString(hRecord, iField, szBufHeap, &dwLength);
111 117
         if (uiResult == ERROR_SUCCESS)
112 118
         {
... ...
@@ -146,6 +170,12 @@ msi_format_record(
146 146
     {
147 147
         /* Copy from stack. */
148 148
         *pszValue = (LPTSTR)malloc(++dwLength * sizeof(TCHAR));
149
+        if (*pszValue == NULL)
150
+        {
151
+            msg(M_FATAL, "%s: malloc(%u) failed", __FUNCTION__, dwLength * sizeof(TCHAR));
152
+            return ERROR_OUTOFMEMORY;
153
+        }
154
+
149 155
         memcpy(*pszValue, szBufStack, dwLength * sizeof(TCHAR));
150 156
         return ERROR_SUCCESS;
151 157
     }
... ...
@@ -153,6 +183,12 @@ msi_format_record(
153 153
     {
154 154
         /* Allocate on heap and retry. */
155 155
         LPTSTR szBufHeap = (LPTSTR)malloc(++dwLength * sizeof(TCHAR));
156
+        if (szBufHeap == NULL)
157
+        {
158
+            msg(M_FATAL, "%s: malloc(%u) failed", __FUNCTION__, dwLength * sizeof(TCHAR));
159
+            return ERROR_OUTOFMEMORY;
160
+        }
161
+
156 162
         uiResult = MsiFormatRecord(hInstall, hRecord, szBufHeap, &dwLength);
157 163
         if (uiResult == ERROR_SUCCESS)
158 164
         {
... ...
@@ -129,6 +129,12 @@ openvpnmsica_setup_sequence_filename(
129 129
     {
130 130
         size_t len_action_name_z = _tcslen(openvpnmsica_cleanup_action_seqs[i].szName) + 1;
131 131
         TCHAR *szPropertyEx = (TCHAR *)malloc((len_property_name + len_action_name_z) * sizeof(TCHAR));
132
+        if (szPropertyEx == NULL)
133
+        {
134
+            msg(M_FATAL, "%s: malloc(%u) failed", __FUNCTION__, (len_property_name + len_action_name_z) * sizeof(TCHAR));
135
+            return ERROR_OUTOFMEMORY;
136
+        }
137
+
132 138
         memcpy(szPropertyEx, szProperty, len_property_name * sizeof(TCHAR));
133 139
         memcpy(szPropertyEx + len_property_name, openvpnmsica_cleanup_action_seqs[i].szName, len_action_name_z * sizeof(TCHAR));
134 140
         _stprintf_s(
... ...
@@ -300,6 +306,10 @@ openvpnmsica_set_driver_certification(_In_ MSIHANDLE hInstall)
300 300
 
301 301
             free(pVersionInfo);
302 302
         }
303
+        else
304
+        {
305
+            msg(M_NONFATAL, "%s: malloc(%u) failed", __FUNCTION__, dwVerInfoSize);
306
+        }
303 307
     }
304 308
 
305 309
     uiResult = MsiSetProperty(hInstall, TEXT("DRIVERCERTIFICATION"), ver_info.dwMajorVersion >= 10 ? ver_info.wProductType > VER_NT_WORKSTATION ? TEXT("whql") : TEXT("attsgn") : TEXT(""));
... ...
@@ -529,6 +539,13 @@ FindTAPInterfaces(_In_ MSIHANDLE hInstall)
529 529
 
530 530
                 /* Append interface to the list. */
531 531
                 struct interface_node *node = (struct interface_node *)malloc(sizeof(struct interface_node));
532
+                if (node == NULL)
533
+                {
534
+                    MsiCloseHandle(hRecord);
535
+                    msg(M_FATAL, "%s: malloc(%u) failed", __FUNCTION__, sizeof(struct interface_node));
536
+                    uiResult = ERROR_OUTOFMEMORY; goto cleanup_pAdapterAdresses;
537
+                }
538
+
532 539
                 node->iface = pInterface;
533 540
                 node->next = NULL;
534 541
                 if (interfaces_head)
... ...
@@ -550,10 +567,23 @@ FindTAPInterfaces(_In_ MSIHANDLE hInstall)
550 550
     {
551 551
         /* Prepare semicolon delimited list of TAP interface ID(s) and active TAP interface ID(s). */
552 552
         LPTSTR
553
-            szTAPInterfaces           = (LPTSTR)malloc(interface_count * (38 /*GUID*/ + 1 /*separator/terminator*/) * sizeof(TCHAR)),
554
-            szTAPInterfacesTail       = szTAPInterfaces,
553
+            szTAPInterfaces     = (LPTSTR)malloc(interface_count * (38 /*GUID*/ + 1 /*separator/terminator*/) * sizeof(TCHAR)),
554
+            szTAPInterfacesTail = szTAPInterfaces;
555
+        if (szTAPInterfaces == NULL)
556
+        {
557
+            msg(M_FATAL, "%s: malloc(%u) failed", __FUNCTION__, interface_count * (38 /*GUID*/ + 1 /*separator/terminator*/) * sizeof(TCHAR));
558
+            uiResult = ERROR_OUTOFMEMORY; goto cleanup_pAdapterAdresses;
559
+        }
560
+
561
+        LPTSTR
555 562
             szTAPInterfacesActive     = (LPTSTR)malloc(interface_count * (38 /*GUID*/ + 1 /*separator/terminator*/) * sizeof(TCHAR)),
556 563
             szTAPInterfacesActiveTail = szTAPInterfacesActive;
564
+        if (szTAPInterfacesActive == NULL)
565
+        {
566
+            msg(M_FATAL, "%s: malloc(%u) failed", __FUNCTION__, interface_count * (38 /*GUID*/ + 1 /*separator/terminator*/) * sizeof(TCHAR));
567
+            uiResult = ERROR_OUTOFMEMORY; goto cleanup_szTAPInterfaces;
568
+        }
569
+
557 570
         while (interfaces_head)
558 571
         {
559 572
             /* Convert interface GUID to UTF-16 string. (LPOLESTR defaults to LPWSTR) */
... ...
@@ -605,7 +635,7 @@ FindTAPInterfaces(_In_ MSIHANDLE hInstall)
605 605
         {
606 606
             SetLastError(uiResult); /* MSDN does not mention MsiSetProperty() to set GetLastError(). But we do have an error code. Set last error manually. */
607 607
             msg(M_NONFATAL | M_ERRNO, "%s: MsiSetProperty(\"TAPINTERFACES\") failed", __FUNCTION__);
608
-            goto cleanup_szTAPInterfaces;
608
+            goto cleanup_szTAPInterfacesActive;
609 609
         }
610 610
 
611 611
         /* Set Installer ACTIVETAPINTERFACES property. */
... ...
@@ -614,11 +644,12 @@ FindTAPInterfaces(_In_ MSIHANDLE hInstall)
614 614
         {
615 615
             SetLastError(uiResult); /* MSDN does not mention MsiSetProperty() to set GetLastError(). But we do have an error code. Set last error manually. */
616 616
             msg(M_NONFATAL | M_ERRNO, "%s: MsiSetProperty(\"ACTIVETAPINTERFACES\") failed", __FUNCTION__);
617
-            goto cleanup_szTAPInterfaces;
617
+            goto cleanup_szTAPInterfacesActive;
618 618
         }
619 619
 
620
-cleanup_szTAPInterfaces:
620
+cleanup_szTAPInterfacesActive:
621 621
         free(szTAPInterfacesActive);
622
+cleanup_szTAPInterfaces:
622 623
         free(szTAPInterfaces);
623 624
     }
624 625
     else
... ...
@@ -626,6 +657,7 @@ cleanup_szTAPInterfaces:
626 626
         uiResult = ERROR_SUCCESS;
627 627
     }
628 628
 
629
+cleanup_pAdapterAdresses:
629 630
     free(pAdapterAdresses);
630 631
 cleanup_tap_list_interfaces:
631 632
     tap_free_interface_list(pInterfaceList);
... ...
@@ -700,6 +732,12 @@ StartOpenVPNGUI(_In_ MSIHANDLE hInstall)
700 700
     {
701 701
         /* Allocate buffer on heap (+1 for terminator), and retry. */
702 702
         szPath = (LPTSTR)malloc((++dwPathSize) * sizeof(TCHAR));
703
+        if (szPath == NULL)
704
+        {
705
+            msg(M_FATAL, "%s: malloc(%u) failed", __FUNCTION__, dwPathSize * sizeof(TCHAR));
706
+            uiResult = ERROR_OUTOFMEMORY; goto cleanup_MsiCreateRecord;
707
+        }
708
+
703 709
         uiResult = MsiFormatRecord(hInstall, hRecord, szPath, &dwPathSize);
704 710
     }
705 711
     if (uiResult != ERROR_SUCCESS)
... ...
@@ -140,6 +140,12 @@ get_reg_string(
140 140
         {
141 141
             /* Read value. */
142 142
             LPTSTR szValue = (LPTSTR)malloc(dwSize);
143
+            if (szValue == NULL)
144
+            {
145
+                msg(M_FATAL, "%s: malloc(%u) failed", __FUNCTION__, dwSize);
146
+                return ERROR_OUTOFMEMORY;
147
+            }
148
+
143 149
             dwResult = RegQueryValueEx(
144 150
                 hKey,
145 151
                 szName,
... ...
@@ -167,6 +173,13 @@ get_reg_string(
167 167
                     dwSizeExp / sizeof(TCHAR) - 1;     /* Note: ANSI version requires one extra char. */
168 168
 #endif
169 169
                 LPTSTR szValueExp = (LPTSTR)malloc(dwSizeExp);
170
+                if (szValueExp == NULL)
171
+                {
172
+                    free(szValue);
173
+                    msg(M_FATAL, "%s: malloc(%u) failed", __FUNCTION__, dwSizeExp);
174
+                    return ERROR_OUTOFMEMORY;
175
+                }
176
+
170 177
                 DWORD dwCountExpResult = ExpandEnvironmentStrings(
171 178
                     szValue,
172 179
                     szValueExp, dwCountExp
... ...
@@ -197,6 +210,13 @@ get_reg_string(
197 197
 #endif
198 198
                     dwCountExp = dwCountExpResult;
199 199
                     szValueExp = (LPTSTR)malloc(dwSizeExp);
200
+                    if (szValueExp == NULL)
201
+                    {
202
+                        free(szValue);
203
+                        msg(M_FATAL, "%s: malloc(%u) failed", __FUNCTION__, dwSizeExp);
204
+                        return ERROR_OUTOFMEMORY;
205
+                    }
206
+
200 207
                     dwCountExpResult = ExpandEnvironmentStrings(
201 208
                         szValue,
202 209
                         szValueExp, dwCountExp);
... ...
@@ -356,6 +376,12 @@ get_device_reg_property(
356 356
     {
357 357
         /* Copy from stack. */
358 358
         *ppData = malloc(dwRequiredSize);
359
+        if (*ppData == NULL)
360
+        {
361
+            msg(M_FATAL, "%s: malloc(%u) failed", __FUNCTION__, dwRequiredSize);
362
+            return ERROR_OUTOFMEMORY;
363
+        }
364
+
359 365
         memcpy(*ppData, bBufStack, dwRequiredSize);
360 366
         return ERROR_SUCCESS;
361 367
     }
... ...
@@ -366,6 +392,12 @@ get_device_reg_property(
366 366
         {
367 367
             /* Allocate on heap and retry. */
368 368
             *ppData = malloc(dwRequiredSize);
369
+            if (*ppData == NULL)
370
+            {
371
+                msg(M_FATAL, "%s: malloc(%u) failed", __FUNCTION__, dwRequiredSize);
372
+                return ERROR_OUTOFMEMORY;
373
+            }
374
+
369 375
             if (SetupDiGetDeviceRegistryProperty(
370 376
                     hDeviceInfoSet,
371 377
                     pDeviceInfoData,
... ...
@@ -499,6 +531,12 @@ tap_create_interface(
499 499
     DWORDLONG dwlDriverVersion = 0;
500 500
     DWORD drvinfo_detail_data_size = sizeof(SP_DRVINFO_DETAIL_DATA) + 0x100;
501 501
     SP_DRVINFO_DETAIL_DATA *drvinfo_detail_data = (SP_DRVINFO_DETAIL_DATA *)malloc(drvinfo_detail_data_size);
502
+    if (drvinfo_detail_data == NULL)
503
+    {
504
+        msg(M_FATAL, "%s: malloc(%u) failed", __FUNCTION__, drvinfo_detail_data_size);
505
+        dwResult = ERROR_OUTOFMEMORY; goto cleanup_DriverInfoList;
506
+    }
507
+
502 508
     for (DWORD dwIndex = 0;; dwIndex++)
503 509
     {
504 510
         /* Get a driver from the list. */
... ...
@@ -543,6 +581,11 @@ tap_create_interface(
543 543
 
544 544
                 drvinfo_detail_data_size = dwSize;
545 545
                 drvinfo_detail_data = (SP_DRVINFO_DETAIL_DATA *)malloc(drvinfo_detail_data_size);
546
+                if (drvinfo_detail_data == NULL)
547
+                {
548
+                    msg(M_FATAL, "%s: malloc(%u) failed", __FUNCTION__, drvinfo_detail_data_size);
549
+                    dwResult = ERROR_OUTOFMEMORY; goto cleanup_DriverInfoList;
550
+                }
546 551
 
547 552
                 /* Re-get driver info details. */
548 553
                 drvinfo_detail_data->cbSize = sizeof(SP_DRVINFO_DETAIL_DATA);
... ...
@@ -1038,6 +1081,12 @@ tap_list_interfaces(
1038 1038
         size_t hwid_size = (_tcszlen(szzDeviceHardwareIDs) + 1) * sizeof(TCHAR);
1039 1039
         size_t name_size = (_tcslen(szName) + 1) * sizeof(TCHAR);
1040 1040
         struct tap_interface_node *node = (struct tap_interface_node *)malloc(sizeof(struct tap_interface_node) + hwid_size + name_size);
1041
+        if (node == NULL)
1042
+        {
1043
+            msg(M_FATAL, "%s: malloc(%u) failed", __FUNCTION__, sizeof(struct tap_interface_node) + hwid_size + name_size);
1044
+            dwResult = ERROR_OUTOFMEMORY; goto cleanup_szName;
1045
+        }
1046
+
1041 1047
         memcpy(&node->guid, &guidInterface, sizeof(GUID));
1042 1048
         node->szzHardwareIDs = (LPTSTR)(node + 1);
1043 1049
         memcpy(node->szzHardwareIDs, szzDeviceHardwareIDs, hwid_size);
... ...
@@ -1054,6 +1103,7 @@ tap_list_interfaces(
1054 1054
             *ppInterface = pInterfaceTail = node;
1055 1055
         }
1056 1056
 
1057
+cleanup_szName:
1057 1058
         free(szName);
1058 1059
 cleanup_hKey:
1059 1060
         RegCloseKey(hKey);