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