File: | hw/xfree86/common/xf86AutoConfig.c |
Location: | line 385, column 18 |
Description: | Access to field 'device' results in a dereference of a null pointer (loaded from field 'screen') |
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 | ||||
89 | static const char **builtinConfig = NULL((void*)0); | |||
90 | static int builtinLines = 0; | |||
91 | ||||
92 | static 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 | ||||
100 | static void | |||
101 | AppendToList(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 | ||||
118 | static void | |||
119 | FreeList(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 | ||||
131 | static void | |||
132 | FreeConfig(void) | |||
133 | { | |||
134 | FreeList(&builtinConfig, &builtinLines); | |||
135 | } | |||
136 | ||||
137 | static void | |||
138 | AppendToConfig(const char *s) | |||
139 | { | |||
140 | AppendToList(s, &builtinConfig, &builtinLines); | |||
141 | } | |||
142 | ||||
143 | Bool | |||
144 | xf86AutoConfig(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 | ||||
192 | static void | |||
193 | listPossibleVideoDrivers(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 */ | |||
297 | static Bool | |||
298 | copyScreen(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 | ||||
334 | GDevPtr | |||
335 | autoConfigDevice(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) { | |||
| ||||
343 | return NULL((void*)0); | |||
344 | } | |||
345 | ||||
346 | /* If there's a configured section with no driver chosen, use it */ | |||
347 | if (preconf_device) { | |||
348 | ptr = preconf_device; | |||
349 | } | |||
350 | else { | |||
351 | ptr = calloc(1, sizeof(GDevRec)); | |||
352 | if (!ptr) { | |||
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) { | |||
365 | /* get all possible video drivers and count them */ | |||
366 | listPossibleVideoDrivers(matches, 20); | |||
367 | for (; matches[num_matches]; num_matches++) { | |||
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) { | |||
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++); | |||
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) { | |||
| ||||
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) { | |||
394 | if (!copyScreen(slp[0].screen, ptr, i, matches[i])) | |||
395 | return NULL((void*)0); | |||
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 | } |