Hello community,

here is the log from the commit of package dmidecode for openSUSE:Factory 
checked in at 2017-06-07 09:53:45
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/dmidecode (Old)
 and      /work/SRC/openSUSE:Factory/.dmidecode.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "dmidecode"

Wed Jun  7 09:53:45 2017 rev:31 rq:500183 version:3.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/dmidecode/dmidecode.changes      2017-01-25 
22:40:07.574234328 +0100
+++ /work/SRC/openSUSE:Factory/.dmidecode.new/dmidecode.changes 2017-06-07 
09:53:48.508376067 +0200
@@ -1,0 +2,21 @@
+Wed May 24 13:50:05 UTC 2017 - jdelv...@suse.de
+
+- Update to upstream version 3.1:
+  * Support for SMBIOS 3.1.0 and 3.1.1. This includes new chassis
+    types, new processor family names, new processor family upgrade
+    names, and new slot types, as well as support of larger BIOS
+    ROM sizes and cache sizes, and a new structure type (43, TPM
+    Device.)
+  * A new command line option to query OEM strings.
+  * All error messages are now printed on stderr (#47274, #48158.)
+  * Fixes a crash with SIGBUS (#46066.)
+  * Various minor fixes, improvements and cleanups.
+  * Obsoletes dmidecode-01-add-no-sysfs-option-description-to-h-output.patch,
+    dmidecode-02-fix-no-smbios-nor-dmi-entry-point-found-on-smbios3.patch,
+    dmidecode-03-let-read_file-return-the-actual-data-size.patch,
+    dmidecode-04-use-read_file-to-read-the-dmi-table-from-sysfs.patch,
+    dmidecode-05-use-dword-for-structure-table-maximum-size-in-smbios3.patch,
+    dmidecode-06-hide-irrelevant-fixup-message.patch, and
+    dmidecode-07-only-decode-one-dmi-table.patch.
+
+-------------------------------------------------------------------

Old:
----
  dmidecode-01-add-no-sysfs-option-description-to-h-output.patch
  dmidecode-02-fix-no-smbios-nor-dmi-entry-point-found-on-smbios3.patch
  dmidecode-03-let-read_file-return-the-actual-data-size.patch
  dmidecode-04-use-read_file-to-read-the-dmi-table-from-sysfs.patch
  dmidecode-05-use-dword-for-structure-table-maximum-size-in-smbios3.patch
  dmidecode-06-hide-irrelevant-fixup-message.patch
  dmidecode-07-only-decode-one-dmi-table.patch
  dmidecode-3.0.tar.xz
  dmidecode-3.0.tar.xz.sig

New:
----
  dmidecode-3.1.tar.xz
  dmidecode-3.1.tar.xz.sig

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ dmidecode.spec ++++++
--- /var/tmp/diff_new_pack.P8EHsl/_old  2017-06-07 09:53:49.248271507 +0200
+++ /var/tmp/diff_new_pack.P8EHsl/_new  2017-06-07 09:53:49.248271507 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package dmidecode
 #
-# Copyright (c) 2017 SUSE LINUX Products GmbH, Nuernberg, Germany.
+# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany.
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -17,7 +17,7 @@
 
 
 Name:           dmidecode
-Version:        3.0
+Version:        3.1
 Release:        0
 Summary:        DMI table decoder
 License:        GPL-2.0+
@@ -28,13 +28,6 @@
 # would be, but tarball is signed by someone else without signatures.
 # https://savannah.nongnu.org/project/memberlist-gpgkeys.php?group=dmidecode
 # Source2:        %{name}.keyring
-Patch1:         dmidecode-01-add-no-sysfs-option-description-to-h-output.patch
-Patch2:         
dmidecode-02-fix-no-smbios-nor-dmi-entry-point-found-on-smbios3.patch
-Patch3:         dmidecode-03-let-read_file-return-the-actual-data-size.patch
-Patch4:         
dmidecode-04-use-read_file-to-read-the-dmi-table-from-sysfs.patch
-Patch5:         
dmidecode-05-use-dword-for-structure-table-maximum-size-in-smbios3.patch
-Patch6:         dmidecode-06-hide-irrelevant-fixup-message.patch
-Patch7:         dmidecode-07-only-decode-one-dmi-table.patch
 Provides:       pmtools:%{_sbindir}/dmidecode
 Obsoletes:      pmtools < 20071117
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
@@ -57,13 +50,6 @@
 
 %prep
 %setup -q
-%patch1 -p1
-%patch2 -p1
-%patch3 -p1
-%patch4 -p1
-%patch5 -p1
-%patch6 -p1
-%patch7 -p1
 
 %build
 make CFLAGS="%{optflags}" %{?_smp_mflags}

++++++ dmidecode-3.0.tar.xz -> dmidecode-3.1.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dmidecode-3.0/AUTHORS new/dmidecode-3.1/AUTHORS
--- old/dmidecode-3.0/AUTHORS   2015-09-03 08:03:19.000000000 +0200
+++ new/dmidecode-3.1/AUTHORS   2017-05-23 15:34:14.000000000 +0200
@@ -19,6 +19,8 @@
 Anton Arapov <an...@redhat.com>
 Roy Franz <roy.fr...@linaro.org>
 Tyler Bell <tyler.b...@hp.com>
+Xie XiuQi <xiexi...@huawei.com>
+Petr Oros <po...@redhat.com>
 
 MANY THANKS TO (IN CHRONOLOGICAL ORDER)
 Werner Heuser
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dmidecode-3.0/CHANGELOG new/dmidecode-3.1/CHANGELOG
--- old/dmidecode-3.0/CHANGELOG 2015-09-03 08:03:19.000000000 +0200
+++ new/dmidecode-3.1/CHANGELOG 2017-05-23 15:34:14.000000000 +0200
@@ -1,5 +1,103 @@
 2015-09-03  Jean Delvare  <jdelv...@suse.de>
 
+       * version.h: Set version to 3.1.
+
+2017-05-23  Jean Delvare  <jdelv...@suse.de>
+
+       * dmidecode.c, dmiopt.c: Add a new option to extract OEM strings, like
+         we already have for many other strings.
+       * dmidecode.8: Document the new option.
+
+2017-04-27  Jean Delvare  <jdelv...@suse.de>
+
+       Update to support SMBIOS specification version 3.1.1.
+
+       * dmidecode.c: Add support for 3-digit versions.
+       * dmidecode.c: Add new enumerated values for processors (DMI type 4).
+
+2017-04-27  Jean Delvare  <jdelv...@suse.de>
+
+       Update to support SMBIOS specification version 3.1.0.
+
+       * dmidecode.c: Add support for extended BIOS ROM size (DMI type 0).
+       * dmidecode.c: Add new enumerated values for chassis types
+         (DMI type 3).
+       * dmidecode.c: Add new enumerated values for processors (DMI type 4).
+       * dmidecode.c: Don't assume 8-bit processor family in dmi_processor_id
+         (DMI type 4).
+       * dmidecode.c: Decode the MIDR register on ARM processors
+         (DMI type 4).
+       * dmidecode.c: Add support for large cache sizes (DMI type 7).
+       * dmidecode.c: Add Mini PCIe system slot enumerated values
+         (DMI type 9).
+       * dmidecode.c: Clarify the memory speed unit (DMI type 17).
+       * dmidecode.c: Add support for structure type 43 (TPM Device).
+
+2017-04-11  Jean Delvare  <jdelv...@suse.de>
+
+       * util.c: Don't leak a file descriptor in function read_file.
+       * util.c, util.c, dmidecode.c: Let callers pass an offset to function
+         read_file.
+       * dmidecode.c: Fix reading from SMBIOS 3 dump files using a 64-bit
+         entry point.
+
+2017-04-10  Jean Delvare  <jdelv...@suse.de>
+
+       * dmidecode.c: Decode the processor ID of the Intel Core M, AMD
+         Athlon X4 and AMD Opteron X1000/X2000 processors (DMI type 4).
+       * dmidecode.c: Display the IPMI interrupt number as a decimal
+         number (DMI type 38).
+
+2017-01-20  Jean Delvare  <jdelv...@suse.de>
+
+       * biosdecode.c: Decode the entry point defined in the Intel
+         Multiprocessor specification.
+
+2017-01-20  Jean Delvare  <jdelv...@suse.de>
+
+       * dmidecode.c: Only decode one DMI table.
+         This fixes Savannah bug #50022:
+         https://savannah.nongnu.org/bugs/?50022
+
+2016-09-22  Jean Delvare  <jdelv...@suse.de>
+
+       * README: Explain that we can no longer support Cygwin.
+
+2016-06-30  Petr Oros  <po...@redhat.com>
+
+       * dmidecode.c: Unmask LRDIMM in memory type detail (DMI type 17).
+
+2015-11-02  Jean Delvare  <jdelv...@suse.de>
+
+       * dmidecode.c, util.c, util.h: Let read_file return the actual data
+         size.
+       * dmidecode.c: Use read_file to read the DMI table from sysfs.
+         This fixes Savannah bug #46176:
+         https://savannah.nongnu.org/bugs/?46176
+       * dmidecode.c: Check the sysfs entry point length.
+
+2015-10-21  Xie XiuQi  <xiexi...@huawei.com>
+
+       * dmidecode.c: Handle SMBIOS 3.0 entry points on EFI systems.
+
+2015-10-20  Jean Delvare  <jdelv...@suse.de>
+
+       * dmidecode.c: Handle OEM-specific types in group associations
+         (DMI type 14).
+
+2015-10-14  Jean Delvare  <jdelv...@suse.de>
+
+       * util.c: Avoid SIGBUS on mmap failure.
+         This fixes Savannah bug #46066:
+         https://savannah.nongnu.org/bugs/?46066
+       * util.c: Fix error paths in mem_chunk.
+
+2015-10-01  Roy Franz  <roy.fr...@linaro.org>
+
+       * dmiopt.c: Add "--no-sysfs" option description to -h output.
+
+2015-09-03  Jean Delvare  <jdelv...@suse.de>
+
        * version.h: Set version to 3.0.
 
 2015-08-04  Tyler Bell  <tyler.b...@hp.com>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dmidecode-3.0/README new/dmidecode-3.1/README
--- old/dmidecode-3.0/README    2015-09-03 08:03:19.000000000 +0200
+++ new/dmidecode-3.1/README    2017-05-23 15:34:14.000000000 +0200
@@ -28,7 +28,7 @@
 articles.
 
 This program was first written for Linux, and has since been reported to work
-on FreeBSD, NetBSD, OpenBSD, BeOS, Cygwin and Solaris as well.
+on FreeBSD, NetBSD, OpenBSD, BeOS and Solaris as well.
 
 There's no configure script, so simply run "make" to build dmidecode, and
 "make install" to install it. You also can use "make uninstall" to remove
@@ -83,9 +83,8 @@
 
 CYGWIN
 
-Dmidecode was reported to work under Cygwin. It seems that /dev/mem doesn't
-work properly before version 1.5.10 though, so you will need to use at least
-this version.
+Dmidecode used to work under Cygwin. However the /dev/mem interface was
+removed at some point in time so it no longer works.
 
 
 ** MISCELLANEOUS TOOLS **
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dmidecode-3.0/biosdecode.c 
new/dmidecode-3.1/biosdecode.c
--- old/dmidecode-3.0/biosdecode.c      2015-09-03 08:03:19.000000000 +0200
+++ new/dmidecode-3.1/biosdecode.c      2017-05-23 15:34:14.000000000 +0200
@@ -2,7 +2,7 @@
  * BIOS Decode
  *
  *   Copyright (C) 2000-2002 Alan Cox <a...@redhat.com>
- *   Copyright (C) 2002-2015 Jean Delvare <jdelv...@suse.de>
+ *   Copyright (C) 2002-2017 Jean Delvare <jdelv...@suse.de>
  *
  *   This program is free software; you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License as published by
@@ -52,6 +52,9 @@
  *  - Fujitsu application panel technical details
  *    As of July 23rd, 2004
  *    http://apanel.sourceforge.net/tech.php
+ *  - Intel Multiprocessor Specification
+ *    Version 1.4
+ *    http://www.intel.com/design/archives/processors/pro/docs/242016.htm
  */
 
 #include <stdio.h>
@@ -546,6 +549,34 @@
 }
 
 /*
+ * Intel Multiprocessor
+ */
+
+static size_t mp_length(const u8 *p)
+{
+       return 16 * p[8];
+}
+
+static int mp_decode(const u8 *p, size_t len)
+{
+       if (!checksum(p, len))
+               return 0;
+
+       printf("Intel Multiprocessor present.\n");
+       printf("\tSpecification Revision: %s\n",
+               p[9] == 0x01 ? "1.1" : p[9] == 0x04 ? "1.4" : "Invalid");
+       if (p[11])
+               printf("\tDefault Configuration: #%d\n", p[11]);
+       else
+               printf("\tConfiguration Table Address: 0x%08X\n",
+                       DWORD(p + 4));
+       printf("\tMode: %s\n", p[12] & (1 << 7) ?
+               "IMCR and PIC" : "Virtual Wire");
+
+       return 1;
+}
+
+/*
  * Main
  */
 
@@ -562,6 +593,7 @@
        { "32OS", 0, 0xE0000, 0xFFFFF, compaq_length, compaq_decode },
        { "\252\125VPD", 0, 0xF0000, 0xFFFFF, vpd_length, vpd_decode },
        { "FJKEYINF", 0, 0xF0000, 0xFFFFF, fjkeyinf_length, fjkeyinf_decode },
+       { "_MP_", 0, 0xE0000, 0xFFFFF, mp_length, mp_decode },
        { NULL, 0, 0, 0, NULL, NULL }
 };
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dmidecode-3.0/dmidecode.c 
new/dmidecode-3.1/dmidecode.c
--- old/dmidecode-3.0/dmidecode.c       2015-09-03 08:03:19.000000000 +0200
+++ new/dmidecode-3.1/dmidecode.c       2017-05-23 15:34:14.000000000 +0200
@@ -2,7 +2,7 @@
  * DMI Decode
  *
  *   Copyright (C) 2000-2002 Alan Cox <a...@redhat.com>
