Bug Summary

File:hw/xfree86/common/xf86AutoConfig.c
Location:line 395, column 28
Description:Potential leak of memory pointed to by 'ptr'

Annotated Source Code

1/*
2 * Copyright 2003 by David H. Dawes.
3 * Copyright 2003 by X-Oz Technologies.
4 * All rights reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
23 *
24 * Except as contained in this notice, the name of the copyright holder(s)
25 * and author(s) shall not be used in advertising or otherwise to promote
26 * the sale, use or other dealings in this Software without prior written
27 * authorization from the copyright holder(s) and author(s).
28 *
29 * Author: David Dawes <dawes@XFree86.Org>.
30 */
31
32#ifdef HAVE_XORG_CONFIG_H1
33#include <xorg-config.h>
34#endif
35
36#include "xf86.h"
37#include "xf86Parser.h"
38#include "xf86tokens.h"
39#include "xf86Config.h"
40#include "xf86Priv.h"
41#include "xf86_OSlib.h"
42#include "xf86platformBus.h"
43#include "xf86pciBus.h"
44#ifdef __sparc__
45#include "xf86sbusBus.h"
46#endif
47
48#ifdef sun
49#include <sys/visual_io.h>
50#include <ctype.h>
51#endif
52
53/* Sections for the default built-in configuration. */
54
55#define BUILTIN_DEVICE_NAME"\"Builtin Default %s Device %d\"" \
56 "\"Builtin Default %s Device %d\""
57
58#define BUILTIN_DEVICE_SECTION_PRE"Section \"Device\"\n" "\tIdentifier\t" "\"Builtin Default %s Device %d\""
"\n" "\tDriver\t\"%s\"\n"
\
59 "Section \"Device\"\n" \
60 "\tIdentifier\t" BUILTIN_DEVICE_NAME"\"Builtin Default %s Device %d\"" "\n" \
61 "\tDriver\t\"%s\"\n"
62
63#define BUILTIN_DEVICE_SECTION_POST"EndSection\n\n" \
64 "EndSection\n\n"
65
66#define BUILTIN_DEVICE_SECTION"Section \"Device\"\n" "\tIdentifier\t" "\"Builtin Default %s Device %d\""
"\n" "\tDriver\t\"%s\"\n" "EndSection\n\n"
\
67 BUILTIN_DEVICE_SECTION_PRE"Section \"Device\"\n" "\tIdentifier\t" "\"Builtin Default %s Device %d\""
"\n" "\tDriver\t\"%s\"\n"
\
68 BUILTIN_DEVICE_SECTION_POST"EndSection\n\n"
69
70#define BUILTIN_SCREEN_NAME"\"Builtin Default %s Screen %d\"" \
71 "\"Builtin Default %s Screen %d\""
72
73#define BUILTIN_SCREEN_SECTION"Section \"Screen\"\n" "\tIdentifier\t" "\"Builtin Default %s Screen %d\""
"\n" "\tDevice\t" "\"Builtin Default %s Device %d\"" "\n" "EndSection\n\n"
\
74 "Section \"Screen\"\n" \
75 "\tIdentifier\t" BUILTIN_SCREEN_NAME"\"Builtin Default %s Screen %d\"" "\n" \
76 "\tDevice\t" BUILTIN_DEVICE_NAME"\"Builtin Default %s Device %d\"" "\n" \
77 "EndSection\n\n"
78
79#define BUILTIN_LAYOUT_SECTION_PRE"Section \"ServerLayout\"\n" "\tIdentifier\t\"Builtin Default Layout\"\n" \
80 "Section \"ServerLayout\"\n" \
81 "\tIdentifier\t\"Builtin Default Layout\"\n"
82
83#define BUILTIN_LAYOUT_SCREEN_LINE"\tScreen\t" "\"Builtin Default %s Screen %d\"" "\n" \
84 "\tScreen\t" BUILTIN_SCREEN_NAME"\"Builtin Default %s Screen %d\"" "\n"
85
86#define BUILTIN_LAYOUT_SECTION_POST"EndSection\n\n" \
87 "EndSection\n\n"
88
89static const char **builtinConfig = NULL((void*)0);
90static int builtinLines = 0;
91
92static void listPossibleVideoDrivers(char *matches[], int nmatches);
93
94/*
95 * A built-in config file is stored as an array of strings, with each string
96 * representing a single line. AppendToConfig() breaks up the string "s"
97 * into lines, and appends those lines it to builtinConfig.
98 */
99
100static void
101AppendToList(const char *s, const char ***list, int *lines)
102{
103 char *str, *newstr, *p;
104
105 str = xnfstrdup(s)XNFstrdup(s);
106 for (p = strtok(str, "\n"); p; p = strtok(NULL((void*)0), "\n")) {
107 (*lines)++;
108 *list = xnfrealloc(*list, (*lines + 1) * sizeof(**list))XNFrealloc((void *)(*list), (unsigned long)((*lines + 1) * sizeof
(**list)))
;
109 newstr = xnfalloc(strlen(p) + 2)XNFalloc((unsigned long)(strlen(p) + 2));
110 strcpy(newstr, p)__builtin___strcpy_chk (newstr, p, __builtin_object_size (newstr
, 2 > 1 ? 1 : 0))
;
111 strcat(newstr, "\n")__builtin___strcat_chk (newstr, "\n", __builtin_object_size (
newstr, 2 > 1 ? 1 : 0))
;
112 (*list)[*lines - 1] = newstr;
113 (*list)[*lines] = NULL((void*)0);
114 }
115 free(str);
116}
117
118static void
119FreeList(const char ***list, int *lines)
120{
121 int i;
122
123 for (i = 0; i < *lines; i++) {
124 free((char *) ((*list)[i]));
125 }
126 free(*list);
127 *list = NULL((void*)0);
128 *lines = 0;
129}
130
131static void
132FreeConfig(void)
133{
134 FreeList(&builtinConfig, &builtinLines);
135}
136
137static void
138AppendToConfig(const char *s)
139{
140 AppendToList(s, &builtinConfig, &builtinLines);
141}
142
143Bool
144xf86AutoConfig(void)
145{
146 char *deviceList[20];
147 char **p;
148 const char **cp;
149 char buf[1024];
150 ConfigStatus ret;
151
152 listPossibleVideoDrivers(deviceList, 20);
153
154 for (p = deviceList; *p; p++) {
155 snprintf(buf, sizeof(buf), BUILTIN_DEVICE_SECTION, *p, 0, *p)__builtin___snprintf_chk (buf, sizeof(buf), 0, __builtin_object_size
(buf, 2 > 1 ? 1 : 0), "Section \"Device\"\n" "\tIdentifier\t"
"\"Builtin Default %s Device %d\"" "\n" "\tDriver\t\"%s\"\n"
"EndSection\n\n", *p, 0, *p)
;
156 AppendToConfig(buf);
157 snprintf(buf, sizeof(buf), BUILTIN_SCREEN_SECTION, *p, 0, *p, 0)__builtin___snprintf_chk (buf, sizeof(buf), 0, __builtin_object_size
(buf, 2 > 1 ? 1 : 0), "Section \"Screen\"\n" "\tIdentifier\t"
"\"Builtin Default %s Screen %d\"" "\n" "\tDevice\t" "\"Builtin Default %s Device %d\""
"\n" "EndSection\n\n", *p, 0, *p, 0)
;
158 AppendToConfig(buf);
159 }
160
161 AppendToConfig(BUILTIN_LAYOUT_SECTION_PRE"Section \"ServerLayout\"\n" "\tIdentifier\t\"Builtin Default Layout\"\n");
162 for (p = deviceList; *p; p++) {
163 snprintf(buf, sizeof(buf), BUILTIN_LAYOUT_SCREEN_LINE, *p, 0)__builtin___snprintf_chk (buf, sizeof(buf), 0, __builtin_object_size
(buf, 2 > 1 ? 1 : 0), "\tScreen\t" "\"Builtin Default %s Screen %d\""
"\n", *p, 0)
;
164 AppendToConfig(buf);
165 }
166 AppendToConfig(BUILTIN_LAYOUT_SECTION_POST"EndSection\n\n");
167
168 for (p = deviceList; *p; p++) {
169 free(*p);
170 }
171
172 xf86MsgVerb(X_DEFAULT, 0,
173 "Using default built-in configuration (%d lines)\n",
174 builtinLines);
175
176 xf86MsgVerb(X_DEFAULT, 3, "--- Start of built-in configuration ---\n");
177 for (cp = builtinConfig; *cp; cp++)
178 xf86ErrorFVerb(3, "\t%s", *cp);
179 xf86MsgVerb(X_DEFAULT, 3, "--- End of built-in configuration ---\n");
180
181 xf86initConfigFiles();
182 xf86setBuiltinConfig(builtinConfig);
183 ret = xf86HandleConfigFile(TRUE1);
184 FreeConfig();
185
186 if (ret != CONFIG_OK)
187 xf86Msg(X_ERROR, "Error parsing the built-in default configuration.\n");
188
189 return ret == CONFIG_OK;
190}
191
192static void
193listPossibleVideoDrivers(char *matches[], int nmatches)
194{
195 int i;
196
197 for (i = 0; i < nmatches; i++) {
198 matches[i] = NULL((void*)0);
199 }
200 i = 0;
201
202#ifdef XSERVER_PLATFORM_BUS
203 i = xf86PlatformMatchDriver(matches, nmatches);
204#endif
205#ifdef sun
206 /* Check for driver type based on /dev/fb type and if valid, use
207 it instead of PCI bus probe results */
208 if (xf86Info.consoleFd >= 0 && (i < (nmatches - 1))) {
209 struct vis_identifier visid;
210 const char *cp;
211 int iret;
212
213 SYSCALL(iret = ioctl(xf86Info.consoleFd, VIS_GETIDENTIFIER, &visid))while(((iret = ioctl(xf86Info.consoleFd, VIS_GETIDENTIFIER, &
visid)) == -1) && ((*__error()) == 4))
;
214 if (iret < 0) {
215 int fbfd;
216
217 fbfd = open(xf86SolarisFbDev, O_RDONLY0x0000);
218 if (fbfd >= 0) {
219 SYSCALL(iret = ioctl(fbfd, VIS_GETIDENTIFIER, &visid))while(((iret = ioctl(fbfd, VIS_GETIDENTIFIER, &visid)) ==
-1) && ((*__error()) == 4))
;
220 close(fbfd);
221 }
222 }
223
224 if (iret < 0) {
225 xf86Msg(X_WARNING,
226 "could not get frame buffer identifier from %s\n",
227 xf86SolarisFbDev);
228 }
229 else {
230 xf86Msg(X_PROBED, "console driver: %s\n", visid.name);
231
232 /* Special case from before the general case was set */
233 if (strcmp(visid.name, "NVDAnvda") == 0) {
234 matches[i++] = xnfstrdup("nvidia")XNFstrdup("nvidia");
235 }
236
237 /* General case - split into vendor name (initial all-caps
238 prefix) & driver name (rest of the string). */
239 if (strcmp(visid.name, "SUNWtext") != 0) {
240 for (cp = visid.name; (*cp != '\0') && isupper(*cp); cp++) {
241 /* find end of all uppercase vendor section */
242 }
243 if ((cp != visid.name) && (*cp != '\0')) {
244 char *driverName = xnfstrdup(cp)XNFstrdup(cp);
245 char *vendorName = xnfstrdup(visid.name)XNFstrdup(visid.name);
246
247 vendorName[cp - visid.name] = '\0';
248
249 matches[i++] = vendorName;
250 matches[i++] = driverName;
251 }
252 }
253 }
254 }
255#endif
256#ifdef __sparc__
257 if (i < (nmatches - 1))
258 {
259 char *sbusDriver = sparcDriverName();
260
261 if (sbusDriver)
262 matches[i++] = xnfstrdup(sbusDriver)XNFstrdup(sbusDriver);
263 }
264#endif
265#ifdef XSERVER_LIBPCIACCESS
266 if (i < (nmatches - 1))
267 i += xf86PciMatchDriver(&matches[i], nmatches - i);
268#endif
269
270#if defined(__linux__)
271 matches[i++] = xnfstrdup("modesetting")XNFstrdup("modesetting");
272#endif
273
274#if !defined(sun)
275 /* Fallback to platform default frame buffer driver */
276 if (i < (nmatches - 1)) {
277#if !defined(__linux__) && defined(__sparc__)
278 matches[i++] = xnfstrdup("wsfb")XNFstrdup("wsfb");
279#else
280 matches[i++] = xnfstrdup("fbdev")XNFstrdup("fbdev");
281#endif
282 }
283#endif /* !sun */
284
285 /* Fallback to platform default hardware */
286 if (i < (nmatches - 1)) {
287#if defined(__i386__) || defined(__amd64__1) || defined(__hurd__)
288 matches[i++] = xnfstrdup("vesa")XNFstrdup("vesa");
289#elif defined(__sparc__) && !defined(sun)
290 matches[i++] = xnfstrdup("sunffb")XNFstrdup("sunffb");
291#endif
292 }
293}
294
295/* copy a screen section and enter the desired driver
296 * and insert it at i in the list of screens */
297static Bool
298copyScreen(confScreenPtr oscreen, GDevPtr odev, int i, char *driver)
299{
300 confScreenPtr nscreen;
301 GDevPtr cptr = NULL((void*)0);
302 char *identifier;
303
304 nscreen = malloc(sizeof(confScreenRec));
305 if (!nscreen)
306 return FALSE0;
307 memcpy(nscreen, oscreen, sizeof(confScreenRec))__builtin___memcpy_chk (nscreen, oscreen, sizeof(confScreenRec
), __builtin_object_size (nscreen, 0))
;
308
309 cptr = malloc(sizeof(GDevRec));
310 if (!cptr) {
311 free(nscreen);
312 return FALSE0;
313 }
314 memcpy(cptr, odev, sizeof(GDevRec))__builtin___memcpy_chk (cptr, odev, sizeof(GDevRec), __builtin_object_size
(cptr, 0))
;
315
316 if (asprintf(&identifier, "Autoconfigured Video Device %s", driver)
317 == -1) {
318 free(cptr);
319 free(nscreen);
320 return FALSE0;
321 }
322 cptr->driver = driver;
323 cptr->identifier = identifier;
324
325 xf86ConfigLayout.screens[i].screen = nscreen;
326
327 /* now associate the new driver entry with the new screen entry */
328 xf86ConfigLayout.screens[i].screen->device = cptr;
329 cptr->myScreenSection = xf86ConfigLayout.screens[i].screen;
330
331 return TRUE1;
332}
333
334GDevPtr
335autoConfigDevice(GDevPtr preconf_device)
336{
337 GDevPtr ptr = NULL((void*)0);
338 char *matches[20]; /* If we have more than 20 drivers we're in trouble */
339 int num_matches = 0, num_screens = 0, i;
340 screenLayoutPtr slp;
341
342 if (!xf86configptr) {
1
Assuming 'xf86configptr' is non-null
2
Taking false branch
343 return NULL((void*)0);
344 }
345
346 /* If there's a configured section with no driver chosen, use it */
347 if (preconf_device) {
3
Assuming 'preconf_device' is null
4
Taking false branch
348 ptr = preconf_device;
349 }
350 else {
351 ptr = calloc(1, sizeof(GDevRec));
5
Memory is allocated
352 if (!ptr) {
6
Assuming 'ptr' is non-null
7
Taking false branch
353 return NULL((void*)0);
354 }
355 ptr->chipID = -1;
356 ptr->chipRev = -1;
357 ptr->irq = -1;
358
359 ptr->active = TRUE1;
360 ptr->claimed = FALSE0;
361 ptr->identifier = "Autoconfigured Video Device";
362 ptr->driver = NULL((void*)0);
363 }
364 if (!ptr->driver) {
8
Taking true branch
365 /* get all possible video drivers and count them */
366 listPossibleVideoDrivers(matches, 20);
367 for (; matches[num_matches]; num_matches++) {
9
Loop condition is true. Entering loop body
10
Loop condition is false. Execution continues on line 372
368 xf86Msg(X_DEFAULT, "Matched %s as autoconfigured driver %d\n",
369 matches[num_matches], num_matches);
370 }
371
372 slp = xf86ConfigLayout.screens;
373 if (slp) {
11
Assuming 'slp' is non-null
12
Taking true branch
374 /* count the number of screens and make space for
375 * a new screen for each additional possible driver
376 * minus one for the already existing first one
377 * plus one for the terminating NULL */
378 for (; slp[num_screens].screen; num_screens++);
13
Loop condition is true. Entering loop body
14
Loop condition is false. Execution continues on line 379
379 xf86ConfigLayout.screens = xnfcalloc(num_screens + num_matches,XNFcalloc((unsigned long)(num_screens + num_matches)*(unsigned
long)(sizeof(screenLayoutRec)))
380 sizeof(screenLayoutRec))XNFcalloc((unsigned long)(num_screens + num_matches)*(unsigned
long)(sizeof(screenLayoutRec)))
;
381 xf86ConfigLayout.screens[0] = slp[0];
382
383 /* do the first match and set that for the original first screen */
384 ptr->driver = matches[0];
385 if (!xf86ConfigLayout.screens[0].screen->device) {
15
Taking false branch
386 xf86ConfigLayout.screens[0].screen->device = ptr;
387 ptr->myScreenSection = xf86ConfigLayout.screens[0].screen;
388 }
389
390 /* for each other driver found, copy the first screen, insert it
391 * into the list of screens and set the driver */
392 i = 0;
393 while (i++ < num_matches) {
16
Loop condition is true. Entering loop body
394 if (!copyScreen(slp[0].screen, ptr, i, matches[i]))
17
Taking true branch
395 return NULL((void*)0);
18
Within the expansion of the macro 'NULL':
a
Potential leak of memory pointed to by 'ptr'
396 }
397
398 /* shift the rest of the original screen list
399 * to the end of the current screen list
400 *
401 * TODO Handle rest of multiple screen sections */
402 for (i = 1; i < num_screens; i++) {
403 xf86ConfigLayout.screens[i + num_matches] = slp[i];
404 }
405 xf86ConfigLayout.screens[num_screens + num_matches - 1].screen =
406 NULL((void*)0);
407 free(slp);
408 }
409 else {
410 /* layout does not have any screens, not much to do */
411 ptr->driver = matches[0];
412 for (i = 1; matches[i]; i++) {
413 if (matches[i] != matches[0]) {
414 free(matches[i]);
415 }
416 }
417 }
418 }
419
420 xf86Msg(X_DEFAULT, "Assigned the driver to the xf86ConfigLayout\n");
421
422 return ptr;
423}