Bug Summary

File:dix/extension.c
Location:line 312, column 27
Description:Call to 'malloc' has an allocation size of 0 bytes

Annotated Source Code

1/***********************************************************
2
3Copyright 1987, 1998 The Open Group
4
5Permission to use, copy, modify, distribute, and sell this software and its
6documentation for any purpose is hereby granted without fee, provided that
7the above copyright notice appear in all copies and that both that
8copyright notice and this permission notice appear in supporting
9documentation.
10
11The above copyright notice and this permission notice shall be included in
12all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
21Except as contained in this notice, the name of The Open Group shall not be
22used in advertising or otherwise to promote the sale, use or other dealings
23in this Software without prior written authorization from The Open Group.
24
25Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
26
27 All Rights Reserved
28
29Permission to use, copy, modify, and distribute this software and its
30documentation for any purpose and without fee is hereby granted,
31provided that the above copyright notice appear in all copies and that
32both that copyright notice and this permission notice appear in
33supporting documentation, and that the name of Digital not be
34used in advertising or publicity pertaining to distribution of the
35software without specific, written prior permission.
36
37DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
38ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
39DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
40ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
41WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
42ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
43SOFTWARE.
44
45******************************************************************/
46
47#ifdef HAVE_DIX_CONFIG_H1
48#include <dix-config.h>
49#endif
50
51#include <X11/X.h>
52#include <X11/Xproto.h>
53#include "misc.h"
54#include "dixstruct.h"
55#include "extnsionst.h"
56#include "gcstruct.h"
57#include "scrnintstr.h"
58#include "dispatch.h"
59#include "privates.h"
60#include "registry.h"
61#include "xace.h"
62
63#define LAST_ERROR255 255
64
65static ExtensionEntry **extensions = (ExtensionEntry **) NULL((void*)0);
66
67int lastEvent = EXTENSION_EVENT_BASE64;
68static int lastError = FirstExtensionError128;
69static unsigned int NumExtensions = 0;
70
71ExtensionEntry *
72AddExtension(const char *name, int NumEvents, int NumErrors,
73 int (*MainProc) (ClientPtr c1),
74 int (*SwappedMainProc) (ClientPtr c2),
75 void (*CloseDownProc) (ExtensionEntry * e),
76 unsigned short (*MinorOpcodeProc) (ClientPtr c3))
77{
78 int i;
79 ExtensionEntry *ext, **newexts;
80
81 if (!MainProc || !SwappedMainProc || !MinorOpcodeProc)
82 return ((ExtensionEntry *) NULL((void*)0));
83 if ((lastEvent + NumEvents > MAXEVENTS128) ||
84 (unsigned) (lastError + NumErrors > LAST_ERROR255)) {
85 LogMessage(X_ERROR, "Not enabling extension %s: maximum number of "
86 "events or errors exceeded.\n", name);
87 return ((ExtensionEntry *) NULL((void*)0));
88 }
89
90 ext = calloc(sizeof(ExtensionEntry), 1);
91 if (!ext)
92 return NULL((void*)0);
93 if (!dixAllocatePrivates(&ext->devPrivates, PRIVATE_EXTENSION)) {
94 free(ext);
95 return NULL((void*)0);
96 }
97 ext->name = strdup(name);
98 ext->num_aliases = 0;
99 ext->aliases = (const char **) NULL((void*)0);
100 if (!ext->name) {
101 dixFreePrivates(ext->devPrivates, PRIVATE_EXTENSION);
102 free(ext);
103 return ((ExtensionEntry *) NULL((void*)0));
104 }
105 i = NumExtensions;
106 newexts = (ExtensionEntry **) realloc(extensions,
107 (i + 1) * sizeof(ExtensionEntry *));
108 if (!newexts) {
109 free((void *) ext->name);
110 dixFreePrivates(ext->devPrivates, PRIVATE_EXTENSION);
111 free(ext);
112 return ((ExtensionEntry *) NULL((void*)0));
113 }
114 NumExtensions++;
115 extensions = newexts;
116 extensions[i] = ext;
117 ext->index = i;
118 ext->base = i + EXTENSION_BASE128;
119 ext->CloseDown = CloseDownProc;
120 ext->MinorOpcode = MinorOpcodeProc;
121 ProcVector[i + EXTENSION_BASE128] = MainProc;
122 SwappedProcVector[i + EXTENSION_BASE128] = SwappedMainProc;
123 if (NumEvents) {
124 ext->eventBase = lastEvent;
125 ext->eventLast = lastEvent + NumEvents;
126 lastEvent += NumEvents;
127 }
128 else {
129 ext->eventBase = 0;
130 ext->eventLast = 0;
131 }
132 if (NumErrors) {
133 ext->errorBase = lastError;
134 ext->errorLast = lastError + NumErrors;
135 lastError += NumErrors;
136 }
137 else {
138 ext->errorBase = 0;
139 ext->errorLast = 0;
140 }
141
142#ifdef X_REGISTRY_REQUEST1
143 RegisterExtensionNames(ext);
144#endif
145 return ext;
146}
147
148Bool
149AddExtensionAlias(const char *alias, ExtensionEntry * ext)
150{
151 char *name;
152 const char **aliases;
153
154 if (!ext)
155 return FALSE0;
156 aliases = realloc(ext->aliases,
157 (ext->num_aliases + 1) * sizeof(char *));
158 if (!aliases)
159 return FALSE0;
160 ext->aliases = aliases;
161 name = strdup(alias);
162 if (!name)
163 return FALSE0;
164 ext->aliases[ext->num_aliases] = name;
165 ext->num_aliases++;
166 return TRUE1;
167}
168
169static int
170FindExtension(const char *extname, int len)
171{
172 int i, j;
173
174 for (i = 0; i < NumExtensions; i++) {
175 if ((strlen(extensions[i]->name) == len) &&
176 !strncmp(extname, extensions[i]->name, len))
177 break;
178 for (j = extensions[i]->num_aliases; --j >= 0;) {
179 if ((strlen(extensions[i]->aliases[j]) == len) &&
180 !strncmp(extname, extensions[i]->aliases[j], len))
181 break;
182 }
183 if (j >= 0)
184 break;
185 }
186 return ((i == NumExtensions) ? -1 : i);
187}
188
189/*
190 * CheckExtension returns the extensions[] entry for the requested
191 * extension name. Maybe this could just return a Bool instead?
192 */
193ExtensionEntry *
194CheckExtension(const char *extname)
195{
196 int n;
197
198 n = FindExtension(extname, strlen(extname));
199 if (n != -1)
200 return extensions[n];
201 else
202 return NULL((void*)0);
203}
204
205/*
206 * Added as part of Xace.
207 */
208ExtensionEntry *
209GetExtensionEntry(int major)
210{
211 if (major < EXTENSION_BASE128)
212 return NULL((void*)0);
213 major -= EXTENSION_BASE128;
214 if (major >= NumExtensions)
215 return NULL((void*)0);
216 return extensions[major];
217}
218
219unsigned short
220StandardMinorOpcode(ClientPtr client)
221{
222 return ((xReq *) client->requestBuffer)->data;
223}
224
225void
226CloseDownExtensions(void)
227{
228 int i, j;
229
230 for (i = NumExtensions - 1; i >= 0; i--) {
231 if (extensions[i]->CloseDown)
232 extensions[i]->CloseDown(extensions[i]);
233 NumExtensions = i;
234 free((void *) extensions[i]->name);
235 for (j = extensions[i]->num_aliases; --j >= 0;)
236 free((void *) extensions[i]->aliases[j]);
237 free(extensions[i]->aliases);
238 dixFreePrivates(extensions[i]->devPrivates, PRIVATE_EXTENSION);
239 free(extensions[i]);
240 }
241 free(extensions);
242 extensions = (ExtensionEntry **) NULL((void*)0);
243 lastEvent = EXTENSION_EVENT_BASE64;
244 lastError = FirstExtensionError128;
245}
246
247int
248ProcQueryExtension(ClientPtr client)
249{
250 xQueryExtensionReply reply;
251 int i;
252
253 REQUEST(xQueryExtensionReq)xQueryExtensionReq *stuff = (xQueryExtensionReq *)client->
requestBuffer
;
254
255 REQUEST_FIXED_SIZE(xQueryExtensionReq, stuff->nbytes)if (((sizeof(xQueryExtensionReq) >> 2) > client->
req_len) || (((stuff->nbytes) >> 2) >= client->
req_len) || ((((uint64_t) sizeof(xQueryExtensionReq) + (stuff
->nbytes) + 3) >> 2) != (uint64_t) client->req_len
)) return(16)
;
256
257 reply = (xQueryExtensionReply) {
258 .type = X_Reply1,
259 .sequenceNumber = client->sequence,
260 .length = 0,
261 .major_opcode = 0
262 };
263
264 if (!NumExtensions)
265 reply.present = xFalse0;
266 else {
267 i = FindExtension((char *) &stuff[1], stuff->nbytes);
268 if (i < 0 || XaceHook(XACE_EXT_ACCESS8, client, extensions[i]))
269 reply.present = xFalse0;
270 else {
271 reply.present = xTrue1;
272 reply.major_opcode = extensions[i]->base;
273 reply.first_event = extensions[i]->eventBase;
274 reply.first_error = extensions[i]->errorBase;
275 }
276 }
277 WriteReplyToClient(client, sizeof(xQueryExtensionReply), &reply){ if ((client)->swapped) (*ReplySwapVector[((xReq *)(client
)->requestBuffer)->reqType]) (client, (int)(sizeof(xQueryExtensionReply
)), &reply); else WriteToClient(client, (int)(sizeof(xQueryExtensionReply
)), (&reply)); }
;
278 return Success0;
279}
280
281int
282ProcListExtensions(ClientPtr client)
283{
284 xListExtensionsReply reply;
285 char *bufptr, *buffer;
286 int total_length = 0;
1
'total_length' initialized to 0
287
288 REQUEST_SIZE_MATCH(xReq)if ((sizeof(xReq) >> 2) != client->req_len) return(16
)
;
289
290 reply = (xListExtensionsReply) {
291 .type = X_Reply1,
292 .nExtensions = 0,
293 .sequenceNumber = client->sequence,
294 .length = 0
295 };
296 buffer = NULL((void*)0);
297
298 if (NumExtensions) {
2
Assuming 'NumExtensions' is not equal to 0
3
Taking true branch
299 int i, j;
300
301 for (i = 0; i < NumExtensions; i++) {
4
Loop condition is true. Entering loop body
7
Assuming 'i' is >= 'NumExtensions'
8
Loop condition is false. Execution continues on line 311
302 /* call callbacks to find out whether to show extension */
303 if (XaceHook(XACE_EXT_ACCESS8, client, extensions[i]) != Success0)
5
Taking true branch
304 continue;
6
Execution continues on line 301
305
306 total_length += strlen(extensions[i]->name) + 1;
307 reply.nExtensions += 1 + extensions[i]->num_aliases;
308 for (j = extensions[i]->num_aliases; --j >= 0;)
309 total_length += strlen(extensions[i]->aliases[j]) + 1;
310 }
311 reply.length = bytes_to_int32(total_length);
312 buffer = bufptr = malloc(total_length);
9
Call to 'malloc' has an allocation size of 0 bytes
313 if (!buffer)
314 return BadAlloc11;
315 for (i = 0; i < NumExtensions; i++) {
316 int len;
317
318 if (XaceHook(XACE_EXT_ACCESS8, client, extensions[i]) != Success0)
319 continue;
320
321 *bufptr++ = len = strlen(extensions[i]->name);
322 memmove(bufptr, extensions[i]->name, len)__builtin___memmove_chk (bufptr, extensions[i]->name, len,
__builtin_object_size (bufptr, 0))
;
323 bufptr += len;
324 for (j = extensions[i]->num_aliases; --j >= 0;) {
325 *bufptr++ = len = strlen(extensions[i]->aliases[j]);
326 memmove(bufptr, extensions[i]->aliases[j], len)__builtin___memmove_chk (bufptr, extensions[i]->aliases[j]
, len, __builtin_object_size (bufptr, 0))
;
327 bufptr += len;
328 }
329 }
330 }
331 WriteReplyToClient(client, sizeof(xListExtensionsReply), &reply){ if ((client)->swapped) (*ReplySwapVector[((xReq *)(client
)->requestBuffer)->reqType]) (client, (int)(sizeof(xListExtensionsReply
)), &reply); else WriteToClient(client, (int)(sizeof(xListExtensionsReply
)), (&reply)); }
;
332 if (reply.length)
333 WriteToClient(client, total_length, buffer);
334
335 free(buffer);
336 return Success0;
337}