- *   Copyright (C) 2002-2015 Jean Delvare <jdelv...@suse.de>
+ *   Copyright (C) 2002-2017 Jean Delvare <jdelv...@suse.de>
  *
  *   This program is free software; you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License as published by
@@ -25,7 +25,7 @@
  *   are deemed to be part of the source code.
  *
  * Unless specified otherwise, all references are aimed at the "System
- * Management BIOS Reference Specification, Version 3.0.0" document,
+ * Management BIOS Reference Specification, Version 3.1.1" document,
  * available from http://www.dmtf.org/standards/smbios.
  *
  * Note to contributors:
@@ -50,6 +50,12 @@
  *  - DMTF DSP0239 version 1.1.0
  *    "Management Component Transport Protocol (MCTP) IDs and Codes"
  *    http://www.dmtf.org/standards/pmci
+ *  - "TPM Main, Part 2 TPM Structures"
+ *    Specification version 1.2, level 2, revision 116
+ *    https://trustedcomputinggroup.org/tpm-main-specification/
+ *  - "PC Client Platform TPM Profile (PTP) Specification"
+ *    Family "2.0", Level 00, Revision 00.43, January 26, 2015
+ *    
https://trustedcomputinggroup.org/pc-client-platform-tpm-profile-ptp-specification/
  */
 
 #include <stdio.h>
