From c590b070031df2490afb38d381a5d3c599ab3d93 Mon Sep 17 00:00:00 2001 From: Xin LI Date: Fri, 23 Jan 2015 18:48:59 +0000 Subject: [PATCH] MFC r276577: MFV r276568: Update file to 5.22. --- contrib/file/ChangeLog | 28 ++ contrib/file/Makefile.in | 5 +- contrib/file/README | 32 +- contrib/file/aclocal.m4 | 8 +- contrib/file/configure | 20 +- contrib/file/configure.ac | 2 +- contrib/file/doc/Makefile.in | 2 +- contrib/file/doc/file.man | 5 +- contrib/file/doc/libmagic.man | 13 +- contrib/file/doc/magic.man | 9 +- contrib/file/magic/Localstuff | 2 +- contrib/file/magic/Magdir/cafebabe | 4 +- contrib/file/magic/Magdir/filesystems | 9 +- contrib/file/magic/Magdir/images | 143 +++++-- contrib/file/magic/Magdir/jpeg | 106 +----- contrib/file/magic/Magdir/qt | 19 + contrib/file/magic/Makefile.am | 3 +- contrib/file/magic/Makefile.in | 5 +- contrib/file/missing | 4 +- contrib/file/python/Makefile.in | 2 +- contrib/file/src/Makefile.in | 8 +- contrib/file/src/apprentice.c | 271 ++++++++------ contrib/file/src/compress.c | 17 +- contrib/file/src/elfclass.h | 16 +- contrib/file/src/file.c | 3 +- contrib/file/src/file.h | 8 +- contrib/file/src/file_opts.h | 7 +- contrib/file/src/funcs.c | 27 +- contrib/file/src/getline.c | 2 +- contrib/file/src/magic.c | 8 +- contrib/file/src/magic.h | 1 + contrib/file/src/magic.h.in | 1 + contrib/file/src/readelf.c | 520 +++++++++++++++----------- contrib/file/src/softmagic.c | 41 +- contrib/file/tests/Makefile.in | 2 +- lib/libmagic/config.h | 6 +- 36 files changed, 797 insertions(+), 562 deletions(-) create mode 100644 contrib/file/magic/Magdir/qt diff --git a/contrib/file/ChangeLog b/contrib/file/ChangeLog index 1bc3de908365..98cdcc46b6ab 100644 --- a/contrib/file/ChangeLog +++ b/contrib/file/ChangeLog @@ -1,3 +1,29 @@ +2015-01-02 15:15 Christos Zoulas + + * release 5.22 + +2015-01-01 12:01 Christos Zoulas + + * add indirect relative for TIFF/Exif + +2014-12-16 18:10 Christos Zoulas + + * restructure elf note printing to avoid repeated messages + * add note limit, suggested by Alexander Cherepanov + +2014-12-16 16:53 Christos Zoulas + + * Bail out on partial pread()'s (Alexander Cherepanov) + * Fix incorrect bounds check in file_printable (Alexander Cherepanov) + +2014-12-11 20:01 Christos Zoulas + + * PR/405: ignore SIGPIPE from uncompress programs + * change printable -> file_printable and use it in + more places for safety + * in ELF, instead of "(uses dynamic libraries)" when PT_INTERP + is present print the interpreter name. + 2014-12-10 20:01 Christos Zoulas * release 5.21 @@ -23,6 +49,8 @@ - reduce the number of recursion levels from 20 to 10 - preserve error messages in indirect magic handling + This is tracked as CVE-2014-8116 and CVE-2014-8117 + 2014-11-12 10:30 Christos Zoulas * fix bogus free in the user buffer case. diff --git a/contrib/file/Makefile.in b/contrib/file/Makefile.in index 095c79144426..eed031897ffd 100644 --- a/contrib/file/Makefile.in +++ b/contrib/file/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.14.1 from Makefile.am. +# Makefile.in generated by automake 1.14 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. @@ -618,10 +618,9 @@ distcheck: dist && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && am__cwd=`pwd` \ && $(am__cd) $(distdir)/_build \ - && ../configure \ + && ../configure --srcdir=.. --prefix="$$dc_install_base" \ $(AM_DISTCHECK_CONFIGURE_FLAGS) \ $(DISTCHECK_CONFIGURE_FLAGS) \ - --srcdir=.. --prefix="$$dc_install_base" \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ diff --git a/contrib/file/README b/contrib/file/README index cfc530f520e9..81a52216c481 100644 --- a/contrib/file/README +++ b/contrib/file/README @@ -1,6 +1,6 @@ ## README for file(1) Command ## - @(#) $File: README,v 1.48 2014/03/07 13:55:30 christos Exp $ + @(#) $File: README,v 1.49 2015/01/02 20:23:04 christos Exp $ Mailing List: file@mx.gw.com Mailing List archives: http://mx.gw.com/pipermail/file/ @@ -25,8 +25,8 @@ A public read-only git repository of the same sources is available at: https://github.com/file/file -The major changes for 5.x are CDF file parsing, indirect magic, and -overhaul in mime and ascii encoding handling. +The major changes for 5.x are CDF file parsing, indirect magic, name/use +(recursion) and overhaul in mime and ascii encoding handling. The major feature of 4.x is the refactoring of the code into a library, and the re-write of the file command in terms of that library. The library @@ -67,33 +67,41 @@ in magic(5) format please, to the maintainer, Christos Zoulas. COPYING - read this first. README - read this second (you are currently reading this file). INSTALL - read on how to install - src/apprentice.c - parses /etc/magic to learn magic +src/asctime_r.c - replacement for OS's that don't have it. src/apptype.c - used for OS/2 specific application type magic src/asprintf.c - replacement for OS's that don't have it. src/ascmagic.c - third & last set of tests, based on hardwired assumptions. -src/asctime_r.c - for systems that don't have it. -src/asprintf.c - for systems that don't have it. -src/cdf.c - parser for Microsoft Compound Document Files +src/asctime_r.c - replacement for OS's that don't have it. +src/asprintf.c - replacement for OS's that don't have it. +src/cdf.[ch] - parser for Microsoft Compound Document Files src/cdf_time.c - time converter for CDF. src/compress.c - handles decompressing files to look inside. -src/ctime_r.c - for systems that don't have it. +src/ctime_r.c - replacement for OS's that don't have it. +src/elfclass.h - common code for elf 32/64. src/encoding.c - handles unicode encodings src/file.c - the main program src/file.h - header file +src/file_opts.h - list of options +src/fmtcheck.c - replacement for OS's that don't have it. src/fsmagic.c - first set of tests the program runs, based on filesystem info src/funcs.c - utilility functions -src/getopt_long.c - for systems that don't have it. -src/getline.c - for systems that don't have it. +src/getline.c - replacement for OS's that don't have it. +src/getopt_long.c - replacement for OS's that don't have it. src/is_tar.c, tar.h - knows about tarchives (courtesy John Gilmore). src/names.h - header file for ascmagic.c +src/magic.h.in - source file for magic.h src/magic.c - the libmagic api +src/pread.c - replacement for OS's that don't have it. src/print.c - print results, errors, warnings. src/readcdf.c - CDF wrapper. src/readelf.[ch] - Stand-alone elf parsing code. src/softmagic.c - 2nd set of tests, based on /etc/magic -src/strlcat.c - for systems that don't have it. -src/strlcpy.c - for systems that don't have it. +src/mygetopt.h - replacement for OS's that don't have it. +src/strcasestr.c - replacement for OS's that don't have it. +src/strlcat.c - replacement for OS's that don't have it. +src/strlcpy.c - replacement for OS's that don't have it. +src/tar.h - tar file definitions src/vasprintf.c - for systems that don't have it. doc/file.man - man page for the command doc/magic.man - man page for the magic file, courtesy Guy Harris. diff --git a/contrib/file/aclocal.m4 b/contrib/file/aclocal.m4 index e575239ba0df..a9ddc4b1f9d8 100644 --- a/contrib/file/aclocal.m4 +++ b/contrib/file/aclocal.m4 @@ -1,4 +1,4 @@ -# generated automatically by aclocal 1.14.1 -*- Autoconf -*- +# generated automatically by aclocal 1.14 -*- Autoconf -*- # Copyright (C) 1996-2013 Free Software Foundation, Inc. @@ -21,7 +21,7 @@ If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) # visibility.m4 serial 5 (gettext-0.18.2) -dnl Copyright (C) 2005, 2008, 2010-2014 Free Software Foundation, Inc. +dnl Copyright (C) 2005, 2008, 2010-2013 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. @@ -113,7 +113,7 @@ AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.14' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. -m4_if([$1], [1.14.1], [], +m4_if([$1], [1.14], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) @@ -129,7 +129,7 @@ m4_define([_AM_AUTOCONF_VERSION], []) # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], -[AM_AUTOMAKE_VERSION([1.14.1])dnl +[AM_AUTOMAKE_VERSION([1.14])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) diff --git a/contrib/file/configure b/contrib/file/configure index ab761d46c277..3cf1d770bbf6 100755 --- a/contrib/file/configure +++ b/contrib/file/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for file 5.21. +# Generated by GNU Autoconf 2.69 for file 5.22. # # Report bugs to . # @@ -590,8 +590,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='file' PACKAGE_TARNAME='file' -PACKAGE_VERSION='5.21' -PACKAGE_STRING='file 5.21' +PACKAGE_VERSION='5.22' +PACKAGE_STRING='file 5.22' PACKAGE_BUGREPORT='christos@astron.com' PACKAGE_URL='' @@ -1327,7 +1327,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures file 5.21 to adapt to many kinds of systems. +\`configure' configures file 5.22 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1397,7 +1397,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of file 5.21:";; + short | recursive ) echo "Configuration of file 5.22:";; esac cat <<\_ACEOF @@ -1507,7 +1507,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -file configure 5.21 +file configure 5.22 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2163,7 +2163,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by file $as_me 5.21, which was +It was created by file $as_me 5.22, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -3029,7 +3029,7 @@ fi # Define the identity of the package. PACKAGE='file' - VERSION='5.21' + VERSION='5.22' cat >>confdefs.h <<_ACEOF @@ -14998,7 +14998,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by file $as_me 5.21, which was +This file was extended by file $as_me 5.22, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -15064,7 +15064,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -file config.status 5.21 +file config.status 5.22 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/contrib/file/configure.ac b/contrib/file/configure.ac index 23f6f5a7dc96..1e2457c12146 100644 --- a/contrib/file/configure.ac +++ b/contrib/file/configure.ac @@ -1,5 +1,5 @@ dnl Process this file with autoconf to produce a configure script. -AC_INIT([file],[5.21],[christos@astron.com]) +AC_INIT([file],[5.22],[christos@astron.com]) AM_INIT_AUTOMAKE([subdir-objects foreign]) m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) diff --git a/contrib/file/doc/Makefile.in b/contrib/file/doc/Makefile.in index 891748776c3c..8d0fa7b8df61 100644 --- a/contrib/file/doc/Makefile.in +++ b/contrib/file/doc/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.14.1 from Makefile.am. +# Makefile.in generated by automake 1.14 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. diff --git a/contrib/file/doc/file.man b/contrib/file/doc/file.man index d9ba4361fddb..109c67686111 100644 --- a/contrib/file/doc/file.man +++ b/contrib/file/doc/file.man @@ -1,5 +1,5 @@ -.\" $File: file.man,v 1.106 2014/03/07 23:11:51 christos Exp $ -.Dd December 3, 2014 +.\" $File: file.man,v 1.111 2014/12/16 23:18:40 christos Exp $ +.Dd December 16, 2014 .Dt FILE __CSECTION__ .Os .Sh NAME @@ -310,6 +310,7 @@ Set various parameter limits. .It Sy "Name" Ta Sy "Default" Ta Sy "Explanation" .It Li indir Ta 15 Ta recursion limit for indirect magic .It Li name Ta 30 Ta use count limit for name/use magic +.It Li elf_notes Ta 256 Ta max ELF notes processed .It Li elf_phnum Ta 128 Ta max ELF program sections processed .It Li elf_shnum Ta 32768 Ta max ELF sections processed .El diff --git a/contrib/file/doc/libmagic.man b/contrib/file/doc/libmagic.man index 537cd7b70d58..3c907cad9b35 100644 --- a/contrib/file/doc/libmagic.man +++ b/contrib/file/doc/libmagic.man @@ -1,4 +1,4 @@ -.\" $File: libmagic.man,v 1.33 2014/11/28 02:46:39 christos Exp $ +.\" $File: libmagic.man,v 1.34 2014/12/16 23:18:40 christos Exp $ .\" .\" Copyright (c) Christos Zoulas 2003. .\" All Rights Reserved. @@ -25,7 +25,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd November 27, 2014 +.Dd December 16, 2014 .Dt LIBMAGIC 3 .Os .Sh NAME @@ -284,6 +284,7 @@ library. .It Sy "Parameter" Ta Sy "Type" Ta Sy "Default" .It Li MAGIC_PARAM_INDIR_MAX Ta size_t Ta 15 .It Li MAGIC_PARAM_NAME_MAX Ta size_t Ta 30 +.It Li MAGIC_PARAM_ELF_NOTES_MAX Ta size_t Ta 256 .It Li MAGIC_PARAM_ELF_PHNUM_MAX Ta size_t Ta 128 .It Li MAGIC_PARAM_ELF_SHNUM_MAX Ta size_t Ta 32768 .El @@ -303,12 +304,16 @@ The parameter controls the maximum number of calls for name/use. .Pp The +.Dv MAGIC_PARAM_NOTES_MAX +parameter controls how many ELF notes will be processed. +.Pp +The .Dv MAGIC_PARAM_PHNUM_MAX -parameter controls how many elf program sections will be processed. +parameter controls how many ELF program sections will be processed. .Pp The .Dv MAGIC_PARAM_SHNUM_MAX -parameter controls how many elf sections will be processed. +parameter controls how many ELF sections will be processed. .Pp The .Fn magic_version diff --git a/contrib/file/doc/magic.man b/contrib/file/doc/magic.man index 762da481231d..b6523f2d9e4b 100644 --- a/contrib/file/doc/magic.man +++ b/contrib/file/doc/magic.man @@ -1,5 +1,5 @@ -.\" $File: magic.man,v 1.84 2014/06/03 19:01:34 christos Exp $ -.Dd June 3, 2014 +.\" $File: magic.man,v 1.85 2015/01/01 17:07:34 christos Exp $ +.Dd January 1, 2015 .Dt MAGIC __FSECTION__ .Os .\" install as magic.4 on USG, magic.5 on V7, Berkeley and Linux systems. @@ -200,6 +200,11 @@ interpreted as a UNIX-style date, but interpreted as local time rather than UTC. .It Dv indirect Starting at the given offset, consult the magic database again. +The offset of th +.Dv indirect +magic is by default absolute in the file, but one can specify +.Dv /r +to indicate that the offset is relative from the beginning of the entry. .It Dv name Define a .Dq named diff --git a/contrib/file/magic/Localstuff b/contrib/file/magic/Localstuff index aef809524b80..419855fb6220 100644 --- a/contrib/file/magic/Localstuff +++ b/contrib/file/magic/Localstuff @@ -2,6 +2,6 @@ #------------------------------------------------------------------------------ # Localstuff: file(1) magic for locally observed files # -# $File: Localstuff,v 1.5 2007/01/12 17:38:27 christos Exp $ +# $File: Localstuff,v 1.4 2003/03/23 04:17:27 christos Exp $ # Add any locally observed files here. Remember: # text if readable, executable if runnable binary, data if unreadable. diff --git a/contrib/file/magic/Magdir/cafebabe b/contrib/file/magic/Magdir/cafebabe index b3206e71e49e..4c58fc6c932f 100644 --- a/contrib/file/magic/Magdir/cafebabe +++ b/contrib/file/magic/Magdir/cafebabe @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: cafebabe,v 1.16 2014/04/30 21:41:02 christos Exp $ +# $File: cafebabe,v 1.17 2015/01/01 17:07:00 christos Exp $ # Cafe Babes unite! # # Since Java bytecode and Mach-O universal binaries have the same magic number, @@ -45,7 +45,7 @@ 0 name mach-o \b [ >0 use mach-o-cpu \b ->&(8.L) indirect \b: +>(8.L) indirect \b: >0 belong x \b] 0 belong 0xcafebabe diff --git a/contrib/file/magic/Magdir/filesystems b/contrib/file/magic/Magdir/filesystems index 00baaed9ed0a..939a0920c929 100644 --- a/contrib/file/magic/Magdir/filesystems +++ b/contrib/file/magic/Magdir/filesystems @@ -1,5 +1,5 @@ #------------------------------------------------------------------------------ -# $File: filesystems,v 1.107 2014/12/03 18:02:52 christos Exp $ +# $File: filesystems,v 1.108 2015/01/01 17:43:47 christos Exp $ # filesystems: file(1) magic for different filesystems # 0 name partid @@ -260,6 +260,13 @@ >>(11.s-2) uleshort 0xAA55 DOS/MBR boot sector # for sector sizes with 512 or more Bytes >0x1FE leshort 0xAA55 DOS/MBR boot sector + +# keep old DOS/MBR boot sector as dummy for mbr and bootloader displaying +# only for sector sizes with 512 or more Bytes +0x1FE leshort 0xAA55 DOS/MBR boot sector +# +# to display information (50) before DOS BPB (strength=70) and after DOS floppy (120) like in old file version +!:strength +65 >2 string OSBS OS/BS MBR # added by Joerg Jenderek at Feb 2013 according to http://thestarman.pcministry.com/asm/mbr/ # and http://en.wikipedia.org/wiki/Master_Boot_Record diff --git a/contrib/file/magic/Magdir/images b/contrib/file/magic/Magdir/images index 9fda2b0361bd..672dd88ba7cf 100644 --- a/contrib/file/magic/Magdir/images +++ b/contrib/file/magic/Magdir/images @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: images,v 1.97 2014/12/08 16:06:19 christos Exp $ +# $File: images,v 1.102 2015/01/02 02:36:35 christos Exp $ # images: file(1) magic for image formats (see also "iff", and "c-lang" for # XPM bitmaps) # @@ -115,7 +115,7 @@ # never changed. The TIFF specification recommends testing for it. 0 string MM\x00\x2a TIFF image data, big-endian !:mime image/tiff ->(4.L) use tiff_ifd +>(4.L) use \^tiff_ifd 0 string II\x2a\x00 TIFF image data, little-endian !:mime image/tiff >(4.l) use tiff_ifd @@ -125,54 +125,57 @@ >2 use tiff_entry 0 name tiff_entry +# NewSubFileType +>0 leshort 0xfe +>>12 use tiff_entry >0 leshort 0x100 >>4 lelong 1 >>>12 use tiff_entry ->>>8 lelong x \b, width=%d +>>>8 leshort x \b, width=%d >0 leshort 0x101 >>4 lelong 1 ->>>8 lelong x \b, height=%d +>>>8 leshort x \b, height=%d >>>12 use tiff_entry >0 leshort 0x102 ->>8 lelong x \b, bps=%d +>>8 leshort x \b, bps=%d >>12 use tiff_entry >0 leshort 0x103 >>4 lelong 1 \b, compression= ->>>8 lelong 1 \bnone ->>>8 lelong 2 \bhuffman ->>>8 lelong 3 \bbi-level group 3 ->>>8 lelong 4 \bbi-level group 4 ->>>8 lelong 5 \bLZW ->>>8 lelong 6 \bJPEG (old) ->>>8 lelong 7 \bJPEG ->>>8 lelong 8 \bdeflate ->>>8 lelong 9 \bJBIG, ITU-T T.85 ->>>8 lelong 0xa \bJBIG, ITU-T T.43 ->>>8 lelong 0x7ffe \bNeXT RLE 2-bit ->>>8 lelong 0x8005 \bPackBits (Macintosh RLE) ->>>8 lelong 0x8029 \bThunderscan RLE ->>>8 lelong 0x807f \bRasterPadding (CT or MP) ->>>8 lelong 0x8080 \bRLE (Line Work) ->>>8 lelong 0x8081 \bRLE (High-Res Cont-Tone) ->>>8 lelong 0x8082 \bRLE (Binary Line Work) ->>>8 lelong 0x80b2 \bDeflate (PKZIP) ->>>8 lelong 0x80b3 \bKodak DCS ->>>8 lelong 0x8765 \bJBIG ->>>8 lelong 0x8798 \bJPEG2000 ->>>8 lelong 0x8799 \bNikon NEF Compressed +>>>8 leshort 1 \bnone +>>>8 leshort 2 \bhuffman +>>>8 leshort 3 \bbi-level group 3 +>>>8 leshort 4 \bbi-level group 4 +>>>8 leshort 5 \bLZW +>>>8 leshort 6 \bJPEG (old) +>>>8 leshort 7 \bJPEG +>>>8 leshort 8 \bdeflate +>>>8 leshort 9 \bJBIG, ITU-T T.85 +>>>8 leshort 0xa \bJBIG, ITU-T T.43 +>>>8 leshort 0x7ffe \bNeXT RLE 2-bit +>>>8 leshort 0x8005 \bPackBits (Macintosh RLE) +>>>8 leshort 0x8029 \bThunderscan RLE +>>>8 leshort 0x807f \bRasterPadding (CT or MP) +>>>8 leshort 0x8080 \bRLE (Line Work) +>>>8 leshort 0x8081 \bRLE (High-Res Cont-Tone) +>>>8 leshort 0x8082 \bRLE (Binary Line Work) +>>>8 leshort 0x80b2 \bDeflate (PKZIP) +>>>8 leshort 0x80b3 \bKodak DCS +>>>8 leshort 0x8765 \bJBIG +>>>8 leshort 0x8798 \bJPEG2000 +>>>8 leshort 0x8799 \bNikon NEF Compressed >>>8 default x ->>>>8 lelong x \b(unknown 0x%x) +>>>>8 leshort x \b(unknown 0x%x) >>>12 use tiff_entry >0 leshort 0x106 \b, PhotometricIntepretation= ->>8 lelong 0 \bWhiteIsZero ->>8 lelong 1 \bBlackIsZero ->>8 lelong 2 \bRGB ->>8 lelong 3 \bRGB Palette ->>8 lelong 4 \bTransparency Mask ->>8 lelong 5 \bCMYK ->>8 lelong 6 \bYCbCr ->>8 lelong 8 \bCIELab ->>>8 lelong x \b(unknown=0x%x) +>>8 leshort 0 \bWhiteIsZero +>>8 leshort 1 \bBlackIsZero +>>8 leshort 2 \bRGB +>>8 leshort 3 \bRGB Palette +>>8 leshort 4 \bTransparency Mask +>>8 leshort 5 \bCMYK +>>8 leshort 6 \bYCbCr +>>8 leshort 8 \bCIELab +>>>8 leshort x \b(unknown=0x%x) >>12 use tiff_entry # FillOrder >0 leshort 0x10a @@ -186,21 +189,79 @@ >0 leshort 0x10e >>(8.l) string x \b, description=%s >>>12 use tiff_entry +# Make +>0 leshort 0x10f +>>(8.l) string x \b, manufacturer=%s +>>>12 use tiff_entry +# Model +>0 leshort 0x110 +>>(8.l) string x \b, model=%s +>>>12 use tiff_entry # StripOffsets >0 leshort 0x111 >>12 use tiff_entry -# NewSubFileType ->0 leshort 0xfe +# Orientation +>0 leshort 0x112 \b, orientation= +>>8 leshort 1 \bupper-left +>>8 leshort 3 \blower-right +>>8 leshort 6 \bupper-right +>>8 leshort 8 \blower-left +>>8 leshort 9 \bundefined +>>8 default x +>>>8 leshort x \b[*%d*] +>>12 use tiff_entry +# XResolution +>0 leshort 0x11a +>>8 lelong x \b, xresolution=%d +>>12 use tiff_entry +# YResolution +>0 leshort 0x11b +>>8 lelong x \b, yresolution=%d +>>12 use tiff_entry +# ResolutionUnit +>0 leshort 0x128 +>>8 leshort x \b, resolutionunit=%d +>>12 use tiff_entry +# Software +>0 leshort 0x131 +>>(8.l) string x \b, software=%s >>12 use tiff_entry # Datetime >0 leshort 0x132 >>(8.l) string x \b, datetime=%s ->>>12 use tiff_entry +>>12 use tiff_entry # HostComputer >0 leshort 0x13c >>(8.l) string x \b, hostcomputer=%s ->>>12 use tiff_entry +>>12 use tiff_entry +# WhitePoint +>0 leshort 0x13e +>>12 use tiff_entry +# PrimaryChromaticities +>0 leshort 0x13f +>>12 use tiff_entry +# YCbCrCoefficients +>0 leshort 0x211 +>>12 use tiff_entry +# YCbCrPositioning +>0 leshort 0x213 +>>12 use tiff_entry +# ReferenceBlackWhite +>0 leshort 0x214 +>>12 use tiff_entry +# Copyright +>0 leshort 0x8298 +>>(8.l) string x \b, copyright=%s +>>12 use tiff_entry +# ExifOffset +>0 leshort 0x8769 +>>12 use tiff_entry +# GPS IFD +>0 leshort 0x8825 \b, GPS-Data +>>12 use tiff_entry + #>0 leshort x \b, unknown=0x%x +#>>12 use tiff_entry 0 string MM\x00\x2b Big TIFF image data, big-endian !:mime image/tiff diff --git a/contrib/file/magic/Magdir/jpeg b/contrib/file/magic/Magdir/jpeg index 1c7156f18d1b..cfe897369392 100644 --- a/contrib/file/magic/Magdir/jpeg +++ b/contrib/file/magic/Magdir/jpeg @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: jpeg,v 1.21 2014/09/12 20:47:00 christos Exp $ +# $File: jpeg,v 1.25 2015/01/02 16:56:50 christos Exp $ # JPEG images # SunOS 5.5.1 had # @@ -31,98 +31,9 @@ # Next, show thumbnail info, if it exists: >>18 byte !0 \b, thumbnail %dx >>>19 byte x \b%d - -# EXIF moved down here to avoid reporting a bogus version number, -# and EXIF version number printing added. -# - Patrik R=E5dman ->6 string Exif \b, EXIF standard -# Look for EXIF IFD offset in IFD 0, and then look for EXIF version tag in EXIF IFD. -# All possible combinations of entries have to be enumerated, since no looping -# is possible. And both endians are possible... -# The combinations included below are from real-world JPEGs. -# Little-endian ->>12 string II -# IFD 0 Entry #5: ->>>70 leshort 0x8769 -# EXIF IFD Entry #1: ->>>>(78.l+14) leshort 0x9000 ->>>>>(78.l+23) byte x %c ->>>>>(78.l+24) byte x \b.%c ->>>>>(78.l+25) byte !0x30 \b%c -# IFD 0 Entry #9: ->>>118 leshort 0x8769 -# EXIF IFD Entry #3: ->>>>(126.l+38) leshort 0x9000 ->>>>>(126.l+47) byte x %c ->>>>>(126.l+48) byte x \b.%c ->>>>>(126.l+49) byte !0x30 \b%c -# IFD 0 Entry #10 ->>>130 leshort 0x8769 -# EXIF IFD Entry #3: ->>>>(138.l+38) leshort 0x9000 ->>>>>(138.l+47) byte x %c ->>>>>(138.l+48) byte x \b.%c ->>>>>(138.l+49) byte !0x30 \b%c -# EXIF IFD Entry #4: ->>>>(138.l+50) leshort 0x9000 ->>>>>(138.l+59) byte x %c ->>>>>(138.l+60) byte x \b.%c ->>>>>(138.l+61) byte !0x30 \b%c -# EXIF IFD Entry #5: ->>>>(138.l+62) leshort 0x9000 ->>>>>(138.l+71) byte x %c ->>>>>(138.l+72) byte x \b.%c ->>>>>(138.l+73) byte !0x30 \b%c -# IFD 0 Entry #11 ->>>142 leshort 0x8769 -# EXIF IFD Entry #3: ->>>>(150.l+38) leshort 0x9000 ->>>>>(150.l+47) byte x %c ->>>>>(150.l+48) byte x \b.%c ->>>>>(150.l+49) byte !0x30 \b%c -# EXIF IFD Entry #4: ->>>>(150.l+50) leshort 0x9000 ->>>>>(150.l+59) byte x %c ->>>>>(150.l+60) byte x \b.%c ->>>>>(150.l+61) byte !0x30 \b%c -# EXIF IFD Entry #5: ->>>>(150.l+62) leshort 0x9000 ->>>>>(150.l+71) byte x %c ->>>>>(150.l+72) byte x \b.%c ->>>>>(150.l+73) byte !0x30 \b%c -# Big-endian ->>12 string MM -# IFD 0 Entry #9: ->>>118 beshort 0x8769 -# EXIF IFD Entry #1: ->>>>(126.L+14) beshort 0x9000 ->>>>>(126.L+23) byte x %c ->>>>>(126.L+24) byte x \b.%c ->>>>>(126.L+25) byte !0x30 \b%c -# EXIF IFD Entry #3: ->>>>(126.L+38) beshort 0x9000 ->>>>>(126.L+47) byte x %c ->>>>>(126.L+48) byte x \b.%c ->>>>>(126.L+49) byte !0x30 \b%c -# IFD 0 Entry #10 ->>>130 beshort 0x8769 -# EXIF IFD Entry #3: ->>>>(138.L+38) beshort 0x9000 ->>>>>(138.L+47) byte x %c ->>>>>(138.L+48) byte x \b.%c ->>>>>(138.L+49) byte !0x30 \b%c -# EXIF IFD Entry #5: ->>>>(138.L+62) beshort 0x9000 ->>>>>(138.L+71) byte x %c ->>>>>(138.L+72) byte x \b.%c ->>>>>(138.L+73) byte !0x30 \b%c -# IFD 0 Entry #11 ->>>142 beshort 0x8769 -# EXIF IFD Entry #4: ->>>>(150.L+50) beshort 0x9000 ->>>>>(150.L+59) byte x %c ->>>>>(150.L+60) byte x \b.%c ->>>>>(150.L+61) byte !0x30 \b%c +>6 string Exif \b, Exif standard: [ +>>12 indirect/r x +>>12 string x \b] # Jump to the first segment >(4.S+4) use jpeg_segment @@ -158,6 +69,12 @@ >0 beshort 0xFFC4 >>(2.S+2) use jpeg_segment +>0 beshort 0xFFE1 +#>>(2.S+2) use jpeg_segment +>>4 string Exif \b, Exif Standard: [ +>>>10 indirect/r x +>>>10 string x \b] + # Application specific markers >0 beshort&0xFFE0 =0xFFE0 >>(2.S+2) use jpeg_segment @@ -170,6 +87,9 @@ >0 beshort&0xFFD0 =0xFFD0 >>(2.S+2) use jpeg_segment +#>0 beshort x unknown 0x%x +#>>(2.S+2) use jpeg_segment + # HSI is Handmade Software's proprietary JPEG encoding scheme 0 string hsi1 JPEG image data, HSI proprietary diff --git a/contrib/file/magic/Magdir/qt b/contrib/file/magic/Magdir/qt new file mode 100644 index 000000000000..72e6ff3a0d67 --- /dev/null +++ b/contrib/file/magic/Magdir/qt @@ -0,0 +1,19 @@ + +#------------------------------------------------------------------------------ +# $File: qt,v 1.2 2014/12/16 19:49:29 christos Exp $ +# qt: file(1) magic for Qt + +# http://doc.qt.io/qt-5/resources.html +0 string \ Qt Resource Collection file + +# https://qt.gitorious.org/qt/qtbase/source/\ +# 5367fa356233da4c0f28172a8f817791525f5457:\ +# src/tools/rcc/rcc.cpp#L840 +0 string qres\0\0 Qt Binary Resource file +0 search/1024 The\040Resource\040Compiler\040for\040Qt Qt C-code resource file + +# https://qt.gitorious.org/qt/qtbase/source/\ +# 5367fa356233da4c0f28172a8f817791525f5457:\ +# src/corelib/kernel/qtranslator.cpp#L62 +0 string \x3c\xb8\x64\x18\xca\xef\x9c\x95 +>8 string \xcd\x21\x1c\xbf\x60\xa1\xbd\xdd Qt Translation file diff --git a/contrib/file/magic/Makefile.am b/contrib/file/magic/Makefile.am index 22972e0ba7e3..7bc327d0ffa2 100644 --- a/contrib/file/magic/Makefile.am +++ b/contrib/file/magic/Makefile.am @@ -1,5 +1,5 @@ # -# $File: Makefile.am,v 1.100 2014/12/10 18:45:43 christos Exp $ +# $File: Makefile.am,v 1.101 2014/12/12 16:48:39 christos Exp $ # MAGIC_FRAGMENT_BASE = Magdir MAGIC_DIR = $(top_srcdir)/magic @@ -198,6 +198,7 @@ $(MAGIC_FRAGMENT_DIR)/pulsar \ $(MAGIC_FRAGMENT_DIR)/pwsafe \ $(MAGIC_FRAGMENT_DIR)/pyramid \ $(MAGIC_FRAGMENT_DIR)/python \ +$(MAGIC_FRAGMENT_DIR)/qt \ $(MAGIC_FRAGMENT_DIR)/revision \ $(MAGIC_FRAGMENT_DIR)/riff \ $(MAGIC_FRAGMENT_DIR)/rpm \ diff --git a/contrib/file/magic/Makefile.in b/contrib/file/magic/Makefile.in index 665c0c7cf9ec..43f42c610283 100644 --- a/contrib/file/magic/Makefile.in +++ b/contrib/file/magic/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.14.1 from Makefile.am. +# Makefile.in generated by automake 1.14 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. @@ -262,7 +262,7 @@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ # -# $File: Makefile.am,v 1.100 2014/12/10 18:45:43 christos Exp $ +# $File: Makefile.am,v 1.101 2014/12/12 16:48:39 christos Exp $ # MAGIC_FRAGMENT_BASE = Magdir MAGIC_DIR = $(top_srcdir)/magic @@ -459,6 +459,7 @@ $(MAGIC_FRAGMENT_DIR)/pulsar \ $(MAGIC_FRAGMENT_DIR)/pwsafe \ $(MAGIC_FRAGMENT_DIR)/pyramid \ $(MAGIC_FRAGMENT_DIR)/python \ +$(MAGIC_FRAGMENT_DIR)/qt \ $(MAGIC_FRAGMENT_DIR)/revision \ $(MAGIC_FRAGMENT_DIR)/riff \ $(MAGIC_FRAGMENT_DIR)/rpm \ diff --git a/contrib/file/missing b/contrib/file/missing index db98974ff5d5..cdea514931f5 100755 --- a/contrib/file/missing +++ b/contrib/file/missing @@ -1,7 +1,7 @@ #! /bin/sh # Common wrapper for a few potentially missing GNU programs. -scriptversion=2013-10-28.13; # UTC +scriptversion=2012-06-26.16; # UTC # Copyright (C) 1996-2013 Free Software Foundation, Inc. # Originally written by Fran,cois Pinard , 1996. @@ -160,7 +160,7 @@ give_advice () ;; autom4te*) echo "You might have modified some maintainer files that require" - echo "the 'autom4te' program to be rebuilt." + echo "the 'automa4te' program to be rebuilt." program_details 'autom4te' ;; bison*|yacc*) diff --git a/contrib/file/python/Makefile.in b/contrib/file/python/Makefile.in index 3e452715bd7d..63a34b4667ba 100644 --- a/contrib/file/python/Makefile.in +++ b/contrib/file/python/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.14.1 from Makefile.am. +# Makefile.in generated by automake 1.14 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. diff --git a/contrib/file/src/Makefile.in b/contrib/file/src/Makefile.in index f1779f96958f..41cb9f55084b 100644 --- a/contrib/file/src/Makefile.in +++ b/contrib/file/src/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.14.1 from Makefile.am. +# Makefile.in generated by automake 1.14 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. @@ -81,9 +81,9 @@ build_triplet = @build@ host_triplet = @host@ bin_PROGRAMS = file$(EXEEXT) subdir = src -DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am strcasestr.c \ - pread.c strlcpy.c vasprintf.c getopt_long.c asctime_r.c \ - strlcat.c ctime_r.c getline.c asprintf.c fmtcheck.c \ +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ctime_r.c \ + vasprintf.c asctime_r.c asprintf.c strcasestr.c pread.c \ + getline.c strlcpy.c strlcat.c fmtcheck.c getopt_long.c \ $(top_srcdir)/depcomp $(include_HEADERS) ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ diff --git a/contrib/file/src/apprentice.c b/contrib/file/src/apprentice.c index cfea6bee4e8b..47b4c870c23a 100644 --- a/contrib/file/src/apprentice.c +++ b/contrib/file/src/apprentice.c @@ -32,7 +32,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: apprentice.c,v 1.227 2014/11/28 02:46:39 christos Exp $") +FILE_RCSID("@(#)$File: apprentice.c,v 1.229 2015/01/01 17:07:34 christos Exp $") #endif /* lint */ #include "magic.h" @@ -528,6 +528,7 @@ file_ms_alloc(int flags) ms->name_max = FILE_NAME_MAX; ms->elf_shnum_max = FILE_ELF_SHNUM_MAX; ms->elf_phnum_max = FILE_ELF_PHNUM_MAX; + ms->elf_notes_max = FILE_ELF_NOTES_MAX; return ms; free: free(ms); @@ -1604,6 +1605,145 @@ check_cond(struct magic_set *ms, int cond, uint32_t cont_level) } #endif /* ENABLE_CONDITIONALS */ +private int +parse_indirect_modifier(struct magic_set *ms, struct magic *m, const char **lp) +{ + const char *l = *lp; + + while (!isspace((unsigned char)*++l)) + switch (*l) { + case CHAR_INDIRECT_RELATIVE: + m->str_flags |= INDIRECT_RELATIVE; + break; + default: + if (ms->flags & MAGIC_CHECK) + file_magwarn(ms, "indirect modifier `%c' " + "invalid", *l); + *lp = l; + return -1; + } + *lp = l; + return 0; +} + +private void +parse_op_modifier(struct magic_set *ms, struct magic *m, const char **lp, + int op) +{ + const char *l = *lp; + char *t; + uint64_t val; + + ++l; + m->mask_op |= op; + val = (uint64_t)strtoull(l, &t, 0); + l = t; + m->num_mask = file_signextend(ms, m, val); + eatsize(&l); + *lp = l; +} + +private int +parse_string_modifier(struct magic_set *ms, struct magic *m, const char **lp) +{ + const char *l = *lp; + char *t; + int have_range = 0; + + while (!isspace((unsigned char)*++l)) { + switch (*l) { + case '0': case '1': case '2': + case '3': case '4': case '5': + case '6': case '7': case '8': + case '9': + if (have_range && (ms->flags & MAGIC_CHECK)) + file_magwarn(ms, "multiple ranges"); + have_range = 1; + m->str_range = CAST(uint32_t, strtoul(l, &t, 0)); + if (m->str_range == 0) + file_magwarn(ms, "zero range"); + l = t - 1; + break; + case CHAR_COMPACT_WHITESPACE: + m->str_flags |= STRING_COMPACT_WHITESPACE; + break; + case CHAR_COMPACT_OPTIONAL_WHITESPACE: + m->str_flags |= STRING_COMPACT_OPTIONAL_WHITESPACE; + break; + case CHAR_IGNORE_LOWERCASE: + m->str_flags |= STRING_IGNORE_LOWERCASE; + break; + case CHAR_IGNORE_UPPERCASE: + m->str_flags |= STRING_IGNORE_UPPERCASE; + break; + case CHAR_REGEX_OFFSET_START: + m->str_flags |= REGEX_OFFSET_START; + break; + case CHAR_BINTEST: + m->str_flags |= STRING_BINTEST; + break; + case CHAR_TEXTTEST: + m->str_flags |= STRING_TEXTTEST; + break; + case CHAR_TRIM: + m->str_flags |= STRING_TRIM; + break; + case CHAR_PSTRING_1_LE: +#define SET_LENGTH(a) m->str_flags = (m->str_flags & ~PSTRING_LEN) | (a) + if (m->type != FILE_PSTRING) + goto bad; + SET_LENGTH(PSTRING_1_LE); + break; + case CHAR_PSTRING_2_BE: + if (m->type != FILE_PSTRING) + goto bad; + SET_LENGTH(PSTRING_2_BE); + break; + case CHAR_PSTRING_2_LE: + if (m->type != FILE_PSTRING) + goto bad; + SET_LENGTH(PSTRING_2_LE); + break; + case CHAR_PSTRING_4_BE: + if (m->type != FILE_PSTRING) + goto bad; + SET_LENGTH(PSTRING_4_BE); + break; + case CHAR_PSTRING_4_LE: + switch (m->type) { + case FILE_PSTRING: + case FILE_REGEX: + break; + default: + goto bad; + } + SET_LENGTH(PSTRING_4_LE); + break; + case CHAR_PSTRING_LENGTH_INCLUDES_ITSELF: + if (m->type != FILE_PSTRING) + goto bad; + m->str_flags |= PSTRING_LENGTH_INCLUDES_ITSELF; + break; + default: + bad: + if (ms->flags & MAGIC_CHECK) + file_magwarn(ms, "string modifier `%c' " + "invalid", *l); + goto out; + } + /* allow multiple '/' for readability */ + if (l[1] == '/' && !isspace((unsigned char)l[2])) + l++; + } + if (string_modifier_check(ms, m) == -1) + goto out; + *lp = l; + return 0; +out: + *lp = l; + return -1; +} + /* * parse one line from magic file, put into magic[index++] if valid */ @@ -1873,118 +2013,27 @@ parse(struct magic_set *ms, struct magic_entry *me, const char *line, m->str_range = 0; m->str_flags = m->type == FILE_PSTRING ? PSTRING_1_LE : 0; if ((op = get_op(*l)) != -1) { - if (!IS_STRING(m->type)) { - uint64_t val; - ++l; - m->mask_op |= op; - val = (uint64_t)strtoull(l, &t, 0); - l = t; - m->num_mask = file_signextend(ms, m, val); - eatsize(&l); - } - else if (op == FILE_OPDIVIDE) { - int have_range = 0; - while (!isspace((unsigned char)*++l)) { - switch (*l) { - case '0': case '1': case '2': - case '3': case '4': case '5': - case '6': case '7': case '8': - case '9': - if (have_range && - (ms->flags & MAGIC_CHECK)) - file_magwarn(ms, - "multiple ranges"); - have_range = 1; - m->str_range = CAST(uint32_t, - strtoul(l, &t, 0)); - if (m->str_range == 0) - file_magwarn(ms, - "zero range"); - l = t - 1; - break; - case CHAR_COMPACT_WHITESPACE: - m->str_flags |= - STRING_COMPACT_WHITESPACE; - break; - case CHAR_COMPACT_OPTIONAL_WHITESPACE: - m->str_flags |= - STRING_COMPACT_OPTIONAL_WHITESPACE; - break; - case CHAR_IGNORE_LOWERCASE: - m->str_flags |= STRING_IGNORE_LOWERCASE; - break; - case CHAR_IGNORE_UPPERCASE: - m->str_flags |= STRING_IGNORE_UPPERCASE; - break; - case CHAR_REGEX_OFFSET_START: - m->str_flags |= REGEX_OFFSET_START; - break; - case CHAR_BINTEST: - m->str_flags |= STRING_BINTEST; - break; - case CHAR_TEXTTEST: - m->str_flags |= STRING_TEXTTEST; - break; - case CHAR_TRIM: - m->str_flags |= STRING_TRIM; - break; - case CHAR_PSTRING_1_LE: - if (m->type != FILE_PSTRING) - goto bad; - m->str_flags = (m->str_flags & ~PSTRING_LEN) | PSTRING_1_LE; - break; - case CHAR_PSTRING_2_BE: - if (m->type != FILE_PSTRING) - goto bad; - m->str_flags = (m->str_flags & ~PSTRING_LEN) | PSTRING_2_BE; - break; - case CHAR_PSTRING_2_LE: - if (m->type != FILE_PSTRING) - goto bad; - m->str_flags = (m->str_flags & ~PSTRING_LEN) | PSTRING_2_LE; - break; - case CHAR_PSTRING_4_BE: - if (m->type != FILE_PSTRING) - goto bad; - m->str_flags = (m->str_flags & ~PSTRING_LEN) | PSTRING_4_BE; - break; - case CHAR_PSTRING_4_LE: - switch (m->type) { - case FILE_PSTRING: - case FILE_REGEX: - break; - default: - goto bad; - } - m->str_flags = (m->str_flags & ~PSTRING_LEN) | PSTRING_4_LE; - break; - case CHAR_PSTRING_LENGTH_INCLUDES_ITSELF: - if (m->type != FILE_PSTRING) - goto bad; - m->str_flags |= PSTRING_LENGTH_INCLUDES_ITSELF; - break; - default: - bad: - if (ms->flags & MAGIC_CHECK) - file_magwarn(ms, - "string extension `%c' " - "invalid", *l); - return -1; - } - /* allow multiple '/' for readability */ - if (l[1] == '/' && - !isspace((unsigned char)l[2])) - l++; - } - if (string_modifier_check(ms, m) == -1) + if (IS_STRING(m->type)) { + int r; + + if (op != FILE_OPDIVIDE) { + if (ms->flags & MAGIC_CHECK) + file_magwarn(ms, + "invalid string/indirect op: " + "`%c'", *t); return -1; - } - else { - if (ms->flags & MAGIC_CHECK) - file_magwarn(ms, "invalid string op: %c", *t); - return -1; - } + } + + if (m->type == FILE_INDIRECT) + r = parse_indirect_modifier(ms, m, &l); + else + r = parse_string_modifier(ms, m, &l); + if (r == -1) + return -1; + } else + parse_op_modifier(ms, m, &l, op); } + /* * We used to set mask to all 1's here, instead let's just not do * anything if mask = 0 (unless you have a better idea) diff --git a/contrib/file/src/compress.c b/contrib/file/src/compress.c index 4a6f42e8caa1..e968bb452850 100644 --- a/contrib/file/src/compress.c +++ b/contrib/file/src/compress.c @@ -35,7 +35,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: compress.c,v 1.75 2014/12/04 15:56:46 christos Exp $") +FILE_RCSID("@(#)$File: compress.c,v 1.77 2014/12/12 16:33:01 christos Exp $") #endif #include "magic.h" @@ -45,6 +45,7 @@ FILE_RCSID("@(#)$File: compress.c,v 1.75 2014/12/04 15:56:46 christos Exp $") #endif #include #include +#include #if !defined(__MINGW32__) && !defined(WIN32) #include #endif @@ -103,10 +104,12 @@ file_zmagic(struct magic_set *ms, int fd, const char *name, size_t i, nsz; int rv = 0; int mime = ms->flags & MAGIC_MIME; + sig_t osigpipe; if ((ms->flags & MAGIC_COMPRESS) == 0) return 0; + osigpipe = signal(SIGPIPE, SIG_IGN); for (i = 0; i < ncompr; i++) { if (nbytes < compr[i].maglen) continue; @@ -133,6 +136,7 @@ file_zmagic(struct magic_set *ms, int fd, const char *name, } } error: + (void)signal(SIGPIPE, osigpipe); free(newbuf); ms->flags |= MAGIC_COMPRESS; return rv; @@ -508,11 +512,16 @@ err: strerror(errno)); #endif n = NODATA; - } else if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { + } else if (!WIFEXITED(status)) { #ifdef DEBUG - (void)fprintf(stderr, "Child status (0x%x)\n", status); + (void)fprintf(stderr, "Child not exited (0x%x)\n", + status); +#endif + } else if (WEXITSTATUS(status) != 0) { +#ifdef DEBUG + (void)fprintf(stderr, "Child exited (0x%d)\n", + WEXITSTATUS(status)); #endif - n = NODATA; } (void) close(fdin[0]); diff --git a/contrib/file/src/elfclass.h b/contrib/file/src/elfclass.h index e144d1127e4e..5360b0b55a7e 100644 --- a/contrib/file/src/elfclass.h +++ b/contrib/file/src/elfclass.h @@ -32,17 +32,18 @@ swap = (u.c[sizeof(int32_t) - 1] + 1) != elfhdr.e_ident[EI_DATA]; type = elf_getu16(swap, elfhdr.e_type); + notecount = ms->elf_notes_max; switch (type) { #ifdef ELFCORE case ET_CORE: phnum = elf_getu16(swap, elfhdr.e_phnum); if (phnum > ms->elf_phnum_max) - return toomany(ms, "program", phnum); + return toomany(ms, "program headers", phnum); flags |= FLAGS_IS_CORE; if (dophn_core(ms, clazz, swap, fd, (off_t)elf_getu(swap, elfhdr.e_phoff), phnum, (size_t)elf_getu16(swap, elfhdr.e_phentsize), - fsize, &flags) == -1) + fsize, &flags, ¬ecount) == -1) return -1; break; #endif @@ -57,22 +58,25 @@ if (dophn_exec(ms, clazz, swap, fd, (off_t)elf_getu(swap, elfhdr.e_phoff), phnum, (size_t)elf_getu16(swap, elfhdr.e_phentsize), - fsize, &flags, shnum) == -1) + fsize, shnum, &flags, ¬ecount) == -1) return -1; /*FALLTHROUGH*/ case ET_REL: shnum = elf_getu16(swap, elfhdr.e_shnum); if (shnum > ms->elf_shnum_max) - return toomany(ms, "section", shnum); + return toomany(ms, "section headers", shnum); if (doshn(ms, clazz, swap, fd, (off_t)elf_getu(swap, elfhdr.e_shoff), shnum, (size_t)elf_getu16(swap, elfhdr.e_shentsize), - fsize, &flags, elf_getu16(swap, elfhdr.e_machine), - (int)elf_getu16(swap, elfhdr.e_shstrndx)) == -1) + fsize, elf_getu16(swap, elfhdr.e_machine), + (int)elf_getu16(swap, elfhdr.e_shstrndx), + &flags, ¬ecount) == -1) return -1; break; default: break; } + if (notecount == 0) + return toomany(ms, "notes", ms->elf_notes_max); return 1; diff --git a/contrib/file/src/file.c b/contrib/file/src/file.c index 148f806f172c..546fd8bac621 100644 --- a/contrib/file/src/file.c +++ b/contrib/file/src/file.c @@ -32,7 +32,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: file.c,v 1.159 2014/11/28 02:46:39 christos Exp $") +FILE_RCSID("@(#)$File: file.c,v 1.160 2014/12/16 23:18:40 christos Exp $") #endif /* lint */ #include "magic.h" @@ -125,6 +125,7 @@ private struct { { "name", MAGIC_PARAM_NAME_MAX, 0 }, { "elf_phnum", MAGIC_PARAM_ELF_PHNUM_MAX, 0 }, { "elf_shnum", MAGIC_PARAM_ELF_SHNUM_MAX, 0 }, + { "elf_notes", MAGIC_PARAM_ELF_NOTES_MAX, 0 }, }; private char *progname; /* used throughout */ diff --git a/contrib/file/src/file.h b/contrib/file/src/file.h index 14fa836d2bb7..01aa37a6b9b0 100644 --- a/contrib/file/src/file.h +++ b/contrib/file/src/file.h @@ -27,7 +27,7 @@ */ /* * file.h - definitions for file(1) program - * @(#)$File: file.h,v 1.161 2014/12/04 15:56:46 christos Exp $ + * @(#)$File: file.h,v 1.164 2015/01/01 17:07:34 christos Exp $ */ #ifndef __file_h__ @@ -234,6 +234,7 @@ struct magic { (t) == FILE_LESTRING16 || \ (t) == FILE_REGEX || \ (t) == FILE_SEARCH || \ + (t) == FILE_INDIRECT || \ (t) == FILE_NAME || \ (t) == FILE_USE) @@ -346,6 +347,8 @@ struct magic { #define STRING_IGNORE_CASE (STRING_IGNORE_LOWERCASE|STRING_IGNORE_UPPERCASE) #define STRING_DEFAULT_RANGE 100 +#define INDIRECT_RELATIVE BIT(0) +#define CHAR_INDIRECT_RELATIVE 'r' /* list of magic entries */ struct mlist { @@ -407,10 +410,12 @@ struct magic_set { uint16_t name_max; uint16_t elf_shnum_max; uint16_t elf_phnum_max; + uint16_t elf_notes_max; #define FILE_INDIR_MAX 15 #define FILE_NAME_MAX 30 #define FILE_ELF_SHNUM_MAX 32768 #define FILE_ELF_PHNUM_MAX 128 +#define FILE_ELF_NOTES_MAX 256 }; /* Type for Unicode characters */ @@ -476,6 +481,7 @@ protected int file_looks_utf8(const unsigned char *, size_t, unichar *, size_t *); protected size_t file_pstring_length_size(const struct magic *); protected size_t file_pstring_get_length(const struct magic *, const char *); +protected char * file_printable(char *, size_t, const char *); #ifdef __EMX__ protected int file_os2_apptype(struct magic_set *, const char *, const void *, size_t); diff --git a/contrib/file/src/file_opts.h b/contrib/file/src/file_opts.h index 9cb1d01deeee..3286ac607ec6 100644 --- a/contrib/file/src/file_opts.h +++ b/contrib/file/src/file_opts.h @@ -43,8 +43,13 @@ OPT('0', "print0", 0, " terminate filenames with ASCII NUL\n") #if defined(HAVE_UTIME) || defined(HAVE_UTIMES) OPT('p', "preserve-date", 0, " preserve access times on files\n") #endif +OPT('P', "parameter", 0, " set file engine parameter limits\n" + " indir 15 recursion limit for indirection\n" + " name 30 use limit for name/use magic\n" + " elf_notes 256 max ELF notes processed\n" + " elf_phnum 128 max ELF prog sections processed\n" + " elf_shnum 32768 max ELF sections processed\n") OPT('r', "raw", 0, " don't translate unprintable chars to \\ooo\n") -OPT('R', "recursion", 0, " set maximum recursion level\n") OPT('s', "special-files", 0, " treat special (block/char devices) files as\n" " ordinary ones\n") OPT('C', "compile", 0, " compile file specified by -m\n") diff --git a/contrib/file/src/funcs.c b/contrib/file/src/funcs.c index f190349fd909..a60ccaaf9cef 100644 --- a/contrib/file/src/funcs.c +++ b/contrib/file/src/funcs.c @@ -27,7 +27,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: funcs.c,v 1.77 2014/11/28 02:46:39 christos Exp $") +FILE_RCSID("@(#)$File: funcs.c,v 1.79 2014/12/16 20:52:49 christos Exp $") #endif /* lint */ #include "magic.h" @@ -531,3 +531,28 @@ file_pop_buffer(struct magic_set *ms, file_pushbuf_t *pb) free(pb); return rbuf; } + +/* + * convert string to ascii printable format. + */ +protected char * +file_printable(char *buf, size_t bufsiz, const char *str) +{ + char *ptr, *eptr; + const unsigned char *s = (const unsigned char *)str; + + for (ptr = buf, eptr = ptr + bufsiz - 1; ptr < eptr && *s; s++) { + if (isprint(*s)) { + *ptr++ = *s; + continue; + } + if (ptr >= eptr - 3) + break; + *ptr++ = '\\'; + *ptr++ = ((*s >> 6) & 7) + '0'; + *ptr++ = ((*s >> 3) & 7) + '0'; + *ptr++ = ((*s >> 0) & 7) + '0'; + } + *ptr = '\0'; + return buf; +} diff --git a/contrib/file/src/getline.c b/contrib/file/src/getline.c index ab5e1155cbb9..b00de01bf093 100644 --- a/contrib/file/src/getline.c +++ b/contrib/file/src/getline.c @@ -80,7 +80,7 @@ getdelim(char **buf, size_t *bufsiz, int delimiter, FILE *fp) } } -ssize_t +public ssize_t getline(char **buf, size_t *bufsiz, FILE *fp) { return getdelim(buf, bufsiz, '\n', fp); diff --git a/contrib/file/src/magic.c b/contrib/file/src/magic.c index b0cf11c28b50..d16f8c6ce9d9 100644 --- a/contrib/file/src/magic.c +++ b/contrib/file/src/magic.c @@ -33,7 +33,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: magic.c,v 1.90 2014/12/04 15:56:46 christos Exp $") +FILE_RCSID("@(#)$File: magic.c,v 1.91 2014/12/16 23:18:40 christos Exp $") #endif /* lint */ #include "magic.h" @@ -554,6 +554,9 @@ magic_setparam(struct magic_set *ms, int param, const void *val) case MAGIC_PARAM_ELF_SHNUM_MAX: ms->elf_shnum_max = *(const size_t *)val; return 0; + case MAGIC_PARAM_ELF_NOTES_MAX: + ms->elf_notes_max = *(const size_t *)val; + return 0; default: errno = EINVAL; return -1; @@ -576,6 +579,9 @@ magic_getparam(struct magic_set *ms, int param, void *val) case MAGIC_PARAM_ELF_SHNUM_MAX: *(size_t *)val = ms->elf_shnum_max; return 0; + case MAGIC_PARAM_ELF_NOTES_MAX: + *(size_t *)val = ms->elf_notes_max; + return 0; default: errno = EINVAL; return -1; diff --git a/contrib/file/src/magic.h b/contrib/file/src/magic.h index 94cb397e337a..721712ffeaba 100644 --- a/contrib/file/src/magic.h +++ b/contrib/file/src/magic.h @@ -107,6 +107,7 @@ int magic_errno(magic_t); #define MAGIC_PARAM_NAME_MAX 1 #define MAGIC_PARAM_ELF_PHNUM_MAX 2 #define MAGIC_PARAM_ELF_SHNUM_MAX 3 +#define MAGIC_PARAM_ELF_NOTES_MAX 4 int magic_setparam(magic_t, int, const void *); int magic_getparam(magic_t, int, void *); diff --git a/contrib/file/src/magic.h.in b/contrib/file/src/magic.h.in index 856478b68f33..0d4c5ce874c4 100644 --- a/contrib/file/src/magic.h.in +++ b/contrib/file/src/magic.h.in @@ -107,6 +107,7 @@ int magic_errno(magic_t); #define MAGIC_PARAM_NAME_MAX 1 #define MAGIC_PARAM_ELF_PHNUM_MAX 2 #define MAGIC_PARAM_ELF_SHNUM_MAX 3 +#define MAGIC_PARAM_ELF_NOTES_MAX 4 int magic_setparam(magic_t, int, const void *); int magic_getparam(magic_t, int, void *); diff --git a/contrib/file/src/readelf.c b/contrib/file/src/readelf.c index 08a2afb2aa0d..d159620cec85 100644 --- a/contrib/file/src/readelf.c +++ b/contrib/file/src/readelf.c @@ -27,7 +27,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: readelf.c,v 1.111 2014/12/09 02:47:45 christos Exp $") +FILE_RCSID("@(#)$File: readelf.c,v 1.117 2014/12/16 23:29:42 christos Exp $") #endif #ifdef BUILTIN_ELF @@ -43,14 +43,14 @@ FILE_RCSID("@(#)$File: readelf.c,v 1.111 2014/12/09 02:47:45 christos Exp $") #ifdef ELFCORE private int dophn_core(struct magic_set *, int, int, int, off_t, int, size_t, - off_t, int *); + off_t, int *, uint16_t *); #endif private int dophn_exec(struct magic_set *, int, int, int, off_t, int, size_t, - off_t, int *, int); + off_t, int, int *, uint16_t *); private int doshn(struct magic_set *, int, int, int, off_t, int, size_t, - off_t, int *, int, int); + off_t, int, int, int *, uint16_t *); private size_t donote(struct magic_set *, void *, size_t, size_t, int, - int, size_t, int *); + int, size_t, int *, uint16_t *); #define ELF_ALIGN(a) ((((a) + align - 1) / align) * align) @@ -67,7 +67,7 @@ private uint64_t getu64(int, uint64_t); private int toomany(struct magic_set *ms, const char *name, uint16_t num) { - if (file_printf(ms, ", too many %s header sections (%u)", name, num + if (file_printf(ms, ", too many %s (%u)", name, num ) == -1) return -1; return 0; @@ -293,15 +293,19 @@ private const char os_style_names[][8] = { "NetBSD", }; -#define FLAGS_DID_CORE 0x01 -#define FLAGS_DID_NOTE 0x02 -#define FLAGS_DID_BUILD_ID 0x04 -#define FLAGS_DID_CORE_STYLE 0x08 -#define FLAGS_IS_CORE 0x10 +#define FLAGS_DID_CORE 0x001 +#define FLAGS_DID_OS_NOTE 0x002 +#define FLAGS_DID_BUILD_ID 0x004 +#define FLAGS_DID_CORE_STYLE 0x008 +#define FLAGS_DID_NETBSD_PAX 0x010 +#define FLAGS_DID_NETBSD_MARCH 0x020 +#define FLAGS_DID_NETBSD_CMODEL 0x040 +#define FLAGS_DID_NETBSD_UNKNOWN 0x080 +#define FLAGS_IS_CORE 0x100 private int dophn_core(struct magic_set *ms, int clazz, int swap, int fd, off_t off, - int num, size_t size, off_t fsize, int *flags) + int num, size_t size, off_t fsize, int *flags, uint16_t *notecount) { Elf32_Phdr ph32; Elf64_Phdr ph64; @@ -319,7 +323,7 @@ dophn_core(struct magic_set *ms, int clazz, int swap, int fd, off_t off, * Loop through all the program headers. */ for ( ; num; num--) { - if (pread(fd, xph_addr, xph_sizeof, off) == -1) { + if (pread(fd, xph_addr, xph_sizeof, off) < (ssize_t)xph_sizeof) { file_badread(ms); return -1; } @@ -347,7 +351,7 @@ dophn_core(struct magic_set *ms, int clazz, int swap, int fd, off_t off, if (offset >= (size_t)bufsize) break; offset = donote(ms, nbuf, offset, (size_t)bufsize, - clazz, swap, 4, flags); + clazz, swap, 4, flags, notecount); if (offset == 0) break; @@ -477,132 +481,127 @@ do_note_freebsd_version(struct magic_set *ms, int swap, void *v) } } -private size_t -donote(struct magic_set *ms, void *vbuf, size_t offset, size_t size, - int clazz, int swap, size_t align, int *flags) +private int +do_bid_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type, + int swap __attribute__((__unused__)), uint32_t namesz, uint32_t descsz, + size_t noff, size_t doff, int *flags) { - Elf32_Nhdr nh32; - Elf64_Nhdr nh64; - size_t noff, doff; -#ifdef ELFCORE - int os_style = -1; -#endif - uint32_t namesz, descsz; - unsigned char *nbuf = CAST(unsigned char *, vbuf); - - if (xnh_sizeof + offset > size) { - /* - * We're out of note headers. - */ - return xnh_sizeof + offset; - } - - (void)memcpy(xnh_addr, &nbuf[offset], xnh_sizeof); - offset += xnh_sizeof; - - namesz = xnh_namesz; - descsz = xnh_descsz; - if ((namesz == 0) && (descsz == 0)) { - /* - * We're out of note headers. - */ - return (offset >= size) ? offset : size; - } - - if (namesz & 0x80000000) { - (void)file_printf(ms, ", bad note name size 0x%lx", - (unsigned long)namesz); - return 0; - } - - if (descsz & 0x80000000) { - (void)file_printf(ms, ", bad note description size 0x%lx", - (unsigned long)descsz); - return 0; - } - - - noff = offset; - doff = ELF_ALIGN(offset + namesz); - - if (offset + namesz > size) { - /* - * We're past the end of the buffer. - */ - return doff; - } - - offset = ELF_ALIGN(doff + descsz); - if (doff + descsz > size) { - /* - * We're past the end of the buffer. - */ - return (offset >= size) ? offset : size; - } - - if ((*flags & (FLAGS_DID_NOTE|FLAGS_DID_BUILD_ID)) == - (FLAGS_DID_NOTE|FLAGS_DID_BUILD_ID)) - goto core; - - if (namesz == 5 && strcmp((char *)&nbuf[noff], "SuSE") == 0 && - xnh_type == NT_GNU_VERSION && descsz == 2) { - file_printf(ms, ", for SuSE %d.%d", nbuf[doff], nbuf[doff + 1]); - } if (namesz == 4 && strcmp((char *)&nbuf[noff], "GNU") == 0 && - xnh_type == NT_GNU_VERSION && descsz == 16) { + type == NT_GNU_BUILD_ID && (descsz == 16 || descsz == 20)) { + uint8_t desc[20]; + uint32_t i; + *flags |= FLAGS_DID_BUILD_ID; + if (file_printf(ms, ", BuildID[%s]=", descsz == 16 ? "md5/uuid" : + "sha1") == -1) + return 1; + (void)memcpy(desc, &nbuf[doff], descsz); + for (i = 0; i < descsz; i++) + if (file_printf(ms, "%02x", desc[i]) == -1) + return 1; + return 1; + } + return 0; +} + +private int +do_os_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type, + int swap, uint32_t namesz, uint32_t descsz, + size_t noff, size_t doff, int *flags) +{ + if (namesz == 5 && strcmp((char *)&nbuf[noff], "SuSE") == 0 && + type == NT_GNU_VERSION && descsz == 2) { + *flags |= FLAGS_DID_OS_NOTE; + file_printf(ms, ", for SuSE %d.%d", nbuf[doff], nbuf[doff + 1]); + return 1; + } + + if (namesz == 4 && strcmp((char *)&nbuf[noff], "GNU") == 0 && + type == NT_GNU_VERSION && descsz == 16) { uint32_t desc[4]; (void)memcpy(desc, &nbuf[doff], sizeof(desc)); + *flags |= FLAGS_DID_OS_NOTE; if (file_printf(ms, ", for GNU/") == -1) - return size; + return 1; switch (elf_getu32(swap, desc[0])) { case GNU_OS_LINUX: if (file_printf(ms, "Linux") == -1) - return size; + return 1; break; case GNU_OS_HURD: if (file_printf(ms, "Hurd") == -1) - return size; + return 1; break; case GNU_OS_SOLARIS: if (file_printf(ms, "Solaris") == -1) - return size; + return 1; break; case GNU_OS_KFREEBSD: if (file_printf(ms, "kFreeBSD") == -1) - return size; + return 1; break; case GNU_OS_KNETBSD: if (file_printf(ms, "kNetBSD") == -1) - return size; + return 1; break; default: if (file_printf(ms, "") == -1) - return size; + return 1; } if (file_printf(ms, " %d.%d.%d", elf_getu32(swap, desc[1]), elf_getu32(swap, desc[2]), elf_getu32(swap, desc[3])) == -1) - return size; - *flags |= FLAGS_DID_NOTE; - return size; + return 1; + return 1; } - if (namesz == 4 && strcmp((char *)&nbuf[noff], "GNU") == 0 && - xnh_type == NT_GNU_BUILD_ID && (descsz == 16 || descsz == 20)) { - uint8_t desc[20]; - uint32_t i; - if (file_printf(ms, ", BuildID[%s]=", descsz == 16 ? "md5/uuid" : - "sha1") == -1) - return size; - (void)memcpy(desc, &nbuf[doff], descsz); - for (i = 0; i < descsz; i++) - if (file_printf(ms, "%02x", desc[i]) == -1) - return size; - *flags |= FLAGS_DID_BUILD_ID; + if (namesz == 7 && strcmp((char *)&nbuf[noff], "NetBSD") == 0) { + if (type == NT_NETBSD_VERSION && descsz == 4) { + *flags |= FLAGS_DID_OS_NOTE; + do_note_netbsd_version(ms, swap, &nbuf[doff]); + return 1; + } } + if (namesz == 8 && strcmp((char *)&nbuf[noff], "FreeBSD") == 0) { + if (type == NT_FREEBSD_VERSION && descsz == 4) { + *flags |= FLAGS_DID_OS_NOTE; + do_note_freebsd_version(ms, swap, &nbuf[doff]); + return 1; + } + } + + if (namesz == 8 && strcmp((char *)&nbuf[noff], "OpenBSD") == 0 && + type == NT_OPENBSD_VERSION && descsz == 4) { + *flags |= FLAGS_DID_OS_NOTE; + if (file_printf(ms, ", for OpenBSD") == -1) + return 1; + /* Content of note is always 0 */ + return 1; + } + + if (namesz == 10 && strcmp((char *)&nbuf[noff], "DragonFly") == 0 && + type == NT_DRAGONFLY_VERSION && descsz == 4) { + uint32_t desc; + *flags |= FLAGS_DID_OS_NOTE; + if (file_printf(ms, ", for DragonFly") == -1) + return 1; + (void)memcpy(&desc, &nbuf[doff], sizeof(desc)); + desc = elf_getu32(swap, desc); + if (file_printf(ms, " %d.%d.%d", desc / 100000, + desc / 10000 % 10, desc % 10000) == -1) + return 1; + return 1; + } + return 0; +} + +private int +do_pax_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type, + int swap, uint32_t namesz, uint32_t descsz, + size_t noff, size_t doff, int *flags) +{ if (namesz == 4 && strcmp((char *)&nbuf[noff], "PaX") == 0 && - xnh_type == NT_NETBSD_PAX && descsz == 4) { + type == NT_NETBSD_PAX && descsz == 4) { static const char *pax[] = { "+mprotect", "-mprotect", @@ -615,80 +614,32 @@ donote(struct magic_set *ms, void *vbuf, size_t offset, size_t size, size_t i; int did = 0; + *flags |= FLAGS_DID_NETBSD_PAX; (void)memcpy(&desc, &nbuf[doff], sizeof(desc)); desc = elf_getu32(swap, desc); if (desc && file_printf(ms, ", PaX: ") == -1) - return size; + return 1; for (i = 0; i < __arraycount(pax); i++) { if (((1 << i) & desc) == 0) continue; if (file_printf(ms, "%s%s", did++ ? "," : "", pax[i]) == -1) - return size; + return 1; } + return 1; } + return 0; +} - if (namesz == 7 && strcmp((char *)&nbuf[noff], "NetBSD") == 0) { - switch (xnh_type) { - case NT_NETBSD_VERSION: - if (descsz == 4) { - do_note_netbsd_version(ms, swap, &nbuf[doff]); - *flags |= FLAGS_DID_NOTE; - return size; - } - break; - case NT_NETBSD_MARCH: - if (file_printf(ms, ", compiled for: %.*s", (int)descsz, - (const char *)&nbuf[doff]) == -1) - return size; - break; - case NT_NETBSD_CMODEL: - if (file_printf(ms, ", compiler model: %.*s", - (int)descsz, (const char *)&nbuf[doff]) == -1) - return size; - break; - default: - if (file_printf(ms, ", note=%u", xnh_type) == -1) - return size; - break; - } - return size; - } - - if (namesz == 8 && strcmp((char *)&nbuf[noff], "FreeBSD") == 0) { - if (xnh_type == NT_FREEBSD_VERSION && descsz == 4) { - do_note_freebsd_version(ms, swap, &nbuf[doff]); - *flags |= FLAGS_DID_NOTE; - return size; - } - } - - if (namesz == 8 && strcmp((char *)&nbuf[noff], "OpenBSD") == 0 && - xnh_type == NT_OPENBSD_VERSION && descsz == 4) { - if (file_printf(ms, ", for OpenBSD") == -1) - return size; - /* Content of note is always 0 */ - *flags |= FLAGS_DID_NOTE; - return size; - } - - if (namesz == 10 && strcmp((char *)&nbuf[noff], "DragonFly") == 0 && - xnh_type == NT_DRAGONFLY_VERSION && descsz == 4) { - uint32_t desc; - if (file_printf(ms, ", for DragonFly") == -1) - return size; - (void)memcpy(&desc, &nbuf[doff], sizeof(desc)); - desc = elf_getu32(swap, desc); - if (file_printf(ms, " %d.%d.%d", desc / 100000, - desc / 10000 % 10, desc % 10000) == -1) - return size; - *flags |= FLAGS_DID_NOTE; - return size; - } - -core: +private int +do_core_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type, + int swap, uint32_t namesz, uint32_t descsz, + size_t noff, size_t doff, int *flags, size_t size, int clazz) +{ +#ifdef ELFCORE + int os_style = -1; /* * Sigh. The 2.0.36 kernel in Debian 2.1, at * least, doesn't correctly implement name @@ -717,20 +668,17 @@ core: os_style = OS_STYLE_NETBSD; } -#ifdef ELFCORE - if ((*flags & FLAGS_DID_CORE) != 0) - return size; - if (os_style != -1 && (*flags & FLAGS_DID_CORE_STYLE) == 0) { if (file_printf(ms, ", %s-style", os_style_names[os_style]) == -1) - return size; + return 1; *flags |= FLAGS_DID_CORE_STYLE; } switch (os_style) { case OS_STYLE_NETBSD: - if (xnh_type == NT_NETBSD_CORE_PROCINFO) { + if (type == NT_NETBSD_CORE_PROCINFO) { + char sbuf[512]; uint32_t signo; /* * Extract the program name. It is at @@ -738,8 +686,9 @@ core: * including the terminating NUL. */ if (file_printf(ms, ", from '%.31s'", - &nbuf[doff + 0x7c]) == -1) - return size; + file_printable(sbuf, sizeof(sbuf), + (const char *)&nbuf[doff + 0x7c])) == -1) + return 1; /* * Extract the signal number. It is at @@ -749,14 +698,14 @@ core: sizeof(signo)); if (file_printf(ms, " (signal %u)", elf_getu32(swap, signo)) == -1) - return size; + return 1; *flags |= FLAGS_DID_CORE; - return size; + return 1; } break; default: - if (xnh_type == NT_PRPSINFO && *flags & FLAGS_IS_CORE) { + if (type == NT_PRPSINFO && *flags & FLAGS_IS_CORE) { size_t i, j; unsigned char c; /* @@ -824,7 +773,7 @@ core: * Try next offsets, in case this match is * in the middle of a string. */ - for (k = i + 1 ; k < NOFFSETS ; k++) { + for (k = i + 1 ; k < NOFFSETS; k++) { size_t no; int adjust = 1; if (prpsoffsets(k) >= prpsoffsets(i)) @@ -849,9 +798,9 @@ core: cp--; if (file_printf(ms, ", from '%.*s'", (int)(cp - cname), cname) == -1) - return size; + return 1; *flags |= FLAGS_DID_CORE; - return size; + return 1; tryanother: ; @@ -860,6 +809,129 @@ core: break; } #endif + return 0; +} + +private size_t +donote(struct magic_set *ms, void *vbuf, size_t offset, size_t size, + int clazz, int swap, size_t align, int *flags, uint16_t *notecount) +{ + Elf32_Nhdr nh32; + Elf64_Nhdr nh64; + size_t noff, doff; + uint32_t namesz, descsz; + unsigned char *nbuf = CAST(unsigned char *, vbuf); + + if (*notecount == 0) + return 0; + --*notecount; + + if (xnh_sizeof + offset > size) { + /* + * We're out of note headers. + */ + return xnh_sizeof + offset; + } + + (void)memcpy(xnh_addr, &nbuf[offset], xnh_sizeof); + offset += xnh_sizeof; + + namesz = xnh_namesz; + descsz = xnh_descsz; + if ((namesz == 0) && (descsz == 0)) { + /* + * We're out of note headers. + */ + return (offset >= size) ? offset : size; + } + + if (namesz & 0x80000000) { + (void)file_printf(ms, ", bad note name size 0x%lx", + (unsigned long)namesz); + return 0; + } + + if (descsz & 0x80000000) { + (void)file_printf(ms, ", bad note description size 0x%lx", + (unsigned long)descsz); + return 0; + } + + noff = offset; + doff = ELF_ALIGN(offset + namesz); + + if (offset + namesz > size) { + /* + * We're past the end of the buffer. + */ + return doff; + } + + offset = ELF_ALIGN(doff + descsz); + if (doff + descsz > size) { + /* + * We're past the end of the buffer. + */ + return (offset >= size) ? offset : size; + } + + if ((*flags & FLAGS_DID_OS_NOTE) == 0) { + if (do_os_note(ms, nbuf, xnh_type, swap, + namesz, descsz, noff, doff, flags)) + return size; + } + + if ((*flags & FLAGS_DID_BUILD_ID) == 0) { + if (do_bid_note(ms, nbuf, xnh_type, swap, + namesz, descsz, noff, doff, flags)) + return size; + } + + if ((*flags & FLAGS_DID_NETBSD_PAX) == 0) { + if (do_pax_note(ms, nbuf, xnh_type, swap, + namesz, descsz, noff, doff, flags)) + return size; + } + + if ((*flags & FLAGS_DID_CORE) == 0) { + if (do_core_note(ms, nbuf, xnh_type, swap, + namesz, descsz, noff, doff, flags, size, clazz)) + return size; + } + + if (namesz == 7 && strcmp((char *)&nbuf[noff], "NetBSD") == 0) { + if (descsz > 100) + descsz = 100; + switch (xnh_type) { + case NT_NETBSD_VERSION: + return size; + case NT_NETBSD_MARCH: + if (*flags & FLAGS_DID_NETBSD_MARCH) + return size; + *flags |= FLAGS_DID_NETBSD_MARCH; + if (file_printf(ms, ", compiled for: %.*s", + (int)descsz, (const char *)&nbuf[doff]) == -1) + return size; + break; + case NT_NETBSD_CMODEL: + if (*flags & FLAGS_DID_NETBSD_CMODEL) + return size; + *flags |= FLAGS_DID_NETBSD_CMODEL; + if (file_printf(ms, ", compiler model: %.*s", + (int)descsz, (const char *)&nbuf[doff]) == -1) + return size; + break; + default: + if (*flags & FLAGS_DID_NETBSD_UNKNOWN) + return size; + *flags |= FLAGS_DID_NETBSD_UNKNOWN; + if (file_printf(ms, ", note=%u", xnh_type) == -1) + return size; + break; + } + return size; + } + return offset; } @@ -915,7 +987,8 @@ static const cap_desc_t cap_desc_386[] = { private int doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num, - size_t size, off_t fsize, int *flags, int mach, int strtab) + size_t size, off_t fsize, int mach, int strtab, int *flags, + uint16_t *notecount) { Elf32_Shdr sh32; Elf64_Shdr sh64; @@ -926,6 +999,7 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num, uint64_t cap_hw1 = 0; /* SunOS 5.x hardware capabilites */ uint64_t cap_sf1 = 0; /* SunOS 5.x software capabilites */ char name[50]; + ssize_t namesize; if (size != xsh_sizeof) { if (file_printf(ms, ", corrupted section header size") == -1) @@ -934,7 +1008,7 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num, } /* Read offset of name section to be able to read section names later */ - if (pread(fd, xsh_addr, xsh_sizeof, off + size * strtab) == -1) { + if (pread(fd, xsh_addr, xsh_sizeof, off + size * strtab) < (ssize_t)xsh_sizeof) { file_badread(ms); return -1; } @@ -942,15 +1016,15 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num, for ( ; num; num--) { /* Read the name of this section. */ - if (pread(fd, name, sizeof(name), name_off + xsh_name) == -1) { + if ((namesize = pread(fd, name, sizeof(name) - 1, name_off + xsh_name)) == -1) { file_badread(ms); return -1; } - name[sizeof(name) - 1] = '\0'; + name[namesize] = '\0'; if (strcmp(name, ".debug_info") == 0) stripped = 0; - if (pread(fd, xsh_addr, xsh_sizeof, off) == -1) { + if (pread(fd, xsh_addr, xsh_sizeof, off) < (ssize_t)xsh_sizeof) { file_badread(ms); return -1; } @@ -980,7 +1054,7 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num, " for note"); return -1; } - if (pread(fd, nbuf, xsh_size, xsh_offset) == -1) { + if (pread(fd, nbuf, xsh_size, xsh_offset) < (ssize_t)xsh_size) { file_badread(ms); free(nbuf); return -1; @@ -991,7 +1065,7 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num, if (noff >= (off_t)xsh_size) break; noff = donote(ms, nbuf, (size_t)noff, - xsh_size, clazz, swap, 4, flags); + xsh_size, clazz, swap, 4, flags, notecount); if (noff == 0) break; } @@ -1158,13 +1232,15 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num, */ private int dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off, - int num, size_t size, off_t fsize, int *flags, int sh_num) + int num, size_t size, off_t fsize, int sh_num, int *flags, + uint16_t *notecount) { Elf32_Phdr ph32; Elf64_Phdr ph64; const char *linking_style = "statically"; - const char *shared_libraries = ""; + const char *interp = ""; unsigned char nbuf[BUFSIZ]; + char ibuf[BUFSIZ]; ssize_t bufsize; size_t offset, align, len; @@ -1175,20 +1251,40 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off, } for ( ; num; num--) { - if (pread(fd, xph_addr, xph_sizeof, off) == -1) { + if (pread(fd, xph_addr, xph_sizeof, off) < (ssize_t)xph_sizeof) { file_badread(ms); return -1; } off += size; + bufsize = 0; + align = 4; /* Things we can determine before we seek */ switch (xph_type) { case PT_DYNAMIC: linking_style = "dynamically"; break; + case PT_NOTE: + if (sh_num) /* Did this through section headers */ + continue; + if (((align = xph_align) & 0x80000000UL) != 0 || + align < 4) { + if (file_printf(ms, + ", invalid note alignment 0x%lx", + (unsigned long)align) == -1) + return -1; + align = 4; + } + /*FALLTHROUGH*/ case PT_INTERP: - shared_libraries = " (uses shared libs)"; + len = xph_filesz < sizeof(nbuf) ? xph_filesz + : sizeof(nbuf); + bufsize = pread(fd, nbuf, len, xph_offset); + if (bufsize == -1) { + file_badread(ms); + return -1; + } break; default: if (fsize != SIZE_UNKNOWN && xph_offset > fsize) { @@ -1200,35 +1296,25 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off, /* Things we can determine when we seek */ switch (xph_type) { + case PT_INTERP: + if (bufsize && nbuf[0]) { + nbuf[bufsize - 1] = '\0'; + interp = (const char *)nbuf; + } else + interp = "*empty*"; + break; case PT_NOTE: - if (((align = xph_align) & 0x80000000UL) != 0 || - align < 4) { - if (file_printf(ms, - ", invalid note alignment 0x%lx", - (unsigned long)align) == -1) - return -1; - align = 4; - } - if (sh_num) - break; /* * This is a PT_NOTE section; loop through all the notes * in the section. */ - len = xph_filesz < sizeof(nbuf) ? xph_filesz - : sizeof(nbuf); - bufsize = pread(fd, nbuf, len, xph_offset); - if (bufsize == -1) { - file_badread(ms); - return -1; - } offset = 0; for (;;) { if (offset >= (size_t)bufsize) break; offset = donote(ms, nbuf, offset, (size_t)bufsize, clazz, swap, align, - flags); + flags, notecount); if (offset == 0) break; } @@ -1237,9 +1323,13 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off, break; } } - if (file_printf(ms, ", %s linked%s", linking_style, shared_libraries) + if (file_printf(ms, ", %s linked", linking_style) == -1) - return -1; + return -1; + if (interp[0]) + if (file_printf(ms, ", interpreter %s", + file_printable(ibuf, sizeof(ibuf), interp)) == -1) + return -1; return 0; } @@ -1259,7 +1349,7 @@ file_tryelf(struct magic_set *ms, int fd, const unsigned char *buf, int flags = 0; Elf32_Ehdr elf32hdr; Elf64_Ehdr elf64hdr; - uint16_t type, phnum, shnum; + uint16_t type, phnum, shnum, notecount; if (ms->flags & (MAGIC_MIME|MAGIC_APPLE)) return 0; diff --git a/contrib/file/src/softmagic.c b/contrib/file/src/softmagic.c index c20ae672c09f..5e277e31fdda 100644 --- a/contrib/file/src/softmagic.c +++ b/contrib/file/src/softmagic.c @@ -32,7 +32,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: softmagic.c,v 1.203 2014/12/04 15:22:05 christos Exp $") +FILE_RCSID("@(#)$File: softmagic.c,v 1.206 2015/01/01 17:07:34 christos Exp $") #endif /* lint */ #include "magic.h" @@ -404,28 +404,6 @@ strndup(const char *str, size_t n) } #endif /* HAVE_STRNDUP */ -static char * -printable(char *buf, size_t bufsiz, const char *str) -{ - char *ptr, *eptr; - const unsigned char *s = (const unsigned char *)str; - - for (ptr = buf, eptr = ptr + bufsiz - 1; ptr < eptr && *s; s++) { - if (isprint(*s)) { - *ptr++ = *s; - continue; - } - if (ptr >= eptr + 4) - break; - *ptr++ = '\\'; - *ptr++ = ((*s >> 6) & 7) + '0'; - *ptr++ = ((*s >> 3) & 7) + '0'; - *ptr++ = ((*s >> 0) & 7) + '0'; - } - *ptr = '\0'; - return buf; -} - private int32_t mprint(struct magic_set *ms, struct magic *m) { @@ -433,7 +411,7 @@ mprint(struct magic_set *ms, struct magic *m) float vf; double vd; int64_t t = 0; - char buf[128], tbuf[26]; + char buf[128], tbuf[26], sbuf[512]; union VALUETYPE *p = &ms->ms_value; switch (m->type) { @@ -527,12 +505,13 @@ mprint(struct magic_set *ms, struct magic *m) case FILE_BESTRING16: case FILE_LESTRING16: if (m->reln == '=' || m->reln == '!') { - if (file_printf(ms, F(ms, m, "%s"), m->value.s) == -1) + if (file_printf(ms, F(ms, m, "%s"), + file_printable(sbuf, sizeof(sbuf), m->value.s)) + == -1) return -1; t = ms->offset + m->vallen; } else { - char sbuf[512]; char *str = p->s; /* compute t before we mangle the string? */ @@ -555,7 +534,7 @@ mprint(struct magic_set *ms, struct magic *m) } if (file_printf(ms, F(ms, m, "%s"), - printable(sbuf, sizeof(sbuf), str)) == -1) + file_printable(sbuf, sizeof(sbuf), str)) == -1) return -1; if (m->type == FILE_PSTRING) @@ -659,7 +638,8 @@ mprint(struct magic_set *ms, struct magic *m) file_oomem(ms, ms->search.rm_len); return -1; } - rval = file_printf(ms, F(ms, m, "%s"), cp); + rval = file_printf(ms, F(ms, m, "%s"), + file_printable(sbuf, sizeof(sbuf), cp)); free(cp); if (rval == -1) @@ -673,7 +653,8 @@ mprint(struct magic_set *ms, struct magic *m) } case FILE_SEARCH: - if (file_printf(ms, F(ms, m, "%s"), m->value.s) == -1) + if (file_printf(ms, F(ms, m, "%s"), + file_printable(sbuf, sizeof(sbuf), m->value.s)) == -1) return -1; if ((m->str_flags & REGEX_OFFSET_START)) t = ms->search.offset; @@ -1684,6 +1665,8 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m, break; case FILE_INDIRECT: + if (m->str_flags & INDIRECT_RELATIVE) + offset += o; if (offset == 0) return 0; diff --git a/contrib/file/tests/Makefile.in b/contrib/file/tests/Makefile.in index 23fb89383d2b..691692b0f88f 100644 --- a/contrib/file/tests/Makefile.in +++ b/contrib/file/tests/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.14.1 from Makefile.am. +# Makefile.in generated by automake 1.14 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. diff --git a/lib/libmagic/config.h b/lib/libmagic/config.h index f132303bf15f..47f33472a6fc 100644 --- a/lib/libmagic/config.h +++ b/lib/libmagic/config.h @@ -278,7 +278,7 @@ #define PACKAGE_NAME "file" /* Define to the full name and version of this package. */ -#define PACKAGE_STRING "file 5.21" +#define PACKAGE_STRING "file 5.22" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "file" @@ -287,7 +287,7 @@ #define PACKAGE_URL "" /* Define to the version of this package. */ -#define PACKAGE_VERSION "5.21" +#define PACKAGE_VERSION "5.22" /* Define to 1 if you have the ANSI C header files. */ #define STDC_HEADERS 1 @@ -318,7 +318,7 @@ /* Version number of package */ -#define VERSION "5.21" +#define VERSION "5.22" /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel). */