Bug Summary

File:test/test-migration.c
Location:line 44, column 10
Description:Call to function 'mktemp' is insecure as it always creates or uses insecure temporary file. Use 'mkstemp' instead

Annotated Source Code

1/*
2 * fontconfig/test/test-migration.c
3 *
4 * Copyright © 2000 Keith Packard
5 * Copyright © 2013 Akira TAGOH
6 *
7 * Permission to use, copy, modify, distribute, and sell this software and its
8 * documentation for any purpose is hereby granted without fee, provided that
9 * the above copyright notice appear in all copies and that both that
10 * copyright notice and this permission notice appear in supporting
11 * documentation, and that the name of the author(s) not be used in
12 * advertising or publicity pertaining to distribution of the software without
13 * specific, written prior permission. The authors make no
14 * representations about the suitability of this software for any purpose. It
15 * is provided "as is" without express or implied warranty.
16 *
17 * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
18 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
19 * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR
20 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
22 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
23 * PERFORMANCE OF THIS SOFTWARE.
24 */
25#include <stdio.h>
26#include <stdlib.h>
27#include <string.h>
28#include <unistd.h>
29#include <sys/types.h>
30#include <dirent.h>
31#ifndef HAVE_STRUCT_DIRENT_D_TYPE
32#include <sys/types.h>
33#include <sys/stat.h>
34#include <unistd.h>
35#endif
36#include <fontconfig/fontconfig.h>
37
38#ifdef HAVE_MKDTEMP
39#define fc_mkdtemp mkdtemp
40#else
41char *
42fc_mkdtemp (char *template)
43{
44 if (!mktemp (template) || mkdir (template, 0700))
Call to function 'mktemp' is insecure as it always creates or uses insecure temporary file. Use 'mkstemp' instead
45 return NULL((void *)0);
46
47 return template;
48}
49#endif
50
51FcBool
52mkdir_p(const char *dir)
53{
54 char *parent;
55 FcBool ret;
56
57 if (strlen (dir) == 0)
58 return FcFalse0;
59 parent = (char *) FcStrDirname ((const FcChar8 *)dir);
60 if (!parent)
61 return FcFalse0;
62 if (access (parent, F_OK0) == 0)
63 ret = mkdir (dir, 0755) == 0 && chmod (dir, 0755) == 0;
64 else if (access (parent, F_OK0) == -1)
65 ret = mkdir_p (parent) && (mkdir (dir, 0755) == 0) && chmod (dir, 0755) == 0;
66 else
67 ret = FcFalse0;
68 free (parent);
69
70 return ret;
71}
72
73FcBool
74unlink_dirs(const char *dir)
75{
76 DIR *d = opendir (dir);
77 struct dirent *e;
78 size_t len = strlen (dir);
79 char *n = NULL((void *)0);
80 FcBool ret = FcTrue1;
81#ifndef HAVE_STRUCT_DIRENT_D_TYPE
82 struct stat statb;
83#endif
84
85 if (!d)
86 return FcFalse0;
87 while ((e = readdir(d)) != NULL((void *)0))
88 {
89 size_t l;
90
91 if (strcmp (e->d_name, ".") == 0 ||
92 strcmp (e->d_name, "..") == 0)
93 continue;
94 l = strlen (e->d_name) + 1;
95 if (n)
96 free (n);
97 n = malloc (l + len + 1);
98 strcpy (n, dir)__builtin___strcpy_chk (n, dir, __builtin_object_size (n, 2 >
1 ? 1 : 0))
;
99 n[len] = '/';
100 strcpy (&n[len + 1], e->d_name)__builtin___strcpy_chk (&n[len + 1], e->d_name, __builtin_object_size
(&n[len + 1], 2 > 1 ? 1 : 0))
;
101#ifdef HAVE_STRUCT_DIRENT_D_TYPE
102 if (e->d_type == DT_DIR4)
103#else
104 if (stat (n, &statb) == -1)
105 {
106 fprintf (stderr__stderrp, "E: %s\n", n);
107 ret = FcFalse0;
108 break;
109 }
110 if (S_ISDIR (statb.st_mode)(((statb.st_mode) & 0170000) == 0040000))
111#endif
112 {
113 if (!unlink_dirs (n))
114 {
115 fprintf (stderr__stderrp, "E: %s\n", n);
116 ret = FcFalse0;
117 break;
118 }
119 }
120 else
121 {
122 if (unlink (n) == -1)
123 {
124 fprintf (stderr__stderrp, "E: %s\n", n);
125 ret = FcFalse0;
126 break;
127 }
128 }
129 }
130 if (n)
131 free (n);
132 closedir (d);
133
134 if (rmdir (dir) == -1)
135 {
136 fprintf (stderr__stderrp, "E: %s\n", dir);
137 return FcFalse0;
138 }
139
140 return ret;
141}
142
143int
144main(void)
145{
146 char template[32] = "fontconfig-XXXXXXXX";
147 char *tmp = fc_mkdtemp (template);
148 size_t len = strlen (tmp), xlen, dlen;
149 char xdg[256], confd[256], fn[256], nfn[256], ud[256], nud[256];
150 int ret = -1;
151 FILE *fp;
152 char *content = "<fontconfig></fontconfig>";
153
154 strcpy (xdg, tmp)__builtin___strcpy_chk (xdg, tmp, __builtin_object_size (xdg,
2 > 1 ? 1 : 0))
;
155 strcpy (&xdg[len], "/.config")__builtin___strcpy_chk (&xdg[len], "/.config", __builtin_object_size
(&xdg[len], 2 > 1 ? 1 : 0))
;
156 setenv ("HOME", tmp, 1);
157 setenv ("XDG_CONFIG_HOME", xdg, 1);
158 xlen = strlen (xdg);
159 strcpy (confd, xdg)__builtin___strcpy_chk (confd, xdg, __builtin_object_size (confd
, 2 > 1 ? 1 : 0))
;
160 strcpy (&confd[xlen], "/fontconfig")__builtin___strcpy_chk (&confd[xlen], "/fontconfig", __builtin_object_size
(&confd[xlen], 2 > 1 ? 1 : 0))
;
161 dlen = strlen (confd);
162 /* In case there are no configuration files nor directory */
163 FcInit ();
164 if (access (confd, F_OK0) == 0)
165 {
166 fprintf (stderr__stderrp, "%s unexpectedly exists\n", confd);
167 goto bail;
168 }
169 FcFini ();
170 if (!unlink_dirs (tmp))
171 {
172 fprintf (stderr__stderrp, "Unable to clean up\n");
173 goto bail;
174 }
175 /* In case there are the user configuration file */
176 strcpy (fn, tmp)__builtin___strcpy_chk (fn, tmp, __builtin_object_size (fn, 2
> 1 ? 1 : 0))
;
177 strcpy (&fn[len], "/.fonts.conf")__builtin___strcpy_chk (&fn[len], "/.fonts.conf", __builtin_object_size
(&fn[len], 2 > 1 ? 1 : 0))
;
178 strcpy (nfn, confd)__builtin___strcpy_chk (nfn, confd, __builtin_object_size (nfn
, 2 > 1 ? 1 : 0))
;
179 strcpy (&nfn[dlen], "/fonts.conf")__builtin___strcpy_chk (&nfn[dlen], "/fonts.conf", __builtin_object_size
(&nfn[dlen], 2 > 1 ? 1 : 0))
;
180 if (!mkdir_p (confd))
181 {
182 fprintf (stderr__stderrp, "Unable to create a config dir: %s\n", confd);
183 goto bail;
184 }
185 if ((fp = fopen (fn, "wb")) == NULL((void *)0))
186 {
187 fprintf (stderr__stderrp, "Unable to create a config file: %s\n", fn);
188 goto bail;
189 }
190 fwrite (content, sizeof (char), strlen (content), fp);
191 fclose (fp);
192 FcInit ();
193 if (access (nfn, F_OK0) != 0)
194 {
195 fprintf (stderr__stderrp, "migration failed for %s\n", nfn);
196 goto bail;
197 }
198 FcFini ();
199 if (!unlink_dirs (tmp))
200 {
201 fprintf (stderr__stderrp, "Unable to clean up\n");
202 goto bail;
203 }
204 /* In case there are the user configuration dir */
205 strcpy (ud, tmp)__builtin___strcpy_chk (ud, tmp, __builtin_object_size (ud, 2
> 1 ? 1 : 0))
;
206 strcpy (&ud[len], "/.fonts.conf.d")__builtin___strcpy_chk (&ud[len], "/.fonts.conf.d", __builtin_object_size
(&ud[len], 2 > 1 ? 1 : 0))
;
207 strcpy (nud, confd)__builtin___strcpy_chk (nud, confd, __builtin_object_size (nud
, 2 > 1 ? 1 : 0))
;
208 strcpy (&nud[dlen], "/conf.d")__builtin___strcpy_chk (&nud[dlen], "/conf.d", __builtin_object_size
(&nud[dlen], 2 > 1 ? 1 : 0))
;
209 if (!mkdir_p (ud))
210 {
211 fprintf (stderr__stderrp, "Unable to create a config dir: %s\n", ud);
212 goto bail;
213 }
214 FcInit ();
215 if (access (nud, F_OK0) != 0)
216 {
217 fprintf (stderr__stderrp, "migration failed for %s\n", nud);
218 goto bail;
219 }
220 FcFini ();
221
222 ret = 0;
223bail:
224 unlink_dirs (tmp);
225
226 return ret;
227}