@@ -69,13 +75,14 @@
 #define out_of_spec "<OUT OF SPEC>"
 static const char *bad_index = "<BAD INDEX>";
 
-#define SUPPORTED_SMBIOS_VER 0x0300
+#define SUPPORTED_SMBIOS_VER 0x030101
 
 #define FLAG_NO_FILE_OFFSET     (1 << 0)
 #define FLAG_STOP_AT_EOT        (1 << 1)
 
-#define SYS_ENTRY_FILE "/sys/firmware/dmi/tables/smbios_entry_point"
-#define SYS_TABLE_FILE "/sys/firmware/dmi/tables/DMI"
+#define SYS_FIRMWARE_DIR "/sys/firmware/dmi/tables"
+#define SYS_ENTRY_FILE SYS_FIRMWARE_DIR "/smbios_entry_point"
+#define SYS_TABLE_FILE SYS_FIRMWARE_DIR "/DMI"
 
 /*
  * Type-independant Stuff
@@ -169,10 +176,13 @@
                "Power Supply",
                "Additional Information",
                "Onboard Device",
-               "Management Controller Host Interface", /* 42 */
+               "Management Controller Host Interface",
+               "TPM Device", /* 43 */
        };
 
-       if (code <= 42)
+       if (code >= 128)
+               return "OEM-specific";
+       if (code <= 43)
                return type[code];
        return out_of_spec;
 }
@@ -292,6 +302,18 @@
                printf(" %u kB", code >> 10);
 }
 
+static void dmi_bios_rom_size(u8 code1, u16 code2)
+{
+       static const char *unit[4] = {
+               "MB", "GB", out_of_spec, out_of_spec
+       };
+
+       if (code1 != 0xFF)
+               printf(" %u kB", (code1 + 1) << 6);
+       else
+               printf(" %u %s", code2 & 0x3FFF, unit[code2 >> 14]);
+}
+
 static void dmi_bios_characteristics(u64 code, const char *prefix)
 {
        /* 7.1.1 */
@@ -550,12 +572,16 @@
                "Blade Enclosing",
                "Tablet",
                "Convertible",
-               "Detachable" /* 0x20 */
+               "Detachable",
+               "IoT Gateway",
+               "Embedded PC",
+               "Mini PC",
+               "Stick PC" /* 0x24 */
        };
 
        code &= 0x7F; /* bits 6:0 are chassis type, 7th bit is the lock bit */
 
-       if (code >= 0x01 && code <= 0x20)
+       if (code >= 0x01 && code <= 0x24)
                return type[code - 0x01];
        return out_of_spec;
 }
@@ -717,7 +743,9 @@
                { 0x2A, "Core Solo Mobile" },
                { 0x2B, "Atom" },
                { 0x2C, "Core M" },
-
+               { 0x2D, "Core m3" },
+               { 0x2E, "Core m5" },
+               { 0x2F, "Core m7" },
                { 0x30, "Alpha" },
                { 0x31, "Alpha 21064" },
                { 0x32, "Alpha 21066" },
@@ -769,6 +797,9 @@
                { 0x66, "Athlon X4" },
                { 0x67, "Opteron X1000" },
                { 0x68, "Opteron X2000" },
+               { 0x69, "Opteron A-Series" },
+               { 0x6A, "Opteron X3000" },
+               { 0x6B, "Zen" },
 
                { 0x70, "Hobbit" },
 
@@ -880,6 +911,8 @@
                { 0xFA, "i860" },
                { 0xFB, "i960" },
 
+               { 0x100, "ARMv7" },
+               { 0x101, "ARMv8" },
                { 0x104, "SH-3" },
                { 0x105, "SH-4" },
                { 0x118, "ARM" },
@@ -891,6 +924,10 @@
                { 0x15E, "DSP" },
                { 0x1F4, "Video Processor" },
        };
+       /*
+        * Note to developers: when adding entries to this list, check if
+        * function dmi_processor_id below needs updating too.
+        */
 
        /* Special case for ambiguous value 0x30 (SMBIOS 2.0 only) */
        if (ver == 0x0200 && data[0x06] == 0x30 && h->length >= 0x08)
@@ -943,7 +980,7 @@
        }
 }
 
