diff --git a/.gitignore b/.gitignore
index eb860fb..7e3bba2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
 /dmidecode-2.11.tar.bz2
 /dmidecode-2.12.tar.bz2
+/dmidecode-3.0.tar.xz
diff --git a/0001-Add-no-sysfs-option-description-to-h-output.patch b/0001-Add-no-sysfs-option-description-to-h-output.patch
new file mode 100644
index 0000000..3b3167c
--- /dev/null
+++ b/0001-Add-no-sysfs-option-description-to-h-output.patch
@@ -0,0 +1,39 @@
+From 33b5aafc6ee6b5de9f2526fb1cf4b14d1e16e4f0 Mon Sep 17 00:00:00 2001
+From: Roy Franz <roy.franz@linaro.org>
+Date: Thu, 1 Oct 2015 08:41:43 +0200
+Subject: [PATCH 1/9] Add "--no-sysfs" option description to -h output
+
+A description of --no-sysfs was not added to the output of "-h" when
+the feature was added, so add it now.
+---
+ CHANGELOG | 4 ++++
+ dmiopt.c  | 1 +
+ 2 files changed, 5 insertions(+)
+
+diff --git a/CHANGELOG b/CHANGELOG
+index f0a51a4..42d815c 100644
+--- a/CHANGELOG
++++ b/CHANGELOG
+@@ -1,3 +1,7 @@
++2015-10-01  Roy Franz  <roy.franz@linaro.org>
++
++	* dmiopt.c: Add "--no-sysfs" option description to -h output.
++
+ 2015-09-03  Jean Delvare  <jdelvare@suse.de>
+ 
+ 	* version.h: Set version to 3.0.
+diff --git a/dmiopt.c b/dmiopt.c
+index 0d142d2..de607f4 100644
+--- a/dmiopt.c
++++ b/dmiopt.c
+@@ -314,6 +314,7 @@ void print_help(void)
+ 		" -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"
+ 		" -V, --version          Display the version and exit\n";
+ 
+ 	printf("%s", help);
+-- 
+2.5.0
+
diff --git a/0002-Avoid-SIGBUS-on-mmap-failure.patch b/0002-Avoid-SIGBUS-on-mmap-failure.patch
new file mode 100644
index 0000000..cd9a957
--- /dev/null
+++ b/0002-Avoid-SIGBUS-on-mmap-failure.patch
@@ -0,0 +1,74 @@
+From c081fa410e7c466df4b3b257e7b974b71fb7f250 Mon Sep 17 00:00:00 2001
+From: Jean Delvare <jdelvare@suse.de>
+Date: Wed, 14 Oct 2015 14:37:04 +0200
+Subject: [PATCH 2/9] Avoid SIGBUS on mmap failure
+
+mmap will fail with SIGBUS if trying to map a non-existent portion of
+a file. While this should never happen with /dev/mem, it can happen if
+passing a regular file with option -d. While people should no longer
+do that, failure gracefully seems better than crashing. So check for
+the file size before calling mmap.
+
+This closes bug #46066:
+http://savannah.nongnu.org/bugs/?46066
+---
+ CHANGELOG |  6 ++++++
+ util.c    | 21 +++++++++++++++++++++
+ 2 files changed, 27 insertions(+)
+
+diff --git a/CHANGELOG b/CHANGELOG
+index 42d815c..aa1c28f 100644
+--- a/CHANGELOG
++++ b/CHANGELOG
+@@ -1,3 +1,9 @@
++2015-10-14  Jean Delvare  <jdelvare@suse.de>
++
++	* util.c: Avoid SIGBUS on mmap failure.
++	  This fixes Savannah bug #46066:
++	  https://savannah.nongnu.org/bugs/?46066
++
+ 2015-10-01  Roy Franz  <roy.franz@linaro.org>
+ 
+ 	* dmiopt.c: Add "--no-sysfs" option description to -h output.
+diff --git a/util.c b/util.c
+index 8cafe5c..5795d02 100644
+--- a/util.c
++++ b/util.c
+@@ -152,6 +152,7 @@ void *mem_chunk(off_t base, size_t len, const char *devmem)
+ 	void *p;
+ 	int fd;
+ #ifdef USE_MMAP
++	struct stat statbuf;
+ 	off_t mmoffset;
+ 	void *mmp;
+ #endif
+@@ -169,6 +170,26 @@ void *mem_chunk(off_t base, size_t len, const char *devmem)
+ 	}
+ 
+ #ifdef USE_MMAP
++	if (fstat(fd, &statbuf) == -1)
++	{
++		fprintf(stderr, "%s: ", devmem);
++		perror("stat");
++		free(p);
++		return NULL;
++	}
++
++	/*
++	 * 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);
++		free(p);
++		return NULL;
++	}
++
+ #ifdef _SC_PAGESIZE
+ 	mmoffset = base % sysconf(_SC_PAGESIZE);
+ #else
+-- 
+2.5.0
+
diff --git a/0003-Fix-error-paths-in-mem_chunk.patch b/0003-Fix-error-paths-in-mem_chunk.patch
new file mode 100644
index 0000000..e57f46d
--- /dev/null
+++ b/0003-Fix-error-paths-in-mem_chunk.patch
@@ -0,0 +1,88 @@
+From 458f73d58c24a7addce82bf1e8bfb8c2554ca458 Mon Sep 17 00:00:00 2001
+From: Jean Delvare <jdelvare@suse.de>
+Date: Wed, 14 Oct 2015 14:37:09 +0200
+Subject: [PATCH 3/9] Fix error paths in mem_chunk
+
+Use a common error path in function mem_chunk, to make sure it does
+not leak memory and does not leave an opened file descriptor behind,
+without duplicating the cleaning code.
+---
+ CHANGELOG |  1 +
+ util.c    | 24 ++++++++++--------------
+ 2 files changed, 11 insertions(+), 14 deletions(-)
+
+diff --git a/CHANGELOG b/CHANGELOG
+index aa1c28f..c940c9f 100644
+--- a/CHANGELOG
++++ b/CHANGELOG
+@@ -3,6 +3,7 @@
+ 	* 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.franz@linaro.org>
+ 
+diff --git a/util.c b/util.c
+index 5795d02..f97ac0d 100644
+--- a/util.c
++++ b/util.c
+@@ -166,7 +166,7 @@ void *mem_chunk(off_t base, size_t len, const char *devmem)
+ 	if ((p = malloc(len)) == NULL)
+ 	{
+ 		perror("malloc");
+-		return NULL;
++		goto out;
+ 	}
+ 
+ #ifdef USE_MMAP
+@@ -174,8 +174,7 @@ void *mem_chunk(off_t base, size_t len, const char *devmem)
+ 	{
+ 		fprintf(stderr, "%s: ", devmem);
+ 		perror("stat");
+-		free(p);
+-		return NULL;
++		goto err_free;
+ 	}
+ 
+ 	/*
+@@ -186,8 +185,7 @@ void *mem_chunk(off_t base, size_t len, const char *devmem)
+ 	{
+ 		fprintf(stderr, "mmap: Can't map beyond end of file %s\n",
+ 			devmem);
+-		free(p);
+-		return NULL;
++		goto err_free;
+ 	}
+ 
+ #ifdef _SC_PAGESIZE
+@@ -220,19 +218,17 @@ try_read:
+ 	{
+ 		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);
+ 
+-- 
+2.5.0
+
diff --git a/0004-dmidecode-Handle-OEM-specific-types-in-group-associa.patch b/0004-dmidecode-Handle-OEM-specific-types-in-group-associa.patch
new file mode 100644
index 0000000..945d53f
--- /dev/null
+++ b/0004-dmidecode-Handle-OEM-specific-types-in-group-associa.patch
@@ -0,0 +1,40 @@
+From 3acecbbab8ecaf3e3b324a2286e51cf9d7950ad5 Mon Sep 17 00:00:00 2001
+From: Jean Delvare <jdelvare@suse.de>
+Date: Tue, 20 Oct 2015 08:47:15 +0200
+Subject: [PATCH 4/9] dmidecode: Handle OEM-specific types in group
+ associations
+
+---
+ CHANGELOG   | 5 +++++
+ dmidecode.c | 2 ++
+ 2 files changed, 7 insertions(+)
+
+diff --git a/CHANGELOG b/CHANGELOG
+index c940c9f..2aa1082 100644
+--- a/CHANGELOG
++++ b/CHANGELOG
+@@ -1,3 +1,8 @@
++2015-10-20  Jean Delvare  <jdelvare@suse.de>
++
++	* dmidecode.c: Handle OEM-specific types in group associations
++	  (DMI type 14).
++
+ 2015-10-14  Jean Delvare  <jdelvare@suse.de>
+ 
+ 	* util.c: Avoid SIGBUS on mmap failure.
+diff --git a/dmidecode.c b/dmidecode.c
+index f41c85b..ce0511b 100644
+--- a/dmidecode.c
++++ b/dmidecode.c
+@@ -172,6 +172,8 @@ static const char *dmi_smbios_structure_type(u8 code)
+ 		"Management Controller Host Interface", /* 42 */
+ 	};
+ 
++	if (code >= 128)
++		return "OEM-specific";
+ 	if (code <= 42)
+ 		return type[code];
+ 	return out_of_spec;
+-- 
+2.5.0
+
diff --git a/0005-Fix-No-SMBIOS-nor-DMI-entry-point-found-on-SMBIOS3.patch b/0005-Fix-No-SMBIOS-nor-DMI-entry-point-found-on-SMBIOS3.patch
new file mode 100644
index 0000000..d6ed349
--- /dev/null
+++ b/0005-Fix-No-SMBIOS-nor-DMI-entry-point-found-on-SMBIOS3.patch
@@ -0,0 +1,63 @@
+From bf7bad24ce141dab5b5acc3ffb98ce5fe4a8e0f9 Mon Sep 17 00:00:00 2001
+From: Xie XiuQi <xiexiuqi@huawei.com>
+Date: Wed, 21 Oct 2015 15:12:50 +0200
+Subject: [PATCH 5/9] Fix 'No SMBIOS nor DMI entry point found' on SMBIOS3
+
+address_from_efi may return a SMBIOS or SMBIOS3 format entry
+point, so add this condition.
+---
+ AUTHORS     |  1 +
+ CHANGELOG   |  4 ++++
+ dmidecode.c | 12 ++++++++++--
+ 3 files changed, 15 insertions(+), 2 deletions(-)
+
+diff --git a/AUTHORS b/AUTHORS
+index d4badfa..ccf7fbb 100644
+--- a/AUTHORS
++++ b/AUTHORS
+@@ -19,6 +19,7 @@ Jarod Wilson <jarod@redhat.com>
+ Anton Arapov <anton@redhat.com>
+ Roy Franz <roy.franz@linaro.org>
+ Tyler Bell <tyler.bell@hp.com>
++Xie XiuQi <xiexiuqi@huawei.com>
+ 
+ MANY THANKS TO (IN CHRONOLOGICAL ORDER)
+ Werner Heuser
+diff --git a/CHANGELOG b/CHANGELOG
+index 2aa1082..be2092a 100644
+--- a/CHANGELOG
++++ b/CHANGELOG
+@@ -1,3 +1,7 @@
++2015-10-21  Xie XiuQi  <xiexiuqi@huawei.com>
++
++	* dmidecode.c: Handle SMBIOS 3.0 entry points on EFI systems.
++
+ 2015-10-20  Jean Delvare  <jdelvare@suse.de>
+ 
+ 	* dmidecode.c: Handle OEM-specific types in group associations
+diff --git a/dmidecode.c b/dmidecode.c
+index ce0511b..cfcade4 100644
+--- a/dmidecode.c
++++ b/dmidecode.c
+@@ -4866,8 +4866,16 @@ int main(int argc, char * const argv[])
+ 		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:
+-- 
+2.5.0
+
diff --git a/0006-dmidecode-Introduce-SYS_FIRMWARE_DIR.patch b/0006-dmidecode-Introduce-SYS_FIRMWARE_DIR.patch
new file mode 100644
index 0000000..2603de3
--- /dev/null
+++ b/0006-dmidecode-Introduce-SYS_FIRMWARE_DIR.patch
@@ -0,0 +1,31 @@
+From 2330b708a6d57fd2b8b7e353dd64d037f980a042 Mon Sep 17 00:00:00 2001
+From: Jean Delvare <jdelvare@suse.de>
+Date: Mon, 2 Nov 2015 09:45:13 +0100
+Subject: [PATCH 6/9] dmidecode: Introduce SYS_FIRMWARE_DIR
+
+Have SYS_FIRMWARE_DIR point to the sysfs directory where our files
+live, and use it in the definition of their paths. This makes it
+easier to temporarily point somewhere else for debugging.
+---
+ dmidecode.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/dmidecode.c b/dmidecode.c
+index cfcade4..183ced4 100644
+--- a/dmidecode.c
++++ b/dmidecode.c
+@@ -74,8 +74,9 @@ static const char *bad_index = "<BAD INDEX>";
+ #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
+-- 
+2.5.0
+
diff --git a/0007-Let-read_file-return-the-actual-data-size.patch b/0007-Let-read_file-return-the-actual-data-size.patch
new file mode 100644
index 0000000..031dd3d
--- /dev/null
+++ b/0007-Let-read_file-return-the-actual-data-size.patch
@@ -0,0 +1,112 @@
+From de9a74e1c60210bee229fcf55b1678a99d1b44dd Mon Sep 17 00:00:00 2001
+From: Jean Delvare <jdelvare@suse.de>
+Date: Mon, 2 Nov 2015 09:45:26 +0100
+Subject: [PATCH 7/9] Let read_file return the actual data size
+
+Let read_file return the actual data size to the caller. This gives
+the caller the possibility to check that the data size is as expected
+and large enough for the purpose, and report to the user if not.
+---
+ CHANGELOG   |  5 +++++
+ dmidecode.c |  4 +++-
+ util.c      | 11 +++++++----
+ util.h      |  2 +-
+ 4 files changed, 16 insertions(+), 6 deletions(-)
+
+diff --git a/CHANGELOG b/CHANGELOG
+index be2092a..1e5437a 100644
+--- a/CHANGELOG
++++ b/CHANGELOG
+@@ -1,3 +1,8 @@
++2015-11-02  Jean Delvare  <jdelvare@suse.de>
++
++	* dmidecode.c, util.c, util.h: Let read_file return the actual data
++	  size.
++
+ 2015-10-21  Xie XiuQi  <xiexiuqi@huawei.com>
+ 
+ 	* dmidecode.c: Handle SMBIOS 3.0 entry points on EFI systems.
+diff --git a/dmidecode.c b/dmidecode.c
+index 183ced4..a43cfd1 100644
+--- a/dmidecode.c
++++ b/dmidecode.c
+@@ -4751,6 +4751,7 @@ int main(int argc, char * const argv[])
+ 	int ret = 0;                /* Returned value */
+ 	int found = 0;
+ 	off_t fp;
++	size_t size;
+ 	int efi;
+ 	u8 *buf;
+ 
+@@ -4820,8 +4821,9 @@ int main(int argc, char * const argv[])
+ 	 * 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(&size, SYS_ENTRY_FILE)) != NULL)
+ 	{
+ 		if (!(opt.flags & FLAG_QUIET))
+ 			printf("Getting SMBIOS data from sysfs.\n");
+diff --git a/util.c b/util.c
+index f97ac0d..52ed413 100644
+--- a/util.c
++++ b/util.c
+@@ -94,10 +94,11 @@ int checksum(const u8 *buf, size_t len)
+  * 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(size_t *max_len, const char *filename)
+ {
+ 	int fd;
+ 	size_t r2 = 0;
+@@ -115,7 +116,7 @@ void *read_file(size_t max_len, const char *filename)
+ 		return(NULL);
+ 	}
+ 
+-	if ((p = malloc(max_len)) == NULL)
++	if ((p = malloc(*max_len)) == NULL)
+ 	{
+ 		perror("malloc");
+ 		return NULL;
+@@ -123,7 +124,7 @@ void *read_file(size_t max_len, const char *filename)
+ 
+ 	do
+ 	{
+-		r = read(fd, p + r2, max_len - r2);
++		r = read(fd, p + r2, *max_len - r2);
+ 		if (r == -1)
+ 		{
+ 			if (errno != EINTR)
+@@ -140,6 +141,8 @@ void *read_file(size_t max_len, const char *filename)
+ 	while (r != 0);
+ 
+ 	close(fd);
++	*max_len = r2;
++
+ 	return p;
+ }
+ 
+diff --git a/util.h b/util.h
+index 9d409cd..b8748f1 100644
+--- a/util.h
++++ b/util.h
+@@ -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(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);
+-- 
+2.5.0
+
diff --git a/0008-dmidecode-Use-read_file-to-read-the-DMI-table-from-s.patch b/0008-dmidecode-Use-read_file-to-read-the-DMI-table-from-s.patch
new file mode 100644
index 0000000..97ca998
--- /dev/null
+++ b/0008-dmidecode-Use-read_file-to-read-the-DMI-table-from-s.patch
@@ -0,0 +1,86 @@
+From 364055211b1956539c6a6268e111e244e1292c8c Mon Sep 17 00:00:00 2001
+From: Jean Delvare <jdelvare@suse.de>
+Date: Mon, 2 Nov 2015 09:45:31 +0100
+Subject: [PATCH 8/9] dmidecode: Use read_file() to read the DMI table from
+ sysfs
+
+We shouldn't use mem_chunk() to read the DMI table from sysfs. This
+will fail for SMBIOS v3 implementations which specify a maximum length
+for the table rather than its exact length. The kernel will trim the
+table to the actual length, so the DMI file will be shorter than the
+length announced in entry point.
+
+read_file() fits the bill in this case, as it deals with end of file
+nicely.
+
+This also helps with corrupted DMI tables, as the kernel will not
+export the part of the table that it wasn't able to parse, effectively
+trimming it.
+
+This fixes bug #46176:
+https://savannah.nongnu.org/bugs/?46176
+Unexpected end of file error
+---
+ CHANGELOG   |  3 +++
+ dmidecode.c | 29 +++++++++++++++++++++--------
+ 2 files changed, 24 insertions(+), 8 deletions(-)
+
+diff --git a/CHANGELOG b/CHANGELOG
+index 1e5437a..fcfc244 100644
+--- a/CHANGELOG
++++ b/CHANGELOG
+@@ -2,6 +2,9 @@
+ 
+ 	* 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
+ 
+ 2015-10-21  Xie XiuQi  <xiexiuqi@huawei.com>
+ 
+diff --git a/dmidecode.c b/dmidecode.c
+index a43cfd1..16d1823 100644
+--- a/dmidecode.c
++++ b/dmidecode.c
+@@ -4524,16 +4524,29 @@ static void dmi_table(off_t base, u32 len, u16 num, u16 ver, const char *devmem,
+ 		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;
++	{
++		/*
++		 * When reading from sysfs, 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(&size, devmem);
++		if (!(opt.flags & FLAG_QUIET) && num && size != (size_t)len)
++		{
++			printf("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."
+ #ifndef USE_MMAP
+-- 
+2.5.0
+
diff --git a/0009-dmidecode-Check-sysfs-entry-point-length.patch b/0009-dmidecode-Check-sysfs-entry-point-length.patch
new file mode 100644
index 0000000..05340ab
--- /dev/null
+++ b/0009-dmidecode-Check-sysfs-entry-point-length.patch
@@ -0,0 +1,52 @@
+From e5c73239404931d4d1b73eb595c3802fbce74c61 Mon Sep 17 00:00:00 2001
+From: Jean Delvare <jdelvare@suse.de>
+Date: Mon, 2 Nov 2015 09:45:36 +0100
+Subject: [PATCH 9/9] dmidecode: Check sysfs entry point length
+
+Before passing the sysfs entry point data over for decoding, check
+that its length meets the expectations.
+---
+ CHANGELOG   | 1 +
+ dmidecode.c | 6 +++---
+ 2 files changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/CHANGELOG b/CHANGELOG
+index fcfc244..ba61cab 100644
+--- a/CHANGELOG
++++ b/CHANGELOG
+@@ -5,6 +5,7 @@
+ 	* 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  <xiexiuqi@huawei.com>
+ 
+diff --git a/dmidecode.c b/dmidecode.c
+index 16d1823..b47c469 100644
+--- a/dmidecode.c
++++ b/dmidecode.c
+@@ -4840,17 +4840,17 @@ int main(int argc, char * const argv[])
+ 	{
+ 		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++;
+-- 
+2.5.0
+
diff --git a/dmidecode-2.12-smbios_fix.patch b/dmidecode-2.12-smbios_fix.patch
deleted file mode 100644
index f39205d..0000000
--- a/dmidecode-2.12-smbios_fix.patch
+++ /dev/null
@@ -1,86 +0,0 @@
-diff -up dmidecode-2.12/CHANGELOG.smbios_fix dmidecode-2.12/CHANGELOG
---- dmidecode-2.12/CHANGELOG.smbios_fix	2013-05-09 09:44:35.668592078 +0200
-+++ dmidecode-2.12/CHANGELOG	2013-05-09 09:44:44.742610559 +0200
-@@ -1,3 +1,10 @@
-+2013-04-24  Jean Delvare  <khali@linux-fr.org>
-+
-+	* dmidecode.c: Strip trailig zeroes from memory voltage values
-+	  (DMI type 17).
-+	* dmidecode.c: Fix support for new processor upgrade types (DMI
-+	  type 4) and new memory device type (DMI type 17.)
-+
- 2013-04-17  Anton Arapov  <anton@redhat.com>
- 
- 	Update to support SMBIOS specification version 2.8.0.
-diff -up dmidecode-2.12/dmidecode.c.smbios_fix dmidecode-2.12/dmidecode.c
---- dmidecode-2.12/dmidecode.c.smbios_fix	2013-05-09 09:44:26.404573273 +0200
-+++ dmidecode-2.12/dmidecode.c	2013-05-09 09:44:44.745610565 +0200
-@@ -69,7 +69,7 @@
- #define out_of_spec "<OUT OF SPEC>"
- static const char *bad_index = "<BAD INDEX>";
- 
--#define SUPPORTED_SMBIOS_VER 0x0207
-+#define SUPPORTED_SMBIOS_VER 0x0208
- 
- /*
-  * Type-independant Stuff
-@@ -712,7 +712,6 @@ static const char *dmi_processor_family(
- 		{ 0x3D, "Opteron 6200" },
- 		{ 0x3E, "Opteron 4200" },
- 		{ 0x3F, "FX" },
--
- 		{ 0x40, "MIPS" },
- 		{ 0x41, "MIPS R4000" },
- 		{ 0x42, "MIPS R4200" },
-@@ -729,7 +728,6 @@ static const char *dmi_processor_family(
- 		{ 0x4D, "Opteron 6300" },
- 		{ 0x4E, "Opteron 3300" },
- 		{ 0x4F, "FirePro" },
--
- 		{ 0x50, "SPARC" },
- 		{ 0x51, "SuperSPARC" },
- 		{ 0x52, "MicroSPARC II" },
-@@ -1176,7 +1174,7 @@ static const char *dmi_processor_upgrade
- 		"Socket LGA1356-3" /* 0x2C */
- 	};
- 
--	if (code >= 0x01 && code <= 0x2A)
-+	if (code >= 0x01 && code <= 0x2C)
- 		return upgrade[code - 0x01];
- 	return out_of_spec;
- }
-@@ -2236,7 +2234,7 @@ static void dmi_memory_voltage_value(u16
- 	if (code == 0)
- 		printf(" Unknown");
- 	else
--		printf(" %.3f V", (float)(i16)code / 1000);
-+		printf(code % 100 ? " %g V" : " %.1f V", (float)code / 1000);
- }
- 
- static const char *dmi_memory_device_form_factor(u8 code)
-@@ -2338,7 +2336,7 @@ static void dmi_memory_device_type_detai
- 	{
- 		int i;
- 
--		for (i = 1; i <= 14; i++)
-+		for (i = 1; i <= 15; i++)
- 			if (code & (1 << i))
- 				printf(" %s", detail[i - 1]);
- 	}
-@@ -3657,13 +3655,13 @@ static void dmi_decode(const struct dmi_
- 			dmi_memory_device_speed(WORD(data + 0x20));
- 			printf("\n");
- 			if (h->length < 0x28) break;
--			printf("\tMinimum voltage: ");
-+			printf("\tMinimum Voltage: ");
- 			dmi_memory_voltage_value(WORD(data + 0x22));
- 			printf("\n");
--			printf("\tMaximum voltage: ");
-+			printf("\tMaximum Voltage: ");
- 			dmi_memory_voltage_value(WORD(data + 0x24));
- 			printf("\n");
--			printf("\tConfigured voltage: ");
-+			printf("\tConfigured Voltage: ");
- 			dmi_memory_voltage_value(WORD(data + 0x26));
- 			printf("\n");
- 			break;
diff --git a/dmidecode.spec b/dmidecode.spec
index 26dc862..c4532e3 100644
--- a/dmidecode.spec
+++ b/dmidecode.spec
@@ -1,13 +1,21 @@
 Summary:        Tool to analyse BIOS DMI data
 Name:           dmidecode
-Version:        2.12
-Release:        9%{?dist}
+Version:        3.0
+Release:        1%{?dist}
 Epoch:          1
 Group:          System Environment/Base
 License:        GPLv2+
-Source0:        %{name}-%{version}.tar.bz2
+Source0:        %{name}-%{version}.tar.xz
 URL:            http://www.nongnu.org/dmidecode/
-Patch0:         dmidecode-2.12-smbios_fix.patch
+Patch1:         0001-Add-no-sysfs-option-description-to-h-output.patch
+Patch2:         0002-Avoid-SIGBUS-on-mmap-failure.patch
+Patch3:         0003-Fix-error-paths-in-mem_chunk.patch
+Patch4:         0004-dmidecode-Handle-OEM-specific-types-in-group-associa.patch
+Patch5:         0005-Fix-No-SMBIOS-nor-DMI-entry-point-found-on-SMBIOS3.patch
+Patch6:         0006-dmidecode-Introduce-SYS_FIRMWARE_DIR.patch
+Patch7:         0007-Let-read_file-return-the-actual-data-size.patch
+Patch8:         0008-dmidecode-Use-read_file-to-read-the-DMI-table-from-s.patch
+Patch9:         0009-dmidecode-Check-sysfs-entry-point-length.patch
 BuildRequires:  automake autoconf
 ExclusiveArch:  %{ix86} x86_64 ia64 aarch64
 
@@ -24,7 +32,15 @@ I/O ports (e.g. serial, parallel, USB).
 
 %prep
 %setup -q
-%patch0 -p1 -b .smbios_fix
+%patch1 -p1 -b .no_sysfs
+%patch2 -p1 -b .avoid_sigbus
+%patch3 -p1 -b .fix_errorpaths
+%patch4 -p1 -b .oem_specific
+%patch5 -p1 -b .entry_point
+%patch6 -p1 -b .sys_firmware_dir
+%patch7 -p1 -b .return_actual
+%patch8 -p1 -b .read_file
+%patch9 -p1 -b .sysfs_entry_check
 
 %build
 make %{?_smp_mflags} CFLAGS="$RPM_OPT_FLAGS"
@@ -45,6 +61,9 @@ make %{?_smp_mflags} DESTDIR=%{buildroot} prefix=%{_prefix} install-bin install-
 %{_mandir}/man8/*
 
 %changelog
+* Thu Jan 21 2016 Anton Arapov <arapov@gmail.com> - 1:3.0-1
+- dmidecode v3 patched up to commit e5c73239404
+
 * Wed Jun 17 2015 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1:2.12-9
 - Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild
 
diff --git a/sources b/sources
index 94ff13b..47771a5 100644
--- a/sources
+++ b/sources
@@ -1 +1 @@
-a406f3cbb27736491698697beeddb781  dmidecode-2.12.tar.bz2
+281ee572d45c78eca73a14834c495ffd  dmidecode-3.0.tar.xz