Bug Summary

File:compress.c
Warning:line 889, column 8
This function call is prohibited after a successful vfork

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name compress.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/builds/rootkea/file/src -resource-dir /usr/lib/llvm-13/lib/clang/13.0.0 -D HAVE_CONFIG_H -I . -I .. -D MAGIC="/usr/local/share/misc/magic" -D PIC -U NDEBUG -internal-isystem /usr/lib/llvm-13/lib/clang/13.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/11/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O0 -Wwrite-strings -fconst-strings -fdebug-compilation-dir=/builds/rootkea/file/src -ferror-limit 19 -fvisibility hidden -fgnuc-version=4.2.1 -analyzer-checker valist,nullability,optin -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /builds/rootkea/file/scan-build/2021-10-29-033212-8365-1 -x c compress.c
1/*
2 * Copyright (c) Ian F. Darwin 1986-1995.
3 * Software written by Ian F. Darwin and others;
4 * maintained 1995-present by Christos Zoulas and others.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice immediately at the beginning of the file, without modification,
11 * this list of conditions, and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
20 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28/*
29 * compress routines:
30 * zmagic() - returns 0 if not recognized, uncompresses and prints
31 * information if recognized
32 * uncompress(method, old, n, newch) - uncompress old into new,
33 * using method, return sizeof new
34 */
35#include "file.h"
36
37#ifndef lint
38FILE_RCSID("@(#)$File: compress.c,v 1.131 2021/10/28 16:01:58 christos Exp $")static const char rcsid[] __attribute__((__used__)) = "@(#)$File: compress.c,v 1.131 2021/10/28 16:01:58 christos Exp $"
;
39#endif
40
41#include "magic.h"
42#include <stdlib.h>
43#ifdef HAVE_UNISTD_H1
44#include <unistd.h>
45#endif
46#include <string.h>
47#include <errno(*__errno_location ()).h>
48#include <ctype.h>
49#include <stdarg.h>
50#include <signal.h>
51#ifndef HAVE_SIG_T1
52typedef void (*sig_t)(int);
53#endif /* HAVE_SIG_T */
54#if !defined(__MINGW32__) && !defined(WIN32) && !defined(__MINGW64__)
55#include <sys/ioctl.h>
56#endif
57#ifdef HAVE_SYS_WAIT_H1
58#include <sys/wait.h>
59#endif
60#if defined(HAVE_SYS_TIME_H1)
61#include <sys/time.h>
62#endif
63
64#if defined(HAVE_ZLIB_H1) && defined(ZLIBSUPPORT1)
65#define BUILTIN_DECOMPRESS
66#include <zlib.h>
67#endif
68
69#if defined(HAVE_BZLIB_H1) && defined(BZLIBSUPPORT1)
70#define BUILTIN_BZLIB
71#include <bzlib.h>
72#endif
73
74#if defined(HAVE_LZMA_H1) && defined(XZLIBSUPPORT1)
75#define BUILTIN_XZLIB
76#include <lzma.h>
77#endif
78
79#ifdef DEBUG
80int tty = -1;
81#define DPRINTF(...) do { \
82 if (tty == -1) \
83 tty = open("/dev/tty", O_RDWR02); \
84 if (tty == -1) \
85 abort(); \
86 dprintf(tty, __VA_ARGS__); \
87} while (/*CONSTCOND*/0)
88#else
89#define DPRINTF(...)
90#endif
91
92#ifdef ZLIBSUPPORT1
93/*
94 * The following python code is not really used because ZLIBSUPPORT is only
95 * defined if we have a built-in zlib, and the built-in zlib handles that.
96 * That is not true for android where we have zlib.h and not -lz.
97 */
98static const char zlibcode[] =
99 "import sys, zlib; sys.stdout.write(zlib.decompress(sys.stdin.read()))";
100
101static const char *zlib_args[] = { "python", "-c", zlibcode, NULL((void*)0) };
102
103static int
104zlibcmp(const unsigned char *buf)
105{
106 unsigned short x = 1;
107 unsigned char *s = CAST(unsigned char *, CAST(void *, &x))((unsigned char *)(((void *)(&x))));
108
109 if ((buf[0] & 0xf) != 8 || (buf[0] & 0x80) != 0)
110 return 0;
111 if (s[0] != 1) /* endianness test */
112 x = buf[0] | (buf[1] << 8);
113 else
114 x = buf[1] | (buf[0] << 8);
115 if (x % 31)
116 return 0;
117 return 1;
118}
119#endif
120
121static int
122lzmacmp(const unsigned char *buf)
123{
124 if (buf[0] != 0x5d || buf[1] || buf[2])
125 return 0;
126 if (buf[12] && buf[12] != 0xff)
127 return 0;
128 return 1;
129}
130
131#define gzip_flags"-cd" "-cd"
132#define lrzip_flags"-do" "-do"
133#define lzip_flags"-cd" gzip_flags"-cd"
134
135static const char *gzip_args[] = {
136 "gzip", gzip_flags"-cd", NULL((void*)0)
137};
138static const char *uncompress_args[] = {
139 "uncompress", "-c", NULL((void*)0)
140};
141static const char *bzip2_args[] = {
142 "bzip2", "-cd", NULL((void*)0)
143};
144static const char *lzip_args[] = {
145 "lzip", lzip_flags"-cd", NULL((void*)0)
146};
147static const char *xz_args[] = {
148 "xz", "-cd", NULL((void*)0)
149};
150static const char *lrzip_args[] = {
151 "lrzip", lrzip_flags"-do", NULL((void*)0)
152};
153static const char *lz4_args[] = {
154 "lz4", "-cd", NULL((void*)0)
155};
156static const char *zstd_args[] = {
157 "zstd", "-cd", NULL((void*)0)
158};
159
160#define do_zlib((void*)0) NULL((void*)0)
161#define do_bzlib((void*)0) NULL((void*)0)
162
163privatestatic const struct {
164 union {
165 const char *magic;
166 int (*func)(const unsigned char *);
167 } u;
168 int maglen;
169 const char **argv;
170 void *unused;
171} compr[] = {
172#define METH_FROZEN2 2
173#define METH_BZIP7 7
174#define METH_XZ9 9
175#define METH_LZMA13 13
176#define METH_ZLIB14 14
177 { { .magic = "\037\235" }, 2, gzip_args, NULL((void*)0) }, /* 0, compressed */
178 /* Uncompress can get stuck; so use gzip first if we have it
179 * Idea from Damien Clark, thanks! */
180 { { .magic = "\037\235" }, 2, uncompress_args, NULL((void*)0) },/* 1, compressed */
181 { { .magic = "\037\213" }, 2, gzip_args, do_zlib((void*)0) },/* 2, gzipped */
182 { { .magic = "\037\236" }, 2, gzip_args, NULL((void*)0) }, /* 3, frozen */
183 { { .magic = "\037\240" }, 2, gzip_args, NULL((void*)0) }, /* 4, SCO LZH */
184 /* the standard pack utilities do not accept standard input */
185 { { .magic = "\037\036" }, 2, gzip_args, NULL((void*)0) }, /* 5, packed */
186 { { .magic = "PK\3\4" }, 4, gzip_args, NULL((void*)0) }, /* 6, pkziped */
187 /* ...only first file examined */
188 { { .magic = "BZh" }, 3, bzip2_args, do_bzlib((void*)0) },/* 7, bzip2-ed */
189 { { .magic = "LZIP" }, 4, lzip_args, NULL((void*)0) }, /* 8, lzip-ed */
190 { { .magic = "\3757zXZ\0" },6, xz_args, NULL((void*)0) }, /* 9, XZ Util */
191 { { .magic = "LRZI" }, 4, lrzip_args, NULL((void*)0) }, /* 10, LRZIP */
192 { { .magic = "\004\"M\030" },4, lz4_args, NULL((void*)0) }, /* 11, LZ4 */
193 { { .magic = "\x28\xB5\x2F\xFD" }, 4, zstd_args, NULL((void*)0) },/* 12, zstd */
194 { { .func = lzmacmp }, -13, xz_args, NULL((void*)0) }, /* 13, lzma */
195#ifdef ZLIBSUPPORT1
196 { { .func = zlibcmp }, -2, zlib_args, NULL((void*)0) }, /* 14, zlib */
197#endif
198};
199
200#define OKDATA0 0
201#define NODATA1 1
202#define ERRDATA2 2
203
204privatestatic ssize_t swrite(int, const void *, size_t);
205#if HAVE_FORK1
206privatestatic size_t ncompr = __arraycount(compr)(sizeof(compr) / sizeof(compr[0]));
207privatestatic int uncompressbuf(int, size_t, size_t, const unsigned char *,
208 unsigned char **, size_t *);
209#ifdef BUILTIN_DECOMPRESS
210privatestatic int uncompresszlib(const unsigned char *, unsigned char **, size_t,
211 size_t *, int);
212privatestatic int uncompressgzipped(const unsigned char *, unsigned char **, size_t,
213 size_t *);
214#endif
215#ifdef BUILTIN_BZLIB
216privatestatic int uncompressbzlib(const unsigned char *, unsigned char **, size_t,
217 size_t *);
218#endif
219#ifdef BUILTIN_XZLIB
220privatestatic int uncompressxzlib(const unsigned char *, unsigned char **, size_t,
221 size_t *);
222#endif
223
224static int makeerror(unsigned char **, size_t *, const char *, ...)
225 __attribute__((__format__(__printf__, 3, 4)));
226privatestatic const char *methodname(size_t);
227
228privatestatic int
229format_decompression_error(struct magic_set *ms, size_t i, unsigned char *buf)
230{
231 unsigned char *p;
232 int mime = ms->flags & MAGIC_MIME(0x0000010|0x0000400);
233
234 if (!mime)
235 return file_printf(ms, "ERROR:[%s: %s]", methodname(i), buf);
236
237 for (p = buf; *p; p++)
238 if (!isalnum(*p)((*__ctype_b_loc ())[(int) ((*p))] & (unsigned short int)
_ISalnum)
)
239 *p = '-';
240
241 return file_printf(ms, "application/x-decompression-error-%s-%s",
242 methodname(i), buf);
243}
244
245protected__attribute__ ((__visibility__("hidden"))) int
246file_zmagic(struct magic_set *ms, const struct buffer *b, const char *name)
247{
248 unsigned char *newbuf = NULL((void*)0);
249 size_t i, nsz;
250 char *rbuf;
251 file_pushbuf_t *pb;
252 int urv, prv, rv = 0;
253 int mime = ms->flags & MAGIC_MIME(0x0000010|0x0000400);
254 int fd = b->fd;
255 const unsigned char *buf = CAST(const unsigned char *, b->fbuf)((const unsigned char *)(b->fbuf));
256 size_t nbytes = b->flen;
257 int sa_saved = 0;
258 struct sigaction sig_act;
259
260 if ((ms->flags & MAGIC_COMPRESS0x0000004) == 0)
1
Assuming the condition is false
2
Taking false branch
261 return 0;
262
263 for (i = 0; i < ncompr; i++) {
3
Assuming 'i' is < 'ncompr'
4
Loop condition is true. Entering loop body
264 int zm;
265 if (nbytes < CAST(size_t, abs(compr[i].maglen))((size_t)(abs(compr[i].maglen))))
5
Assuming the condition is false
6
Taking false branch
266 continue;
267 if (compr[i].maglen < 0) {
7
Assuming field 'maglen' is < 0
8
Taking true branch
268 zm = (*compr[i].u.func)(buf);
269 } else {
270 zm = memcmp(buf, compr[i].u.magic,
271 CAST(size_t, compr[i].maglen)((size_t)(compr[i].maglen))) == 0;
272 }
273
274 if (!zm)
9
Assuming 'zm' is not equal to 0
10
Taking false branch
275 continue;
276
277 /* Prevent SIGPIPE death if child dies unexpectedly */
278 if (!sa_saved
10.1
'sa_saved' is 0
) {
11
Taking true branch
279 //We can use sig_act for both new and old, but
280 struct sigaction new_act;
281 memset(&new_act, 0, sizeof(new_act));
282 new_act.sa_handler__sigaction_handler.sa_handler = SIG_IGN((__sighandler_t) 1);
283 sa_saved = sigaction(SIGPIPE13, &new_act, &sig_act) != -1;
12
Assuming the condition is false
284 }
285
286 nsz = nbytes;
287 urv = uncompressbuf(fd, ms->bytes_max, i, buf, &newbuf, &nsz);
13
Calling 'uncompressbuf'
288 DPRINTF("uncompressbuf = %d, %s, %" SIZE_T_FORMAT "u\n", urv,
289 (char *)newbuf, nsz);
290 switch (urv) {
291 case OKDATA0:
292 case ERRDATA2:
293 ms->flags &= ~MAGIC_COMPRESS0x0000004;
294 if (urv == ERRDATA2)
295 prv = format_decompression_error(ms, i, newbuf);
296 else
297 prv = file_buffer(ms, -1, NULL((void*)0), name, newbuf, nsz);
298 if (prv == -1)
299 goto error;
300 rv = 1;
301 if ((ms->flags & MAGIC_COMPRESS_TRANSP0x2000000) != 0)
302 goto out;
303 if (mime != MAGIC_MIME(0x0000010|0x0000400) && mime != 0)
304 goto out;
305 if ((file_printf(ms,
306 mime ? " compressed-encoding=" : " (")) == -1)
307 goto error;
308 if ((pb = file_push_buffer(ms)) == NULL((void*)0))
309 goto error;
310 /*
311 * XXX: If file_buffer fails here, we overwrite
312 * the compressed text. FIXME.
313 */
314 if (file_buffer(ms, -1, NULL((void*)0), NULL((void*)0), buf, nbytes) == -1) {
315 if (file_pop_buffer(ms, pb) != NULL((void*)0))
316 abort();
317 goto error;
318 }
319 if ((rbuf = file_pop_buffer(ms, pb)) != NULL((void*)0)) {
320 if (file_printf(ms, "%s", rbuf) == -1) {
321 free(rbuf);
322 goto error;
323 }
324 free(rbuf);
325 }
326 if (!mime && file_printf(ms, ")") == -1)
327 goto error;
328 /*FALLTHROUGH*/
329 case NODATA1:
330 break;
331 default:
332 abort();
333 /*NOTREACHED*/
334 error:
335 rv = -1;
336 break;
337 }
338 }
339out:
340 DPRINTF("rv = %d\n", rv);
341
342 if (sa_saved && sig_act.sa_handler__sigaction_handler.sa_handler != SIG_IGN((__sighandler_t) 1))
343 (void)sigaction(SIGPIPE13, &sig_act, NULL((void*)0));
344
345 free(newbuf);
346 ms->flags |= MAGIC_COMPRESS0x0000004;
347 DPRINTF("Zmagic returns %d\n", rv);
348 return rv;
349}
350#endif
351/*
352 * `safe' write for sockets and pipes.
353 */
354privatestatic ssize_t
355swrite(int fd, const void *buf, size_t n)
356{
357 ssize_t rv;
358 size_t rn = n;
359
360 do
361 switch (rv = write(fd, buf, n)) {
362 case -1:
363 if (errno(*__errno_location ()) == EINTR4)
364 continue;
365 return -1;
366 default:
367 n -= rv;
368 buf = CAST(const char *, buf)((const char *)(buf)) + rv;
369 break;
370 }
371 while (n > 0);
372 return rn;
373}
374
375
376/*
377 * `safe' read for sockets and pipes.
378 */
379protected__attribute__ ((__visibility__("hidden"))) ssize_t
380sread(int fd, void *buf, size_t n, int canbepipe __attribute__((__unused__)))
381{
382 ssize_t rv;
383#ifdef FIONREAD0x541B
384 int t = 0;
385#endif
386 size_t rn = n;
387
388 if (fd == STDIN_FILENO0)
389 goto nocheck;
390
391#ifdef FIONREAD0x541B
392 if (canbepipe && (ioctl(fd, FIONREAD0x541B, &t) == -1 || t == 0)) {
393#ifdef FD_ZERO
394 ssize_t cnt;
395 for (cnt = 0;; cnt++) {
396 fd_set check;
397 struct timeval tout = {0, 100 * 1000};
398 int selrv;
399
400 FD_ZERO(&check)do { unsigned int __i; fd_set *__arr = (&check); for (__i
= 0; __i < sizeof (fd_set) / sizeof (__fd_mask); ++__i) (
(__arr)->fds_bits)[__i] = 0; } while (0)
;
401 FD_SET(fd, &check)((void) (((&check)->fds_bits)[((fd) / (8 * (int) sizeof
(__fd_mask)))] |= ((__fd_mask) (1UL << ((fd) % (8 * (int
) sizeof (__fd_mask)))))))
;
402
403 /*
404 * Avoid soft deadlock: do not read if there
405 * is nothing to read from sockets and pipes.
406 */
407 selrv = select(fd + 1, &check, NULL((void*)0), NULL((void*)0), &tout);
408 if (selrv == -1) {
409 if (errno(*__errno_location ()) == EINTR4 || errno(*__errno_location ()) == EAGAIN11)
410 continue;
411 } else if (selrv == 0 && cnt >= 5) {
412 return 0;
413 } else
414 break;
415 }
416#endif
417 (void)ioctl(fd, FIONREAD0x541B, &t);
418 }
419
420 if (t > 0 && CAST(size_t, t)((size_t)(t)) < n) {
421 n = t;
422 rn = n;
423 }
424#endif
425
426nocheck:
427 do
428 switch ((rv = read(fd, buf, n))) {
429 case -1:
430 if (errno(*__errno_location ()) == EINTR4)
431 continue;
432 return -1;
433 case 0:
434 return rn - n;
435 default:
436 n -= rv;
437 buf = CAST(char *, CCAST(void *, buf))((char *)(((void *)(uintptr_t)(buf)))) + rv;
438 break;
439 }
440 while (n > 0);
441 return rn;
442}
443
444protected__attribute__ ((__visibility__("hidden"))) int
445file_pipe2file(struct magic_set *ms, int fd, const void *startbuf,
446 size_t nbytes)
447{
448 char buf[4096];
449 ssize_t r;
450 int tfd;
451
452 (void)strlcpy(buf, "/tmp/file.XXXXXX", sizeof buf);
453#ifndef HAVE_MKSTEMP1
454 {
455 char *ptr = mktemp(buf);
456 tfd = open(ptr, O_RDWR02|O_TRUNC01000|O_EXCL0200|O_CREAT0100, 0600);
457 r = errno(*__errno_location ());
458 (void)unlink(ptr);
459 errno(*__errno_location ()) = r;
460 }
461#else
462 {
463 int te;
464 mode_t ou = umask(0);
465 tfd = mkstemp(buf);
466 (void)umask(ou);
467 te = errno(*__errno_location ());
468 (void)unlink(buf);
469 errno(*__errno_location ()) = te;
470 }
471#endif
472 if (tfd == -1) {
473 file_error(ms, errno(*__errno_location ()),
474 "cannot create temporary file for pipe copy");
475 return -1;
476 }
477
478 if (swrite(tfd, startbuf, nbytes) != CAST(ssize_t, nbytes)((ssize_t)(nbytes)))
479 r = 1;
480 else {
481 while ((r = sread(fd, buf, sizeof(buf), 1)) > 0)
482 if (swrite(tfd, buf, CAST(size_t, r)((size_t)(r))) != r)
483 break;
484 }
485
486 switch (r) {
487 case -1:
488 file_error(ms, errno(*__errno_location ()), "error copying from pipe to temp file");
489 return -1;
490 case 0:
491 break;
492 default:
493 file_error(ms, errno(*__errno_location ()), "error while writing to temp file");
494 return -1;
495 }
496
497 /*
498 * We duplicate the file descriptor, because fclose on a
499 * tmpfile will delete the file, but any open descriptors
500 * can still access the phantom inode.
501 */
502 if ((fd = dup2(tfd, fd)) == -1) {
503 file_error(ms, errno(*__errno_location ()), "could not dup descriptor for temp file");
504 return -1;
505 }
506 (void)close(tfd);
507 if (lseek(fd, CAST(off_t, 0)((off_t)(0)), SEEK_SET0) == CAST(off_t, -1)((off_t)(-1))) {
508 file_badseek(ms);
509 return -1;
510 }
511 return fd;
512}
513#if HAVE_FORK1
514#ifdef BUILTIN_DECOMPRESS
515
516#define FHCRC(1 << 1) (1 << 1)
517#define FEXTRA(1 << 2) (1 << 2)
518#define FNAME(1 << 3) (1 << 3)
519#define FCOMMENT(1 << 4) (1 << 4)
520
521
522privatestatic int
523uncompressgzipped(const unsigned char *old, unsigned char **newch,
524 size_t bytes_max, size_t *n)
525{
526 unsigned char flg = old[3];
527 size_t data_start = 10;
528
529 if (flg & FEXTRA(1 << 2)) {
530 if (data_start + 1 >= *n)
531 goto err;
532 data_start += 2 + old[data_start] + old[data_start + 1] * 256;
533 }
534 if (flg & FNAME(1 << 3)) {
535 while(data_start < *n && old[data_start])
536 data_start++;
537 data_start++;
538 }
539 if (flg & FCOMMENT(1 << 4)) {
540 while(data_start < *n && old[data_start])
541 data_start++;
542 data_start++;
543 }
544 if (flg & FHCRC(1 << 1))
545 data_start += 2;
546
547 if (data_start >= *n)
548 goto err;
549
550 *n -= data_start;
551 old += data_start;
552 return uncompresszlib(old, newch, bytes_max, n, 0);
553err:
554 return makeerror(newch, n, "File too short");
555}
556
557privatestatic int
558uncompresszlib(const unsigned char *old, unsigned char **newch,
559 size_t bytes_max, size_t *n, int zlib)
560{
561 int rc;
562 z_stream z;
563
564 if ((*newch = CAST(unsigned char *, malloc(bytes_max + 1))((unsigned char *)(malloc(bytes_max + 1)))) == NULL((void*)0))
565 return makeerror(newch, n, "No buffer, %s", strerror(errno(*__errno_location ())));
566
567 z.next_in = CCAST(Bytef *, old)((Bytef *)(uintptr_t)(old));
568 z.avail_in = CAST(uint32_t, *n)((uint32_t)(*n));
569 z.next_out = *newch;
570 z.avail_out = CAST(unsigned int, bytes_max)((unsigned int)(bytes_max));
571 z.zalloc = Z_NULL0;
572 z.zfree = Z_NULL0;
573 z.opaque = Z_NULL0;
574
575 /* LINTED bug in header macro */
576 rc = zlib ? inflateInit(&z)inflateInit_((&z), "1.2.11", (int)sizeof(z_stream)) : inflateInit2(&z, -15)inflateInit2_((&z), (-15), "1.2.11", (int)sizeof(z_stream
))
;
577 if (rc != Z_OK0)
578 goto err;
579
580 rc = inflate(&z, Z_SYNC_FLUSH2);
581 if (rc != Z_OK0 && rc != Z_STREAM_END1)
582 goto err;
583
584 *n = CAST(size_t, z.total_out)((size_t)(z.total_out));
585 rc = inflateEnd(&z);
586 if (rc != Z_OK0)
587 goto err;
588
589 /* let's keep the nul-terminate tradition */
590 (*newch)[*n] = '\0';
591
592 return OKDATA0;
593err:
594 strlcpy(RCAST(char *, *newch)((char *)(uintptr_t)(*newch)), z.msg ? z.msg : zError(rc), bytes_max);
595 *n = strlen(RCAST(char *, *newch)((char *)(uintptr_t)(*newch)));
596 return ERRDATA2;
597}
598#endif
599
600#ifdef BUILTIN_BZLIB
601privatestatic int
602uncompressbzlib(const unsigned char *old, unsigned char **newch,
603 size_t bytes_max, size_t *n)
604{
605 int rc;
606 bz_stream bz;
607
608 memset(&bz, 0, sizeof(bz));
609 rc = BZ2_bzDecompressInit(&bz, 0, 0);
610 if (rc != BZ_OK0)
611 goto err;
612
613 if ((*newch = CAST(unsigned char *, malloc(bytes_max + 1))((unsigned char *)(malloc(bytes_max + 1)))) == NULL((void*)0))
614 return makeerror(newch, n, "No buffer, %s", strerror(errno(*__errno_location ())));
615
616 bz.next_in = CCAST(char *, RCAST(const char *, old))((char *)(uintptr_t)(((const char *)(uintptr_t)(old))));
617 bz.avail_in = CAST(uint32_t, *n)((uint32_t)(*n));
618 bz.next_out = RCAST(char *, *newch)((char *)(uintptr_t)(*newch));
619 bz.avail_out = CAST(unsigned int, bytes_max)((unsigned int)(bytes_max));
620
621 rc = BZ2_bzDecompress(&bz);
622 if (rc != BZ_OK0 && rc != BZ_STREAM_END4)
623 goto err;
624
625 /* Assume byte_max is within 32bit */
626 /* assert(bz.total_out_hi32 == 0); */
627 *n = CAST(size_t, bz.total_out_lo32)((size_t)(bz.total_out_lo32));
628 rc = BZ2_bzDecompressEnd(&bz);
629 if (rc != BZ_OK0)
630 goto err;
631
632 /* let's keep the nul-terminate tradition */
633 (*newch)[*n] = '\0';
634
635 return OKDATA0;
636err:
637 snprintf(RCAST(char *, *newch)((char *)(uintptr_t)(*newch)), bytes_max, "bunzip error %d", rc);
638 *n = strlen(RCAST(char *, *newch)((char *)(uintptr_t)(*newch)));
639 return ERRDATA2;
640}
641#endif
642
643#ifdef BUILTIN_XZLIB
644privatestatic int
645uncompressxzlib(const unsigned char *old, unsigned char **newch,
646 size_t bytes_max, size_t *n)
647{
648 int rc;
649 lzma_stream xz;
650
651 memset(&xz, 0, sizeof(xz));
652 rc = lzma_auto_decoder(&xz, UINT64_MAX(18446744073709551615UL), 0);
653 if (rc != LZMA_OK)
654 goto err;
655
656 if ((*newch = CAST(unsigned char *, malloc(bytes_max + 1))((unsigned char *)(malloc(bytes_max + 1)))) == NULL((void*)0))
657 return makeerror(newch, n, "No buffer, %s", strerror(errno(*__errno_location ())));
658
659 xz.next_in = CCAST(const uint8_t *, old)((const uint8_t *)(uintptr_t)(old));
660 xz.avail_in = CAST(uint32_t, *n)((uint32_t)(*n));
661 xz.next_out = RCAST(uint8_t *, *newch)((uint8_t *)(uintptr_t)(*newch));
662 xz.avail_out = CAST(unsigned int, bytes_max)((unsigned int)(bytes_max));
663
664 rc = lzma_code(&xz, LZMA_RUN);
665 if (rc != LZMA_OK && rc != LZMA_STREAM_END)
666 goto err;
667
668 *n = CAST(size_t, xz.total_out)((size_t)(xz.total_out));
669
670 lzma_end(&xz);
671
672 /* let's keep the nul-terminate tradition */
673 (*newch)[*n] = '\0';
674
675 return OKDATA0;
676err:
677 snprintf(RCAST(char *, *newch)((char *)(uintptr_t)(*newch)), bytes_max, "unxz error %d", rc);
678 *n = strlen(RCAST(char *, *newch)((char *)(uintptr_t)(*newch)));
679 return ERRDATA2;
680}
681#endif
682
683
684static int
685makeerror(unsigned char **buf, size_t *len, const char *fmt, ...)
686{
687 char *msg;
688 va_list ap;
689 int rv;
690
691 va_start(ap, fmt)__builtin_va_start(ap, fmt);
692 rv = vasprintf(&msg, fmt, ap);
693 va_end(ap)__builtin_va_end(ap);
694 if (rv < 0) {
695 *buf = NULL((void*)0);
696 *len = 0;
697 return NODATA1;
698 }
699 *buf = RCAST(unsigned char *, msg)((unsigned char *)(uintptr_t)(msg));
700 *len = strlen(msg);
701 return ERRDATA2;
702}
703
704static void
705closefd(int *fd, size_t i)
706{
707 if (fd[i] == -1)
708 return;
709 (void) close(fd[i]);
710 fd[i] = -1;
711}
712
713static void
714closep(int *fd)
715{
716 size_t i;
717 for (i = 0; i < 2; i++)
718 closefd(fd, i);
719}
720
721static int
722copydesc(int i, int fd)
723{
724 if (fd == i)
725 return 0; /* "no dup was necessary" */
726 if (dup2(fd, i) == -1) {
727 DPRINTF("dup(%d, %d) failed (%s)\n", fd, i, strerror(errno));
728 exit(1);
729 }
730 return 1;
731}
732
733static pid_t
734writechild(int fd, const void *old, size_t n)
735{
736 pid_t pid;
737
738 /*
739 * fork again, to avoid blocking because both
740 * pipes filled
741 */
742 pid = fork();
743 if (pid == -1) {
744 DPRINTF("Fork failed (%s)\n", strerror(errno));
745 exit(1);
746 }
747 if (pid == 0) {
748 /* child */
749 if (swrite(fd, old, n) != CAST(ssize_t, n)((ssize_t)(n))) {
750 DPRINTF("Write failed (%s)\n", strerror(errno));
751 exit(1);
752 }
753 exit(0);
754 }
755 /* parent */
756 return pid;
757}
758
759static ssize_t
760filter_error(unsigned char *ubuf, ssize_t n)
761{
762 char *p;
763 char *buf;
764
765 ubuf[n] = '\0';
766 buf = RCAST(char *, ubuf)((char *)(uintptr_t)(ubuf));
767 while (isspace(CAST(unsigned char, *buf))((*__ctype_b_loc ())[(int) ((((unsigned char)(*buf))))] &
(unsigned short int) _ISspace)
)
768 buf++;
769 DPRINTF("Filter error[[[%s]]]\n", buf);
770 if ((p = strchr(CAST(char *, buf)((char *)(buf)), '\n')) != NULL((void*)0))
771 *p = '\0';
772 if ((p = strchr(CAST(char *, buf)((char *)(buf)), ';')) != NULL((void*)0))
773 *p = '\0';
774 if ((p = strrchr(CAST(char *, buf)((char *)(buf)), ':')) != NULL((void*)0)) {
775 ++p;
776 while (isspace(CAST(unsigned char, *p))((*__ctype_b_loc ())[(int) ((((unsigned char)(*p))))] & (
unsigned short int) _ISspace)
)
777 p++;
778 n = strlen(p);
779 memmove(ubuf, p, CAST(size_t, n + 1)((size_t)(n + 1)));
780 }
781 DPRINTF("Filter error after[[[%s]]]\n", (char *)ubuf);
782 if (islower(*ubuf)((*__ctype_b_loc ())[(int) ((*ubuf))] & (unsigned short int
) _ISlower)
)
783 *ubuf = toupper(*ubuf);
784 return n;
785}
786
787privatestatic const char *
788methodname(size_t method)
789{
790 switch (method) {
791#ifdef BUILTIN_DECOMPRESS
792 case METH_FROZEN2:
793 case METH_ZLIB14:
794 return "zlib";
795#endif
796#ifdef BUILTIN_BZLIB
797 case METH_BZIP7:
798 return "bzlib";
799#endif
800#ifdef BUILTIN_XZLIB
801 case METH_XZ9:
802 case METH_LZMA13:
803 return "xzlib";
804#endif
805 default:
806 return compr[method].argv[0];
807 }
808}
809
810privatestatic int
811uncompressbuf(int fd, size_t bytes_max, size_t method, const unsigned char *old,
812 unsigned char **newch, size_t* n)
813{
814 int fdp[3][2];
815 int status, rv, w;
816 pid_t pid;
817 pid_t writepid = -1;
818 size_t i;
819 ssize_t r;
820
821 switch (method) {
14
Control jumps to the 'default' case at line 837
822#ifdef BUILTIN_DECOMPRESS
823 case METH_FROZEN2:
824 return uncompressgzipped(old, newch, bytes_max, n);
825 case METH_ZLIB14:
826 return uncompresszlib(old, newch, bytes_max, n, 1);
827#endif
828#ifdef BUILTIN_BZLIB
829 case METH_BZIP7:
830 return uncompressbzlib(old, newch, bytes_max, n);
831#endif
832#ifdef BUILTIN_XZLIB
833 case METH_XZ9:
834 case METH_LZMA13:
835 return uncompressxzlib(old, newch, bytes_max, n);
836#endif
837 default:
838 break;
15
Execution continues on line 841
839 }
840
841 (void)fflush(stdoutstdout);
842 (void)fflush(stderrstderr);
843
844 for (i = 0; i < __arraycount(fdp)(sizeof(fdp) / sizeof(fdp[0])); i++)
16
Loop condition is true. Entering loop body
17
Loop condition is true. Entering loop body
18
Loop condition is true. Entering loop body
19
Loop condition is false. Execution continues on line 861
845 fdp[i][0] = fdp[i][1] = -1;
846
847 /*
848 * There are multithreaded users who run magic_file()
849 * from dozens of threads. If two parallel magic_file() calls
850 * analyze two large compressed files, both will spawn
851 * an uncompressing child here, which writes out uncompressed data.
852 * We read some portion, then close the pipe, then waitpid() the child.
853 * If uncompressed data is larger, child shound get EPIPE and exit.
854 * However, with *parallel* calls OTHER child may unintentionally
855 * inherit pipe fds, thus keeping pipe open and making writes in
856 * our child block instead of failing with EPIPE!
857 * (For the bug to occur, two threads must mutually inherit their pipes,
858 * and both must have large outputs. Thus it happens not that often).
859 * To avoid this, be sure to create pipes with O_CLOEXEC.
860 */
861 if ((fd == -1 && file_pipe_closexec(fdp[STDIN_FILENO0]) == -1) ||
20
Assuming the condition is true
21
Assuming the condition is false
24
Taking false branch
862 file_pipe_closexec(fdp[STDOUT_FILENO1]) == -1 ||
22
Assuming the condition is false
863 file_pipe_closexec(fdp[STDERR_FILENO2]) == -1) {
23
Assuming the condition is false
864 closep(fdp[STDIN_FILENO0]);
865 closep(fdp[STDOUT_FILENO1]);
866 return makeerror(newch, n, "Cannot create pipe, %s",
867 strerror(errno(*__errno_location ())));
868 }
869
870 /* For processes with large mapped virtual sizes, vfork
871 * may be _much_ faster (10-100 times) than fork.
872 */
873 pid = vfork();
874 if (pid == -1) {
25
Taking false branch
875 return makeerror(newch, n, "Cannot vfork, %s",
876 strerror(errno(*__errno_location ())));
877 }
878 if (pid
25.1
'pid' is equal to 0
== 0) {
26
Taking true branch
879 /* child */
880 /* Note: we are after vfork, do not modify memory
881 * in a way which confuses parent. In particular,
882 * do not modify fdp[i][j].
883 */
884 if (fd != -1) {
27
Taking false branch
885 (void) lseek(fd, CAST(off_t, 0)((off_t)(0)), SEEK_SET0);
886 if (copydesc(STDIN_FILENO0, fd))
887 (void) close(fd);
888 } else {
889 if (copydesc(STDIN_FILENO0, fdp[STDIN_FILENO0][0]))
28
This function call is prohibited after a successful vfork
890 (void) close(fdp[STDIN_FILENO0][0]);
891 if (fdp[STDIN_FILENO0][1] > 2)
892 (void) close(fdp[STDIN_FILENO0][1]);
893 }
894 file_clear_closexec(STDIN_FILENO0);
895
896///FIXME: if one of the fdp[i][j] is 0 or 1, this can bomb spectacularly
897 if (copydesc(STDOUT_FILENO1, fdp[STDOUT_FILENO1][1]))
898 (void) close(fdp[STDOUT_FILENO1][1]);
899 if (fdp[STDOUT_FILENO1][0] > 2)
900 (void) close(fdp[STDOUT_FILENO1][0]);
901 file_clear_closexec(STDOUT_FILENO1);
902
903 if (copydesc(STDERR_FILENO2, fdp[STDERR_FILENO2][1]))
904 (void) close(fdp[STDERR_FILENO2][1]);
905 if (fdp[STDERR_FILENO2][0] > 2)
906 (void) close(fdp[STDERR_FILENO2][0]);
907 file_clear_closexec(STDERR_FILENO2);
908
909 (void)execvp(compr[method].argv[0],
910 RCAST(char *const *, RCAST(intptr_t, compr[method].argv))((char *const *)(uintptr_t)(((intptr_t)(uintptr_t)(compr[method
].argv))))
);
911 dprintf(STDERR_FILENO2, "exec `%s' failed, %s",
912 compr[method].argv[0], strerror(errno(*__errno_location ())));
913 _exit(1); /* _exit(), not exit(), because of vfork */
914 }
915 /* parent */
916 /* Close write sides of child stdout/err pipes */
917 for (i = 1; i < __arraycount(fdp)(sizeof(fdp) / sizeof(fdp[0])); i++)
918 closefd(fdp[i], 1);
919 /* Write the buffer data to child stdin, if we don't have fd */
920 if (fd == -1) {
921 closefd(fdp[STDIN_FILENO0], 0);
922 writepid = writechild(fdp[STDIN_FILENO0][1], old, *n);
923 closefd(fdp[STDIN_FILENO0], 1);
924 }
925
926 *newch = CAST(unsigned char *, malloc(bytes_max + 1))((unsigned char *)(malloc(bytes_max + 1)));
927 if (*newch == NULL((void*)0)) {
928 rv = makeerror(newch, n, "No buffer, %s",
929 strerror(errno(*__errno_location ())));
930 goto err;
931 }
932 rv = OKDATA0;
933 r = sread(fdp[STDOUT_FILENO1][0], *newch, bytes_max, 0);
934 if (r <= 0) {
935 DPRINTF("Read stdout failed %d (%s)\n", fdp[STDOUT_FILENO][0],
936 r != -1 ? strerror(errno) : "no data");
937
938 rv = ERRDATA2;
939 if (r == 0 &&
940 (r = sread(fdp[STDERR_FILENO2][0], *newch, bytes_max, 0)) > 0)
941 {
942 r = filter_error(*newch, r);
943 goto ok;
944 }
945 free(*newch);
946 if (r == 0)
947 rv = makeerror(newch, n, "Read failed, %s",
948 strerror(errno(*__errno_location ())));
949 else
950 rv = makeerror(newch, n, "No data");
951 goto err;
952 }
953ok:
954 *n = r;
955 /* NUL terminate, as every buffer is handled here. */
956 (*newch)[*n] = '\0';
957err:
958 closefd(fdp[STDIN_FILENO0], 1);
959 closefd(fdp[STDOUT_FILENO1], 0);
960 closefd(fdp[STDERR_FILENO2], 0);
961
962 w = waitpid(pid, &status, 0);
963wait_err:
964 if (w == -1) {
965 free(*newch);
966 rv = makeerror(newch, n, "Wait failed, %s", strerror(errno(*__errno_location ())));
967 DPRINTF("Child wait return %#x\n", status);
968 } else if (!WIFEXITED(status)(((status) & 0x7f) == 0)) {
969 DPRINTF("Child not exited (%#x)\n", status);
970 } else if (WEXITSTATUS(status)(((status) & 0xff00) >> 8) != 0) {
971 DPRINTF("Child exited (%#x)\n", WEXITSTATUS(status));
972 }
973 if (writepid > 0) {
974 /* _After_ we know decompressor has exited, our input writer
975 * definitely will exit now (at worst, writing fails in it,
976 * since output fd is closed now on the reading size).
977 */
978 w = waitpid(writepid, &status, 0);
979 writepid = -1;
980 goto wait_err;
981 }
982
983 closefd(fdp[STDIN_FILENO0], 0); //why? it is already closed here!
984 DPRINTF("Returning %p n=%" SIZE_T_FORMAT "u rv=%d\n", *newch, *n, rv);
985
986 return rv;
987}
988#endif