-static void dmi_processor_id(u8 type, const u8 *p, const char *version, const 
char *prefix)
+static void dmi_processor_id(const struct dmi_header *h, const char *prefix)
 {
        /* Intel AP-485 revision 36, table 2-4 */
        static const char *flags[32] = {
@@ -980,13 +1017,14 @@
                NULL, /* 30 */
                "PBE (Pending break enabled)" /* 31 */
        };
-       /*
-        * Extra flags are now returned in the ECX register when one calls
-        * the CPUID instruction. Their meaning is explained in table 3-5, but
-        * DMI doesn't support this yet.
-        */
+       const u8 *data = h->data;
+       const u8 *p = data + 0x08;
        u32 eax, edx;
        int sig = 0;
+       u16 type;
+
+       type = (data[0x06] == 0xFE && h->length >= 0x2A) ?
+               WORD(data + 0x28) : data[0x06];
 
        /*
         * This might help learn about new processors supporting the
@@ -1026,8 +1064,24 @@
                        return;
                }
        }
+       else if ((type >= 0x100 && type <= 0x101) /* ARM */
+             || (type >= 0x118 && type <= 0x119)) /* ARM */
+       {
+               u32 midr = DWORD(p);
+               /*
+                * The format of this field was not defined for ARM processors
+                * before version 3.1.0 of the SMBIOS specification, so we
+                * silently skip it if it reads all zeroes.
+                */
+               if (midr == 0)
+                       return;
+               printf("%sSignature: Implementor 0x%02x, Variant 0x%x, 
Architecture %u, Part 0x%03x, Revision %u\n",
+                       prefix, midr >> 24, (midr >> 20) & 0xF,
+                       (midr >> 16) & 0xF, (midr >> 4) & 0xFFF, midr & 0xF);
+               return;
+       }
        else if ((type >= 0x0B && type <= 0x15) /* Intel, Cyrix */
-             || (type >= 0x28 && type <= 0x2B) /* Intel */
+             || (type >= 0x28 && type <= 0x2F) /* Intel */
              || (type >= 0xA1 && type <= 0xB3) /* Intel */
              || type == 0xB5 /* Intel */
              || (type >= 0xB9 && type <= 0xC7) /* Intel */
@@ -1039,12 +1093,14 @@
              || type == 0x1F /* AMD */
              || (type >= 0x38 && type <= 0x3F) /* AMD */
              || (type >= 0x46 && type <= 0x4F) /* AMD */
+             || (type >= 0x66 && type <= 0x6B) /* AMD */
              || (type >= 0x83 && type <= 0x8F) /* AMD */
              || (type >= 0xB6 && type <= 0xB7) /* AMD */
              || (type >= 0xE4 && type <= 0xEF)) /* AMD */
                sig = 2;
        else if (type == 0x01 || type == 0x02)
        {
+               const char *version = dmi_string(h, data[0x10]);
                /*
                 * Some X86-class CPU have family "Other" or "Unknown". In this 
case,
                 * we use the version string to determine if they are known to
@@ -1062,9 +1118,14 @@
                else
                        return;
        }
-       else /* not X86-class */
+       else /* neither X86 nor ARM */
                return;
 
+       /*
+        * Extra flags are now returned in the ECX register when one calls
+        * the CPUID instruction. Their meaning is explained in table 3-5, but
+        * DMI doesn't support this yet.
+        */
        eax = DWORD(p);
        edx = DWORD(p + 4);
        switch (sig)
@@ -1200,10 +1261,18 @@
                "Socket LGA1150",
                "Socket BGA1168",
                "Socket BGA1234",
-               "Socket BGA1364" /* 0x30 */
+               "Socket BGA1364",
+               "Socket AM4",
+               "Socket LGA1151",
+               "Socket BGA1356",
+               "Socket BGA1440",
+               "Socket BGA1515",
+               "Socket LGA3647-1",
+               "Socket SP3",
+               "Socket SP3r2" /* 0x38 */
        };
 
-       if (code >= 0x01 && code <= 0x30)
+       if (code >= 0x01 && code <= 0x38)
                return upgrade[code - 0x01];
        return out_of_spec;
 }
@@ -1476,6 +1545,21 @@
                printf(" %u kB", code);
 }
 
+static void dmi_cache_size_2(u32 code)
+{
+       if (code & 0x80000000)
+       {
+               code &= 0x7FFFFFFFLU;
+               /* Use a more convenient unit for large cache size */
+               if (code >= 0x8000)
+                       printf(" %u MB", code >> 4);
+               else
+                       printf(" %u kB", code << 6);
+       }
+       else
+               printf(" %u kB", code);
+}
+
 static void dmi_cache_types(u16 code, const char *sep)
 {
        /* 7.8.2 */
@@ -1712,7 +1796,10 @@
                "MXM 3.0 Type A",
                "MXM 3.0 Type B",
                "PCI Express 2 SFF-8639",
-               "PCI Express 3 SFF-8639" /* 0x20 */
+               "PCI Express 3 SFF-8639",
+               "PCI Express Mini 52-pin with bottom-side keep-outs",
+               "PCI Express Mini 52-pin without bottom-side keep-outs",
+               "PCI Express Mini 76-pin" /* 0x23 */
        };
        static const char *type_0xA0[] = {
                "PC-98/C20", /* 0xA0 */
@@ -1744,7 +1831,7 @@
         * function dmi_slot_id below needs updating too.
         */
 
-       if (code >= 0x01 && code <= 0x20)
+       if (code >= 0x01 && code <= 0x23)
                return type[code - 0x01];
        if (code >= 0xA0 && code <= 0xB6)
                return type_0xA0[code - 0xA0];
@@ -1826,6 +1913,9 @@
                case 0x13: /* AGP */
                case 0x1F: /* PCI Express 2 */
                case 0x20: /* PCI Express 3 */
+               case 0x21: /* PCI Express Mini */
+               case 0x22: /* PCI Express Mini */
+               case 0x23: /* PCI Express Mini */
                case 0xA5: /* PCI Express */
                case 0xA6: /* PCI Express */
                case 0xA7: /* PCI Express */
@@ -2274,10 +2364,13 @@
 {
        code &= 0x7FFFFFFFUL;
 
-       /* Use the most suitable unit depending on size */
+       /*
+        * Use the greatest unit for which the exact value can be displayed
+        * as an integer without rounding
+        */
        if (code & 0x3FFUL)
                printf(" %lu MB", (unsigned long)code);
-       else if (code & 0xFFFFFUL)
+       else if (code & 0xFFC00UL)
                printf(" %lu GB", (unsigned long)code >> 10);
        else
                printf(" %lu TB", (unsigned long)code >> 20);
@@ -2389,7 +2482,7 @@
                "LRDIMM"  /* 15 */
        };
 
-       if ((code & 0x7FFE) == 0)
+       if ((code & 0xFFFE) == 0)
                printf(" None");
        else
        {
@@ -2406,7 +2499,7 @@
        if (code == 0)
                printf(" Unknown");
        else
-               printf(" %u MHz", code);
+               printf(" %u MT/s", code);
 }
 
 /*
@@ -2946,7 +3039,7 @@
  * first 5 characters of the device name to be trimmed. It's easy to
  * check and fix, so do it, but warn.
  */
-static void dmi_fixup_type_34(struct dmi_header *h)
+static void dmi_fixup_type_34(struct dmi_header *h, int display)
 {
        u8 *p = h->data;
 
@@ -2954,7 +3047,10 @@
        if (h->length == 0x10
         && is_printable(p + 0x0B, 0x10 - 0x0B))
        {
-               printf("Invalid entry length (%u). Fixed up to %u.\n", 0x10, 
0x0B);
+               if (!(opt.flags & FLAG_QUIET) && display)
+                       fprintf(stderr,
+                               "Invalid entry length (%u). Fixed up to %u.\n",
+                               0x10, 0x0B);
                h->length = 0x0B;
        }
 }
@@ -3223,6 +3319,57 @@
 }
 
 /*
+ * 7.44 TPM Device (Type 43)
+ */
+
+static void dmi_tpm_vendor_id(const u8 *p)
+{
+       char vendor_id[5];
+       int i;
+
+       /* ASCII filtering */
+       for (i = 0; i < 4 && p[i] != 0; i++)
+       {
+               if (p[i] < 32 || p[i] >= 127)
+                       vendor_id[i] = '.';
+               else
+                       vendor_id[i] = p[i];
+       }
+
+       /* Terminate the string */
+       vendor_id[i] = '\0';
+
+       printf(" %s", vendor_id);
+}
+
+static void dmi_tpm_characteristics(u64 code, const char *prefix)
+{
+       /* 7.1.1 */
+       static const char *characteristics[] = {
+               "TPM Device characteristics not supported", /* 2 */
+               "Family configurable via firmware update",
+               "Family configurable via platform software support",
+               "Family configurable via OEM proprietary mechanism" /* 5 */
+       };
+       int i;
+
+       /*
+        * This isn't very clear what this bit is supposed to mean
+        */
+       if (code.l & (1 << 2))
+       {
+               printf("%s%s\n",
+                       prefix, characteristics[0]);
+               return;
+       }
+
+       for (i = 3; i <= 5; i++)
+               if (code.l & (1 << i))
+                       printf("%s%s\n",
+                               prefix, characteristics[i - 2]);
+}
+
+/*
  * Main
  */
 
@@ -3257,8 +3404,9 @@
                                dmi_bios_runtime_size((0x10000 - WORD(data + 
0x06)) << 4);
                                printf("\n");
                        }
-                       printf("\tROM Size: %u kB\n",
-                               (data[0x09] + 1) << 6);
+                       printf("\tROM Size:");
+                       dmi_bios_rom_size(data[0x09], h->length < 0x1A ? 16 : 
WORD(data + 0x18));
+                       printf("\n");
                        printf("\tCharacteristics:\n");
                        dmi_bios_characteristics(QWORD(data + 0x0A), "\t\t");
                        if (h->length < 0x13) break;
@@ -3382,7 +3530,7 @@
                                dmi_processor_family(h, ver));
                        printf("\tManufacturer: %s\n",
                                dmi_string(h, data[0x07]));
-                       dmi_processor_id(data[0x06], data + 0x08, dmi_string(h, 
data[0x10]), "\t");
+                       dmi_processor_id(h, "\t");
                        printf("\tVersion: %s\n",
                                dmi_string(h, data[0x10]));
                        printf("\tVoltage:");
@@ -3509,10 +3657,16 @@
                        printf("\tLocation: %s\n",
                                dmi_cache_location((WORD(data + 0x05) >> 5) & 
0x0003));
                        printf("\tInstalled Size:");
-                       dmi_cache_size(WORD(data + 0x09));
+                       if (h->length >= 0x1B)
+                               dmi_cache_size_2(DWORD(data + 0x17));
+                       else
+                               dmi_cache_size(WORD(data + 0x09));
                        printf("\n");
                        printf("\tMaximum Size:");
-                       dmi_cache_size(WORD(data + 0x07));
+                       if (h->length >= 0x17)
+                               dmi_cache_size_2(DWORD(data + 0x13));
+                       else
+                               dmi_cache_size(WORD(data + 0x07));
                        printf("\n");
                        printf("\tSupported SRAM Types:");
                        dmi_cache_types(WORD(data + 0x0B), "\n\t\t");
@@ -4234,7 +4388,7 @@
                        }
                        if (data[0x11] != 0x00)
                        {
-                               printf("\tInterrupt Number: %x\n",
+                               printf("\tInterrupt Number: %u\n",
                                        data[0x11]);
                        }
                        break;
@@ -4331,6 +4485,43 @@
                        }
                        break;
 
+               case 43: /* 7.44 TPM Device */
+                       printf("TPM Device\n");
+                       if (h->length < 0x1B) break;
+                       printf("\tVendor ID:");
+                       dmi_tpm_vendor_id(data + 0x04);
+                       printf("\n");
+                       printf("\tSpecification Version: %d.%d", data[0x08], 
data[0x09]);
+                       switch (data[0x08])
+                       {
+                               case 0x01:
+                                       /*
+                                        * We skip the first 2 bytes, which are
+                                        * redundant with the above, and uncoded
+                                        * in a silly way.
+                                        */
+                                       printf("\tFirmware Revision: %u.%u\n",
+                                               data[0x0C], data[0x0D]);
+                                       break;
+                               case 0x02:
+                                       printf("\tFirmware Revision: %u.%u\n",
+                                               DWORD(data + 0x0A) >> 16,
+                                               DWORD(data + 0x0A) && 0xFF);
+                                       /*
+                                        * We skip the next 4 bytes, as their
+                                        * format is not standardized and their
+                                        * usefulness seems limited anyway.
+                                        */
+                                       break;
+                       }
+                       printf("\tDescription: %s", dmi_string(h, data[0x12]));
+                       printf("\tCharacteristics:\n");
+                       dmi_tpm_characteristics(QWORD(data + 0x13), "\t\t");
+                       if (h->length < 0x1F) break;
+                       printf("\tOEM-specific Information: 0x%08X\n",
+                               DWORD(data + 0x1B));
+                       break;
+
                case 126: /* 7.44 Inactive */
                        printf("Inactive\n");
                        break;
@@ -4364,6 +4555,21 @@
        int key;
        u8 offset = opt.string->offset;
 
+       if (opt.string->type == 11) /* OEM strings */
+       {
+               if (h->length < 5 || offset > data[4])
+               {
+                       fprintf(stderr, "No OEM string number %u\n", offset);
+                       return;
+               }
+
+               if (offset)
+                       printf("%s\n", dmi_string(h, offset));
+               else
+                       printf("%u\n", data[4]);        /* count */
+               return;
+       }
+
        if (offset >= h->length)
                return;
 
@@ -4422,9 +4628,14 @@
                 */
                if (h.length < 4)
                {
-                       printf("Invalid entry length (%u). DMI table is "
-                              "broken! Stop.\n\n", (unsigned int)h.length);
-                       opt.flags |= FLAG_QUIET;
+                       if (!(opt.flags & FLAG_QUIET))
+                       {
+                               fprintf(stderr,
+                                       "Invalid entry length (%u). DMI table "
+                                       "is broken! Stop.\n\n",
+                                       (unsigned int)h.length);
+                               opt.flags |= FLAG_QUIET;
+                       }
                        break;
                }
 
@@ -4443,7 +4654,7 @@
 
                /* Fixup a common mistake */
                if (h.type == 34)
-                       dmi_fixup_type_34(&h);
+                       dmi_fixup_type_34(&h, display);
 
                /* look for the next handle */
                next = data + h.length;
@@ -4485,26 +4696,28 @@
        if (!(opt.flags & FLAG_QUIET))
        {
                if (num && i != num)
-                       printf("Wrong DMI structures count: %d announced, "
+                       fprintf(stderr, "Wrong DMI structures count: %d 
announced, "
                                "only %d decoded.\n", num, i);
                if ((unsigned long)(data - buf) > len
                 || (num && (unsigned long)(data - buf) < len))
-                       printf("Wrong DMI structures length: %u bytes "
+                       fprintf(stderr, "Wrong DMI structures length: %u bytes "
                                "announced, structures occupy %lu bytes.\n",
                                len, (unsigned long)(data - buf));
        }
 }
 
-static void dmi_table(off_t base, u32 len, u16 num, u16 ver, const char 
*devmem,
+static void dmi_table(off_t base, u32 len, u16 num, u32 ver, const char 
*devmem,
                      u32 flags)
 {
        u8 *buf;
 
        if (ver > SUPPORTED_SMBIOS_VER && !(opt.flags & FLAG_QUIET))
        {
-               printf("# SMBIOS implementations newer than version %u.%u are 
not\n"
+               printf("# SMBIOS implementations newer than version %u.%u.%u 
are not\n"
                       "# fully supported by this version of dmidecode.\n",
-                      SUPPORTED_SMBIOS_VER >> 8, SUPPORTED_SMBIOS_VER & 0xFF);
+                      SUPPORTED_SMBIOS_VER >> 16,
+                      (SUPPORTED_SMBIOS_VER >> 8) & 0xFF,
+                      SUPPORTED_SMBIOS_VER & 0xFF);
        }
 
        if (!(opt.flags & FLAG_QUIET))
@@ -4521,29 +4734,45 @@
                printf("\n");
        }
 
-       /*
-        * When we are reading the DMI table from sysfs, we want to print
-        * the address of the table (done above), but the offset of the
-        * data in the file is 0.  When reading from /dev/mem, the offset
-        * in the file is the address.
-        */
-       if (flags & FLAG_NO_FILE_OFFSET)
-               base = 0;
+       if ((flags & FLAG_NO_FILE_OFFSET) || (opt.flags & FLAG_FROM_DUMP))
+       {
+               /*
+                * When reading from sysfs or from a dump file, the file may be
+                * shorter than announced. For SMBIOS v3 this is expcted, as we
+                * only know the maximum table size, not the actual table size.
+                * For older implementations (and for SMBIOS v3 too), this
+                * would be the result of the kernel truncating the table on
+                * parse error.
+                */
+               size_t size = len;
+               buf = read_file(flags & FLAG_NO_FILE_OFFSET ? 0 : base,
+                       &size, devmem);
+               if (!(opt.flags & FLAG_QUIET) && num && size != (size_t)len)
+               {
+                       fprintf(stderr, "Wrong DMI structures length: %u bytes "
+                               "announced, only %lu bytes available.\n",
+                               len, (unsigned long)size);
+               }
+               len = size;
+       }
+       else
+               buf = mem_chunk(base, len, devmem);
 
-       if ((buf = mem_chunk(base, len, devmem)) == NULL)
+       if (buf == NULL)
        {
-               fprintf(stderr, "Table is unreachable, sorry."
+               fprintf(stderr, "Failed to read table, sorry.\n");
 #ifndef USE_MMAP
-                       " Try compiling dmidecode with -DUSE_MMAP."
+               if (!(flags & FLAG_NO_FILE_OFFSET))
+                       fprintf(stderr,
+                               "Try compiling dmidecode with -DUSE_MMAP.\n");
 #endif
-                       "\n");
                return;
        }
 
        if (opt.flags & FLAG_DUMP_BIN)
                dmi_table_dump(buf, len);
        else
-               dmi_table_decode(buf, len, num, ver, flags);
+               dmi_table_decode(buf, len, num, ver >> 8, flags);
 
        free(buf);
 }
@@ -4580,13 +4809,13 @@
 
 static int smbios3_decode(u8 *buf, const char *devmem, u32 flags)
 {
-       u16 ver;
+       u32 ver;
        u64 offset;
 
        if (!checksum(buf, buf[0x06]))
                return 0;
 
-       ver = (buf[0x07] << 8) + buf[0x08];
+       ver = (buf[0x07] << 16) + (buf[0x08] << 8) + buf[0x09];
        if (!(opt.flags & FLAG_QUIET))
                printf("SMBIOS %u.%u.%u present.\n",
                       buf[0x07], buf[0x08], buf[0x09]);
@@ -4599,7 +4828,7 @@
        }
 
        dmi_table(((off_t)offset.h << 32) | offset.l,
-                 WORD(buf + 0x0C), 0, ver, devmem, flags | FLAG_STOP_AT_EOT);
+                 DWORD(buf + 0x0C), 0, ver, devmem, flags | FLAG_STOP_AT_EOT);
 
        if (opt.flags & FLAG_DUMP_BIN)
        {
@@ -4633,14 +4862,16 @@
                case 0x021F:
                case 0x0221:
                        if (!(opt.flags & FLAG_QUIET))
-                               printf("SMBIOS version fixup (2.%d -> 2.%d).\n",
-                                      ver & 0xFF, 3);
+                               fprintf(stderr,
+                                       "SMBIOS version fixup (2.%d -> 
2.%d).\n",
+                                       ver & 0xFF, 3);
                        ver = 0x0203;
                        break;
                case 0x0233:
                        if (!(opt.flags & FLAG_QUIET))
-                               printf("SMBIOS version fixup (2.%d -> 2.%d).\n",
-                                      51, 6);
+                               fprintf(stderr,
+                                       "SMBIOS version fixup (2.%d -> 
2.%d).\n",
+                                       51, 6);
                        ver = 0x0206;
                        break;
        }
@@ -4649,7 +4880,7 @@
                        ver >> 8, ver & 0xFF);
 
        dmi_table(DWORD(buf + 0x18), WORD(buf + 0x16), WORD(buf + 0x1C),
-               ver, devmem, flags);
+               ver << 8, devmem, flags);
 
        if (opt.flags & FLAG_DUMP_BIN)
        {
@@ -4677,7 +4908,8 @@
                        buf[0x0E] >> 4, buf[0x0E] & 0x0F);
 
        dmi_table(DWORD(buf + 0x08), WORD(buf + 0x06), WORD(buf + 0x0C),
-               ((buf[0x0E] & 0xF0) << 4) + (buf[0x0E] & 0x0F), devmem, flags);
+               ((buf[0x0E] & 0xF0) << 12) + ((buf[0x0E] & 0x0F) << 8),
+               devmem, flags);
 
        if (opt.flags & FLAG_DUMP_BIN)
        {
@@ -4748,9 +4980,17 @@
        int ret = 0;                /* Returned value */
        int found = 0;
        off_t fp;
+       size_t size;
        int efi;
        u8 *buf;
 
+       /*
+        * We don't want stdout and stderr to be mixed up if both are
+        * redirected to the same file.
+        */
+       setlinebuf(stdout);
+       setlinebuf(stderr);
+
        if (sizeof(u8) != 1 || sizeof(u16) != 2 || sizeof(u32) != 4 || '\0' != 
0)
        {
                fprintf(stderr, "%s: compiler incompatibility\n", argv[0]);
@@ -4817,22 +5057,23 @@
         * contain one of several types of entry points, so read enough for
         * the largest one, then determine what type it contains.
         */
+       size = 0x20;
        if (!(opt.flags & FLAG_NO_SYSFS)
-        && (buf = read_file(0x20, SYS_ENTRY_FILE)) != NULL)
+        && (buf = read_file(0, &size, SYS_ENTRY_FILE)) != NULL)
        {
                if (!(opt.flags & FLAG_QUIET))
                        printf("Getting SMBIOS data from sysfs.\n");
-               if (memcmp(buf, "_SM3_", 5) == 0)
+               if (size >= 24 && memcmp(buf, "_SM3_", 5) == 0)
                {
                        if (smbios3_decode(buf, SYS_TABLE_FILE, 
FLAG_NO_FILE_OFFSET))
                                found++;
                }
-               else if (memcmp(buf, "_SM_", 4) == 0)
+               else if (size >= 31 && memcmp(buf, "_SM_", 4) == 0)
                {
                        if (smbios_decode(buf, SYS_TABLE_FILE, 
FLAG_NO_FILE_OFFSET))
                                found++;
                }
-               else if (memcmp(buf, "_DMI_", 5) == 0)
+               else if (size >= 15 && memcmp(buf, "_DMI_", 5) == 0)
                {
                        if (legacy_decode(buf, SYS_TABLE_FILE, 
FLAG_NO_FILE_OFFSET))
                                found++;
@@ -4864,8 +5105,16 @@
                goto exit_free;
        }
 
-       if (smbios_decode(buf, opt.devmem, 0))
-               found++;
+       if (memcmp(buf, "_SM3_", 5) == 0)
+       {
+               if (smbios3_decode(buf, opt.devmem, 0))
+                       found++;
+       }
+       else if (memcmp(buf, "_SM_", 4) == 0)
+       {
+               if (smbios_decode(buf, opt.devmem, 0))
+                       found++;
+       }
        goto done;
 
 memory_scan:
@@ -4878,28 +5127,37 @@
                goto exit_free;
        }
 
-       for (fp = 0; fp <= 0xFFF0; fp += 16)
+       /* Look for a 64-bit entry point first */
+       for (fp = 0; fp <= 0xFFE0; fp += 16)
        {
-               if (memcmp(buf + fp, "_SM3_", 5) == 0 && fp <= 0xFFE0)
+               if (memcmp(buf + fp, "_SM3_", 5) == 0)
                {
                        if (smbios3_decode(buf + fp, opt.devmem, 0))
                        {
                                found++;
-                               fp += 16;
+                               goto done;
                        }
                }
-               else if (memcmp(buf + fp, "_SM_", 4) == 0 && fp <= 0xFFE0)
+       }
+
+       /* If none found, look for a 32-bit entry point */
+       for (fp = 0; fp <= 0xFFF0; fp += 16)
+       {
+               if (memcmp(buf + fp, "_SM_", 4) == 0 && fp <= 0xFFE0)
                {
                        if (smbios_decode(buf + fp, opt.devmem, 0))
                        {
                                found++;
-                               fp += 16;
+                               goto done;
                        }
                }
                else if (memcmp(buf + fp, "_DMI_", 5) == 0)
                {
                        if (legacy_decode(buf + fp, opt.devmem, 0))
+                       {
                                found++;
+                               goto done;
+                       }
                }
        }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dmidecode-3.0/dmiopt.c new/dmidecode-3.1/dmiopt.c
--- old/dmidecode-3.0/dmiopt.c  2015-09-03 08:03:19.000000000 +0200
+++ new/dmidecode-3.1/dmiopt.c  2017-05-23 15:34:14.000000000 +0200
@@ -20,6 +20,7 @@
  */
 
 #include <stdio.h>
+#include <string.h>
 #include <strings.h>
 #include <stdlib.h>
 #include <getopt.h>
@@ -171,6 +172,10 @@
        { "processor-frequency", 4, 0x16 },     /* dmi_processor_frequency() */
 };
 
+/* This is a template, 3rd field is set at runtime. */
+static struct string_keyword opt_oem_string_keyword =
+       { NULL, 11, 0x00 };
+
 static void print_opt_string_list(void)
 {
        unsigned int i;
@@ -206,6 +211,34 @@
        return -1;
 }
 
+static int parse_opt_oem_string(const char *arg)
+{
+       unsigned long val;
+       char *next;
+
+       if (opt.string)
+       {
+               fprintf(stderr, "Only one string can be specified\n");
+               return -1;
+       }
+
+       /* Return the number of OEM strings */
+       if (strcmp(arg, "count") == 0)
+               goto done;
+
+       val = strtoul(arg, &next, 10);
+       if (next == arg || val == 0x00 || val > 0xff)
+       {
+               fprintf(stderr, "Invalid OEM string number: %s\n", arg);
+               return -1;
+       }
+
+       opt_oem_string_keyword.offset = val;
+done:
+       opt.string = &opt_oem_string_keyword;
+       return 0;
+}
+
 
 /*
  * Command line options handling
@@ -225,6 +258,7 @@
                { "dump", no_argument, NULL, 'u' },
                { "dump-bin", required_argument, NULL, 'B' },
                { "from-dump", required_argument, NULL, 'F' },
+               { "oem-string", required_argument, NULL, 'O' },
                { "no-sysfs", no_argument, NULL, 'S' },
                { "version", no_argument, NULL, 'V' },
                { NULL, 0, NULL, 0 }
@@ -255,6 +289,11 @@
                                        return -1;
                                opt.flags |= FLAG_QUIET;
                                break;
+                       case 'O':
+                               if (parse_opt_oem_string(optarg) < 0)
+                                       return -1;
+                               opt.flags |= FLAG_QUIET;
+                               break;
                        case 't':
                                opt.type = parse_opt_type(opt.type, optarg);
                                if (opt.type == NULL)
@@ -314,6 +353,8 @@
                " -u, --dump             Do not decode the entries\n"
                "     --dump-bin FILE    Dump the DMI data to a binary file\n"
                "     --from-dump FILE   Read the DMI data from a binary file\n"
+               "     --no-sysfs         Do not attempt to read DMI data from 
sysfs files\n"
+               "     --oem-string N     Only display the value of the given 
OEM string\n"
                " -V, --version          Display the version and exit\n";
 
        printf("%s", help);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dmidecode-3.0/man/dmidecode.8 
new/dmidecode-3.1/man/dmidecode.8
--- old/dmidecode-3.0/man/dmidecode.8   2015-09-03 08:03:19.000000000 +0200
+++ new/dmidecode-3.1/man/dmidecode.8   2017-05-23 15:34:14.000000000 +0200
@@ -134,13 +134,18 @@
 Do not attempt to read DMI data from sysfs files. This is mainly useful for
 debugging.
 .TP
+.BR "  " "  " "--oem-string N"
+Only display the value of the \s-1OEM\s0 string number \fBN\fR. The first
+\s-1OEM\s0 string has number 1. With special value "count", return the
+number of OEM strings instead.
+.TP
 .BR "-h" ", " "--help"
 Display usage information and exit
 .TP
 .BR "-V" ", " "--version"
 Display the version and exit
 .P
-Options --string, --type and --dump-bin
+Options --string, --type, --dump-bin and --oem-string
 determine the output format and are mutually exclusive.
 .P
 Please note in case of
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dmidecode-3.0/util.c new/dmidecode-3.1/util.c
--- old/dmidecode-3.0/util.c    2015-09-03 08:03:19.000000000 +0200
+++ new/dmidecode-3.1/util.c    2017-05-23 15:34:14.000000000 +0200
@@ -2,7 +2,7 @@
  * Common "util" functions
  * This file is part of the dmidecode project.
  *
- *   Copyright (C) 2002-2015 Jean Delvare <jdelv...@suse.de>
+ *   Copyright (C) 2002-2017 Jean Delvare <jdelv...@suse.de>
  *
  *   This program is free software; you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License as published by
@@ -89,15 +89,16 @@
 }
 
 /*
- * Reads all of file, up to max_len bytes.
+ * Reads all of file from given offset, up to max_len bytes.
  * A buffer of max_len bytes is allocated by this function, and
  * needs to be freed by the caller.
  * This provides a similar usage model to mem_chunk()
  *
- * Returns pointer to buffer of max_len bytes, or NULL on error
+ * Returns pointer to buffer of max_len bytes, or NULL on error, and
+ * sets max_len to the length actually read.
  *
  */
-void *read_file(size_t max_len, const char *filename)
+void *read_file(off_t base, size_t *max_len, const char *filename)
 {
        int fd;
        size_t r2 = 0;
@@ -112,26 +113,34 @@
        {
                if (errno != ENOENT)
                        perror(filename);
-               return(NULL);
+               return NULL;
        }
 
-       if ((p = malloc(max_len)) == NULL)
+       if (lseek(fd, base, SEEK_SET) == -1)
+       {
+               fprintf(stderr, "%s: ", filename);
+               perror("lseek");
+               p = NULL;
+               goto out;
+       }
+
+       if ((p = malloc(*max_len)) == NULL)
        {
                perror("malloc");
-               return NULL;
+               goto out;
        }
 
        do
        {
-               r = read(fd, p + r2, max_len - r2);
+               r = read(fd, p + r2, *max_len - r2);
                if (r == -1)
                {
                        if (errno != EINTR)
                        {
-                               close(fd);
                                perror(filename);
                                free(p);
-                               return NULL;
+                               p = NULL;
+                               goto out;
                        }
                }
                else
@@ -139,7 +148,10 @@
        }
        while (r != 0);
 
+       *max_len = r2;
+out:
        close(fd);
+
        return p;
 }
 
@@ -152,6 +164,7 @@
        void *p;
        int fd;
 #ifdef USE_MMAP
+       struct stat statbuf;
        off_t mmoffset;
        void *mmp;
 #endif
@@ -165,10 +178,28 @@
        if ((p = malloc(len)) == NULL)
        {
                perror("malloc");
-               return NULL;
+               goto out;
        }
 
 #ifdef USE_MMAP
+       if (fstat(fd, &statbuf) == -1)
+       {
+               fprintf(stderr, "%s: ", devmem);
+               perror("stat");
+               goto err_free;
+       }
+
+       /*
+        * mmap() will fail with SIGBUS if trying to map beyond the end of
+        * the file.
+        */
+       if (S_ISREG(statbuf.st_mode) && base + (off_t)len > statbuf.st_size)
+       {
+               fprintf(stderr, "mmap: Can't map beyond end of file %s\n",
+                       devmem);
+               goto err_free;
+       }
+
 #ifdef _SC_PAGESIZE
        mmoffset = base % sysconf(_SC_PAGESIZE);
 #else
@@ -199,19 +230,17 @@
        {
                fprintf(stderr, "%s: ", devmem);
                perror("lseek");
-               free(p);
-               return NULL;
+               goto err_free;
        }
 
-       if (myread(fd, p, len, devmem) == -1)
-       {
-               free(p);
-               return NULL;
-       }
+       if (myread(fd, p, len, devmem) == 0)
+               goto out;
+
+err_free:
+       free(p);
+       p = NULL;
 
-#ifdef USE_MMAP
 out:
-#endif
        if (close(fd) == -1)
                perror(devmem);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dmidecode-3.0/util.h new/dmidecode-3.1/util.h
--- old/dmidecode-3.0/util.h    2015-09-03 08:03:19.000000000 +0200
+++ new/dmidecode-3.1/util.h    2017-05-23 15:34:14.000000000 +0200
@@ -1,7 +1,7 @@
 /*
  * This file is part of the dmidecode project.
  *
- *   Copyright (C) 2003-2015 Jean Delvare <jdelv...@suse.de>
+ *   Copyright (C) 2003-2017 Jean Delvare <jdelv...@suse.de>
  *
  *   This program is free software; you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License as published by
@@ -25,7 +25,7 @@
 #define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
 
 int checksum(const u8 *buf, size_t len);
-void *read_file(size_t len, const char *filename);
+void *read_file(off_t base, size_t *len, const char *filename);
 void *mem_chunk(off_t base, size_t len, const char *devmem);
 int write_dump(size_t base, size_t len, const void *data, const char 
*dumpfile, int add);
 u64 u64_range(u64 start, u64 end);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dmidecode-3.0/version.h new/dmidecode-3.1/version.h
--- old/dmidecode-3.0/version.h 2015-09-03 08:03:19.000000000 +0200
+++ new/dmidecode-3.1/version.h 2017-05-23 15:34:14.000000000 +0200
@@ -1 +1 @@
-#define VERSION "3.0"
+#define VERSION "3.1"


Reply via email to