Merge Mainline
This commit is contained in:
@@ -35,7 +35,7 @@ define autoreconf
|
||||
$(patsubst %,rm -f %;,$(2)) \
|
||||
$(foreach p,$(3), \
|
||||
if [ -f $(p)/configure.ac ] || [ -f $(p)/configure.in ]; then \
|
||||
[ -d $(p)/autom4te.cache ] && rm -rf autom4te.cache; \
|
||||
[ -d $(p)/autom4te.cache ] && rm -rf $(p)/autom4te.cache; \
|
||||
[ -e $(p)/config.rpath ] || \
|
||||
ln -s $(SCRIPT_DIR)/config.rpath $(p)/config.rpath; \
|
||||
touch NEWS AUTHORS COPYING ABOUT-NLS ChangeLog; \
|
||||
|
||||
@@ -6,7 +6,6 @@ include $(TOPDIR)/rules.mk
|
||||
include $(INCLUDE_DIR)/kernel.mk
|
||||
|
||||
PKG_NAME:=grub
|
||||
PKG_CPE_ID:=cpe:/a:gnu:grub2
|
||||
PKG_VERSION:=2.06
|
||||
PKG_RELEASE:=$(AUTORELEASE)
|
||||
|
||||
@@ -14,6 +13,9 @@ PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
|
||||
PKG_SOURCE_URL:=@GNU/grub
|
||||
PKG_HASH:=b79ea44af91b93d17cd3fe80bdae6ed43770678a9a5ae192ccea803ebb657ee1
|
||||
|
||||
PKG_LICENSE:=GPL-3.0-or-later
|
||||
PKG_CPE_ID:=cpe:/a:gnu:grub2
|
||||
|
||||
HOST_BUILD_PARALLEL:=1
|
||||
PKG_BUILD_DEPENDS:=grub2/host
|
||||
|
||||
|
||||
38
package/devel/gdb/patches/010-aarch64-headers.patch
Normal file
38
package/devel/gdb/patches/010-aarch64-headers.patch
Normal file
@@ -0,0 +1,38 @@
|
||||
The signal definitions of musl and gdb collide
|
||||
|
||||
The kernel defines "struct sigcontext" in asm/sigcontext.h and musl libc
|
||||
defines it in signal.h which collides.
|
||||
Kernel 4.14 misses the definitions of struct user_sve_header so we still
|
||||
have to use the aarch64-sve-linux-sigcontext.h header file which also
|
||||
provides that and make sure aarch64-sve-linux-sigcontext.h does not
|
||||
provide the same headers as the kernel or musl.
|
||||
|
||||
--- a/gdb/nat/aarch64-sve-linux-ptrace.h
|
||||
+++ b/gdb/nat/aarch64-sve-linux-ptrace.h
|
||||
@@ -31,7 +31,7 @@
|
||||
#include <sys/ptrace.h>
|
||||
#include <asm/ptrace.h>
|
||||
|
||||
-#ifndef SVE_SIG_ZREGS_SIZE
|
||||
+#ifndef SVE_PT_REGS_SVE
|
||||
#include "aarch64-sve-linux-sigcontext.h"
|
||||
#endif
|
||||
|
||||
--- a/gdb/nat/aarch64-sve-linux-sigcontext.h
|
||||
+++ b/gdb/nat/aarch64-sve-linux-sigcontext.h
|
||||
@@ -19,6 +19,7 @@
|
||||
#ifndef NAT_AARCH64_SVE_LINUX_SIGCONTEXT_H
|
||||
#define NAT_AARCH64_SVE_LINUX_SIGCONTEXT_H
|
||||
|
||||
+#ifndef SVE_MAGIC
|
||||
#define SVE_MAGIC 0x53564501
|
||||
|
||||
struct sve_context {
|
||||
@@ -128,6 +129,7 @@ struct sve_context {
|
||||
(SVE_SIG_FFR_OFFSET(vq) + SVE_SIG_FFR_SIZE(vq) - SVE_SIG_REGS_OFFSET)
|
||||
|
||||
#define SVE_SIG_CONTEXT_SIZE(vq) (SVE_SIG_REGS_OFFSET + SVE_SIG_REGS_SIZE(vq))
|
||||
+#endif
|
||||
|
||||
/* SVE/FP/SIMD state (NT_ARM_SVE) */
|
||||
|
||||
@@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=argp-standalone
|
||||
PKG_VERSION:=1.3
|
||||
PKG_RELEASE:=1
|
||||
PKG_RELEASE:=2
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=http://www.lysator.liu.se/~nisse/misc/
|
||||
@@ -20,6 +20,7 @@ PKG_LICENSE:=LGPL-2.1
|
||||
PKG_LICENSE:=Makefile.am
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
include $(INCLUDE_DIR)/host-build.mk
|
||||
|
||||
define Package/argp-standalone
|
||||
SECTION:=libs
|
||||
@@ -47,4 +48,14 @@ define Build/InstallDev
|
||||
$(1)/usr/lib/
|
||||
endef
|
||||
|
||||
define Host/Install
|
||||
$(INSTALL_DIR) $(1)/include
|
||||
$(CP) $(HOST_BUILD_DIR)/argp.h \
|
||||
$(1)/include/
|
||||
$(INSTALL_DIR) $(1)/lib
|
||||
$(CP) $(HOST_BUILD_DIR)/libargp.a \
|
||||
$(1)/lib/
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,argp-standalone))
|
||||
$(eval $(call HostBuild))
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
PKG_NAME:=toolchain
|
||||
PKG_RELEASE:=3
|
||||
PKG_RELEASE:=4
|
||||
|
||||
PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
|
||||
PKG_LICENSE:=GPL-3.0-with-GCC-exception
|
||||
@@ -490,6 +490,7 @@ ifeq ($(CONFIG_EXTERNAL_TOOLCHAIN),)
|
||||
define Package/libstdcpp/install
|
||||
$(INSTALL_DIR) $(1)/usr/lib
|
||||
$(CP) $(TOOLCHAIN_DIR)/lib/libstdc++.so.* $(1)/usr/lib/
|
||||
rm -rf $(1)/usr/lib/*-gdb.py
|
||||
endef
|
||||
|
||||
define Package/libasan/install
|
||||
|
||||
@@ -8,12 +8,13 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=zlib
|
||||
PKG_VERSION:=1.2.11
|
||||
PKG_RELEASE:=4
|
||||
PKG_VERSION:=1.2.12
|
||||
PKG_RELEASE:=$(AUTORELEASE)
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
|
||||
PKG_SOURCE_URL:=@SF/libpng http://www.zlib.net
|
||||
PKG_HASH:=4ff941449631ace0d4d203e3483be9dbc9da454084111f97ea0a2114e19bf066
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL:=https://github.com/madler/zlib
|
||||
PKG_MIRROR_HASH:=a162fc219763635f0c1591ec515d4b08684e4b0bfb4b1c8e65e4eab18d597c27
|
||||
PKG_SOURCE_VERSION:=21767c654d31d2dccdde4330529775c6c5fd5389
|
||||
|
||||
PKG_LICENSE:=Zlib
|
||||
PKG_LICENSE_FILES:=README
|
||||
|
||||
@@ -21,11 +21,9 @@ https://bugs.chromium.org/p/chromium/issues/detail?id=688601
|
||||
4 files changed, 166 insertions(+), 8 deletions(-)
|
||||
create mode 100644 contrib/arm/neon_adler32.c
|
||||
|
||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||
index 0fe939df..8e75f664 100644
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -7,6 +7,7 @@ set(VERSION "1.2.11")
|
||||
@@ -7,6 +7,7 @@ set(VERSION "1.2.12")
|
||||
|
||||
option(ASM686 "Enable building i686 assembly implementation")
|
||||
option(AMD64 "Enable building amd64 assembly implementation")
|
||||
@@ -77,16 +75,16 @@ index 0fe939df..8e75f664 100644
|
||||
set_target_properties(zlib PROPERTIES DEFINE_SYMBOL ZLIB_DLL)
|
||||
set_target_properties(zlib PROPERTIES SOVERSION 1)
|
||||
|
||||
diff --git a/adler32.c b/adler32.c
|
||||
index d0be4380..45ebaa4b 100644
|
||||
--- a/adler32.c
|
||||
+++ b/adler32.c
|
||||
@@ -136,7 +136,12 @@ uLong ZEXPORT adler32(adler, buf, len)
|
||||
@@ -136,7 +136,14 @@ uLong ZEXPORT adler32(adler, buf, len)
|
||||
const Bytef *buf;
|
||||
uInt len;
|
||||
{
|
||||
+#ifdef ARMv8
|
||||
+# pragma message("Using NEON-ized Adler32.")
|
||||
+unsigned long NEON_adler32(unsigned long adler, const unsigned char *buf,
|
||||
+ const unsigned int len);
|
||||
+ return NEON_adler32(adler, buf, len);
|
||||
+#else
|
||||
return adler32_z(adler, buf, len);
|
||||
@@ -94,23 +92,18 @@ index d0be4380..45ebaa4b 100644
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
diff --git a/contrib/README.contrib b/contrib/README.contrib
|
||||
index a411d5c3..3fd1d202 100644
|
||||
--- a/contrib/README.contrib
|
||||
+++ b/contrib/README.contrib
|
||||
@@ -12,6 +12,9 @@ amd64/ by Mikhail Teterin <mi@ALDAN.algebra.com>
|
||||
asm code for AMD64
|
||||
See patch at http://www.freebsd.org/cgi/query-pr.cgi?pr=bin/96393
|
||||
@@ -8,6 +8,9 @@ ada/ by Dmitriy Anisimkov <anisim
|
||||
Support for Ada
|
||||
See http://zlib-ada.sourceforge.net/
|
||||
|
||||
+arm/ by Adenilson Cavalcanti <cavalcantii@chromium.org>
|
||||
+ ARM optimizations (NEON and ARMv8 code).
|
||||
+
|
||||
asm686/ by Brian Raiter <breadbox@muppetlabs.com>
|
||||
asm code for Pentium and PPro/PII, using the AT&T (GNU as) syntax
|
||||
See http://www.muppetlabs.com/~breadbox/software/assembly.html
|
||||
diff --git a/contrib/arm/neon_adler32.c b/contrib/arm/neon_adler32.c
|
||||
new file mode 100644
|
||||
index 00000000..f173a74f
|
||||
blast/ by Mark Adler <madler@alumni.caltech.edu>
|
||||
Decompressor for output of PKWare Data Compression Library (DCL)
|
||||
|
||||
--- /dev/null
|
||||
+++ b/contrib/arm/neon_adler32.c
|
||||
@@ -0,0 +1,137 @@
|
||||
|
||||
@@ -1,343 +0,0 @@
|
||||
From 5c44459c3b28a9bd3283aaceab7c615f8020c531 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Adler <madler@alumni.caltech.edu>
|
||||
Date: Tue, 17 Apr 2018 22:09:22 -0700
|
||||
Subject: [PATCH] Fix a bug that can crash deflate on some input when using
|
||||
Z_FIXED.
|
||||
|
||||
This bug was reported by Danilo Ramos of Eideticom, Inc. It has
|
||||
lain in wait 13 years before being found! The bug was introduced
|
||||
in zlib 1.2.2.2, with the addition of the Z_FIXED option. That
|
||||
option forces the use of fixed Huffman codes. For rare inputs with
|
||||
a large number of distant matches, the pending buffer into which
|
||||
the compressed data is written can overwrite the distance symbol
|
||||
table which it overlays. That results in corrupted output due to
|
||||
invalid distances, and can result in out-of-bound accesses,
|
||||
crashing the application.
|
||||
|
||||
The fix here combines the distance buffer and literal/length
|
||||
buffers into a single symbol buffer. Now three bytes of pending
|
||||
buffer space are opened up for each literal or length/distance
|
||||
pair consumed, instead of the previous two bytes. This assures
|
||||
that the pending buffer cannot overwrite the symbol table, since
|
||||
the maximum fixed code compressed length/distance is 31 bits, and
|
||||
since there are four bytes of pending space for every three bytes
|
||||
of symbol space.
|
||||
---
|
||||
deflate.c | 74 ++++++++++++++++++++++++++++++++++++++++---------------
|
||||
deflate.h | 25 +++++++++----------
|
||||
trees.c | 50 +++++++++++--------------------------
|
||||
3 files changed, 79 insertions(+), 70 deletions(-)
|
||||
|
||||
diff --git a/deflate.c b/deflate.c
|
||||
index 425babc00..19cba873a 100644
|
||||
--- a/deflate.c
|
||||
+++ b/deflate.c
|
||||
@@ -255,11 +255,6 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
|
||||
int wrap = 1;
|
||||
static const char my_version[] = ZLIB_VERSION;
|
||||
|
||||
- ushf *overlay;
|
||||
- /* We overlay pending_buf and d_buf+l_buf. This works since the average
|
||||
- * output size for (length,distance) codes is <= 24 bits.
|
||||
- */
|
||||
-
|
||||
if (version == Z_NULL || version[0] != my_version[0] ||
|
||||
stream_size != sizeof(z_stream)) {
|
||||
return Z_VERSION_ERROR;
|
||||
@@ -329,9 +324,47 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
|
||||
|
||||
s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
|
||||
|
||||
- overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
|
||||
- s->pending_buf = (uchf *) overlay;
|
||||
- s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);
|
||||
+ /* We overlay pending_buf and sym_buf. This works since the average size
|
||||
+ * for length/distance pairs over any compressed block is assured to be 31
|
||||
+ * bits or less.
|
||||
+ *
|
||||
+ * Analysis: The longest fixed codes are a length code of 8 bits plus 5
|
||||
+ * extra bits, for lengths 131 to 257. The longest fixed distance codes are
|
||||
+ * 5 bits plus 13 extra bits, for distances 16385 to 32768. The longest
|
||||
+ * possible fixed-codes length/distance pair is then 31 bits total.
|
||||
+ *
|
||||
+ * sym_buf starts one-fourth of the way into pending_buf. So there are
|
||||
+ * three bytes in sym_buf for every four bytes in pending_buf. Each symbol
|
||||
+ * in sym_buf is three bytes -- two for the distance and one for the
|
||||
+ * literal/length. As each symbol is consumed, the pointer to the next
|
||||
+ * sym_buf value to read moves forward three bytes. From that symbol, up to
|
||||
+ * 31 bits are written to pending_buf. The closest the written pending_buf
|
||||
+ * bits gets to the next sym_buf symbol to read is just before the last
|
||||
+ * code is written. At that time, 31*(n-2) bits have been written, just
|
||||
+ * after 24*(n-2) bits have been consumed from sym_buf. sym_buf starts at
|
||||
+ * 8*n bits into pending_buf. (Note that the symbol buffer fills when n-1
|
||||
+ * symbols are written.) The closest the writing gets to what is unread is
|
||||
+ * then n+14 bits. Here n is lit_bufsize, which is 16384 by default, and
|
||||
+ * can range from 128 to 32768.
|
||||
+ *
|
||||
+ * Therefore, at a minimum, there are 142 bits of space between what is
|
||||
+ * written and what is read in the overlain buffers, so the symbols cannot
|
||||
+ * be overwritten by the compressed data. That space is actually 139 bits,
|
||||
+ * due to the three-bit fixed-code block header.
|
||||
+ *
|
||||
+ * That covers the case where either Z_FIXED is specified, forcing fixed
|
||||
+ * codes, or when the use of fixed codes is chosen, because that choice
|
||||
+ * results in a smaller compressed block than dynamic codes. That latter
|
||||
+ * condition then assures that the above analysis also covers all dynamic
|
||||
+ * blocks. A dynamic-code block will only be chosen to be emitted if it has
|
||||
+ * fewer bits than a fixed-code block would for the same set of symbols.
|
||||
+ * Therefore its average symbol length is assured to be less than 31. So
|
||||
+ * the compressed data for a dynamic block also cannot overwrite the
|
||||
+ * symbols from which it is being constructed.
|
||||
+ */
|
||||
+
|
||||
+ s->pending_buf = (uchf *) ZALLOC(strm, s->lit_bufsize, 4);
|
||||
+ s->pending_buf_size = (ulg)s->lit_bufsize * 4;
|
||||
|
||||
if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
|
||||
s->pending_buf == Z_NULL) {
|
||||
@@ -340,8 +373,12 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
|
||||
deflateEnd (strm);
|
||||
return Z_MEM_ERROR;
|
||||
}
|
||||
- s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
|
||||
- s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
|
||||
+ s->sym_buf = s->pending_buf + s->lit_bufsize;
|
||||
+ s->sym_end = (s->lit_bufsize - 1) * 3;
|
||||
+ /* We avoid equality with lit_bufsize*3 because of wraparound at 64K
|
||||
+ * on 16 bit machines and because stored blocks are restricted to
|
||||
+ * 64K-1 bytes.
|
||||
+ */
|
||||
|
||||
s->level = level;
|
||||
s->strategy = strategy;
|
||||
@@ -552,7 +589,7 @@ int ZEXPORT deflatePrime (strm, bits, value)
|
||||
|
||||
if (deflateStateCheck(strm)) return Z_STREAM_ERROR;
|
||||
s = strm->state;
|
||||
- if ((Bytef *)(s->d_buf) < s->pending_out + ((Buf_size + 7) >> 3))
|
||||
+ if (s->sym_buf < s->pending_out + ((Buf_size + 7) >> 3))
|
||||
return Z_BUF_ERROR;
|
||||
do {
|
||||
put = Buf_size - s->bi_valid;
|
||||
@@ -1113,7 +1150,6 @@ int ZEXPORT deflateCopy (dest, source)
|
||||
#else
|
||||
deflate_state *ds;
|
||||
deflate_state *ss;
|
||||
- ushf *overlay;
|
||||
|
||||
|
||||
if (deflateStateCheck(source) || dest == Z_NULL) {
|
||||
@@ -1133,8 +1169,7 @@ int ZEXPORT deflateCopy (dest, source)
|
||||
ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
|
||||
ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos));
|
||||
ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos));
|
||||
- overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2);
|
||||
- ds->pending_buf = (uchf *) overlay;
|
||||
+ ds->pending_buf = (uchf *) ZALLOC(dest, ds->lit_bufsize, 4);
|
||||
|
||||
if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
|
||||
ds->pending_buf == Z_NULL) {
|
||||
@@ -1148,8 +1183,7 @@ int ZEXPORT deflateCopy (dest, source)
|
||||
zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
|
||||
|
||||
ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
|
||||
- ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush);
|
||||
- ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize;
|
||||
+ ds->sym_buf = ds->pending_buf + ds->lit_bufsize;
|
||||
|
||||
ds->l_desc.dyn_tree = ds->dyn_ltree;
|
||||
ds->d_desc.dyn_tree = ds->dyn_dtree;
|
||||
@@ -1925,7 +1959,7 @@ local block_state deflate_fast(s, flush)
|
||||
FLUSH_BLOCK(s, 1);
|
||||
return finish_done;
|
||||
}
|
||||
- if (s->last_lit)
|
||||
+ if (s->sym_next)
|
||||
FLUSH_BLOCK(s, 0);
|
||||
return block_done;
|
||||
}
|
||||
@@ -2056,7 +2090,7 @@ local block_state deflate_slow(s, flush)
|
||||
FLUSH_BLOCK(s, 1);
|
||||
return finish_done;
|
||||
}
|
||||
- if (s->last_lit)
|
||||
+ if (s->sym_next)
|
||||
FLUSH_BLOCK(s, 0);
|
||||
return block_done;
|
||||
}
|
||||
@@ -2131,7 +2165,7 @@ local block_state deflate_rle(s, flush)
|
||||
FLUSH_BLOCK(s, 1);
|
||||
return finish_done;
|
||||
}
|
||||
- if (s->last_lit)
|
||||
+ if (s->sym_next)
|
||||
FLUSH_BLOCK(s, 0);
|
||||
return block_done;
|
||||
}
|
||||
@@ -2170,7 +2204,7 @@ local block_state deflate_huff(s, flush)
|
||||
FLUSH_BLOCK(s, 1);
|
||||
return finish_done;
|
||||
}
|
||||
- if (s->last_lit)
|
||||
+ if (s->sym_next)
|
||||
FLUSH_BLOCK(s, 0);
|
||||
return block_done;
|
||||
}
|
||||
diff --git a/deflate.h b/deflate.h
|
||||
index 23ecdd312..d4cf1a98b 100644
|
||||
--- a/deflate.h
|
||||
+++ b/deflate.h
|
||||
@@ -217,7 +217,7 @@ typedef struct internal_state {
|
||||
/* Depth of each subtree used as tie breaker for trees of equal frequency
|
||||
*/
|
||||
|
||||
- uchf *l_buf; /* buffer for literals or lengths */
|
||||
+ uchf *sym_buf; /* buffer for distances and literals/lengths */
|
||||
|
||||
uInt lit_bufsize;
|
||||
/* Size of match buffer for literals/lengths. There are 4 reasons for
|
||||
@@ -239,13 +239,8 @@ typedef struct internal_state {
|
||||
* - I can't count above 4
|
||||
*/
|
||||
|
||||
- uInt last_lit; /* running index in l_buf */
|
||||
-
|
||||
- ushf *d_buf;
|
||||
- /* Buffer for distances. To simplify the code, d_buf and l_buf have
|
||||
- * the same number of elements. To use different lengths, an extra flag
|
||||
- * array would be necessary.
|
||||
- */
|
||||
+ uInt sym_next; /* running index in sym_buf */
|
||||
+ uInt sym_end; /* symbol table full when sym_next reaches this */
|
||||
|
||||
ulg opt_len; /* bit length of current block with optimal trees */
|
||||
ulg static_len; /* bit length of current block with static trees */
|
||||
@@ -325,20 +320,22 @@ void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf,
|
||||
|
||||
# define _tr_tally_lit(s, c, flush) \
|
||||
{ uch cc = (c); \
|
||||
- s->d_buf[s->last_lit] = 0; \
|
||||
- s->l_buf[s->last_lit++] = cc; \
|
||||
+ s->sym_buf[s->sym_next++] = 0; \
|
||||
+ s->sym_buf[s->sym_next++] = 0; \
|
||||
+ s->sym_buf[s->sym_next++] = cc; \
|
||||
s->dyn_ltree[cc].Freq++; \
|
||||
- flush = (s->last_lit == s->lit_bufsize-1); \
|
||||
+ flush = (s->sym_next == s->sym_end); \
|
||||
}
|
||||
# define _tr_tally_dist(s, distance, length, flush) \
|
||||
{ uch len = (uch)(length); \
|
||||
ush dist = (ush)(distance); \
|
||||
- s->d_buf[s->last_lit] = dist; \
|
||||
- s->l_buf[s->last_lit++] = len; \
|
||||
+ s->sym_buf[s->sym_next++] = dist; \
|
||||
+ s->sym_buf[s->sym_next++] = dist >> 8; \
|
||||
+ s->sym_buf[s->sym_next++] = len; \
|
||||
dist--; \
|
||||
s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
|
||||
s->dyn_dtree[d_code(dist)].Freq++; \
|
||||
- flush = (s->last_lit == s->lit_bufsize-1); \
|
||||
+ flush = (s->sym_next == s->sym_end); \
|
||||
}
|
||||
#else
|
||||
# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
|
||||
diff --git a/trees.c b/trees.c
|
||||
index 4f4a65011..decaeb7c3 100644
|
||||
--- a/trees.c
|
||||
+++ b/trees.c
|
||||
@@ -416,7 +416,7 @@ local void init_block(s)
|
||||
|
||||
s->dyn_ltree[END_BLOCK].Freq = 1;
|
||||
s->opt_len = s->static_len = 0L;
|
||||
- s->last_lit = s->matches = 0;
|
||||
+ s->sym_next = s->matches = 0;
|
||||
}
|
||||
|
||||
#define SMALLEST 1
|
||||
@@ -948,7 +948,7 @@ void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last)
|
||||
|
||||
Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
|
||||
opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
|
||||
- s->last_lit));
|
||||
+ s->sym_next / 3));
|
||||
|
||||
if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
|
||||
|
||||
@@ -1017,8 +1017,9 @@ int ZLIB_INTERNAL _tr_tally (s, dist, lc)
|
||||
unsigned dist; /* distance of matched string */
|
||||
unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */
|
||||
{
|
||||
- s->d_buf[s->last_lit] = (ush)dist;
|
||||
- s->l_buf[s->last_lit++] = (uch)lc;
|
||||
+ s->sym_buf[s->sym_next++] = dist;
|
||||
+ s->sym_buf[s->sym_next++] = dist >> 8;
|
||||
+ s->sym_buf[s->sym_next++] = lc;
|
||||
if (dist == 0) {
|
||||
/* lc is the unmatched char */
|
||||
s->dyn_ltree[lc].Freq++;
|
||||
@@ -1033,30 +1034,7 @@ int ZLIB_INTERNAL _tr_tally (s, dist, lc)
|
||||
s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++;
|
||||
s->dyn_dtree[d_code(dist)].Freq++;
|
||||
}
|
||||
-
|
||||
-#ifdef TRUNCATE_BLOCK
|
||||
- /* Try to guess if it is profitable to stop the current block here */
|
||||
- if ((s->last_lit & 0x1fff) == 0 && s->level > 2) {
|
||||
- /* Compute an upper bound for the compressed length */
|
||||
- ulg out_length = (ulg)s->last_lit*8L;
|
||||
- ulg in_length = (ulg)((long)s->strstart - s->block_start);
|
||||
- int dcode;
|
||||
- for (dcode = 0; dcode < D_CODES; dcode++) {
|
||||
- out_length += (ulg)s->dyn_dtree[dcode].Freq *
|
||||
- (5L+extra_dbits[dcode]);
|
||||
- }
|
||||
- out_length >>= 3;
|
||||
- Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
|
||||
- s->last_lit, in_length, out_length,
|
||||
- 100L - out_length*100L/in_length));
|
||||
- if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1;
|
||||
- }
|
||||
-#endif
|
||||
- return (s->last_lit == s->lit_bufsize-1);
|
||||
- /* We avoid equality with lit_bufsize because of wraparound at 64K
|
||||
- * on 16 bit machines and because stored blocks are restricted to
|
||||
- * 64K-1 bytes.
|
||||
- */
|
||||
+ return (s->sym_next == s->sym_end);
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
@@ -1069,13 +1047,14 @@ local void compress_block(s, ltree, dtree)
|
||||
{
|
||||
unsigned dist; /* distance of matched string */
|
||||
int lc; /* match length or unmatched char (if dist == 0) */
|
||||
- unsigned lx = 0; /* running index in l_buf */
|
||||
+ unsigned sx = 0; /* running index in sym_buf */
|
||||
unsigned code; /* the code to send */
|
||||
int extra; /* number of extra bits to send */
|
||||
|
||||
- if (s->last_lit != 0) do {
|
||||
- dist = s->d_buf[lx];
|
||||
- lc = s->l_buf[lx++];
|
||||
+ if (s->sym_next != 0) do {
|
||||
+ dist = s->sym_buf[sx++] & 0xff;
|
||||
+ dist += (unsigned)(s->sym_buf[sx++] & 0xff) << 8;
|
||||
+ lc = s->sym_buf[sx++];
|
||||
if (dist == 0) {
|
||||
send_code(s, lc, ltree); /* send a literal byte */
|
||||
Tracecv(isgraph(lc), (stderr," '%c' ", lc));
|
||||
@@ -1100,11 +1079,10 @@ local void compress_block(s, ltree, dtree)
|
||||
}
|
||||
} /* literal or match pair ? */
|
||||
|
||||
- /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
|
||||
- Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx,
|
||||
- "pendingBuf overflow");
|
||||
+ /* Check that the overlay between pending_buf and sym_buf is ok: */
|
||||
+ Assert(s->pending < s->lit_bufsize + sx, "pendingBuf overflow");
|
||||
|
||||
- } while (lx < s->last_lit);
|
||||
+ } while (sx < s->sym_next);
|
||||
|
||||
send_code(s, END_BLOCK, ltree);
|
||||
}
|
||||
@@ -28,7 +28,9 @@ define Package/firewall
|
||||
SECTION:=net
|
||||
CATEGORY:=Base system
|
||||
TITLE:=OpenWrt C Firewall
|
||||
DEPENDS:=+libubox +libubus +libuci +libip4tc +IPV6:libip6tc +libxtables +kmod-ipt-core +kmod-ipt-conntrack +IPV6:kmod-nf-conntrack6 +kmod-ipt-nat +iptables-mod-fullconenat
|
||||
DEPENDS:=+libubox +libubus +libuci +libip4tc +IPV6:libip6tc +libxtables \
|
||||
+kmod-ipt-core +kmod-ipt-conntrack +IPV6:kmod-nf-conntrack6 +kmod-ipt-nat \
|
||||
+iptables-mod-fullconenat
|
||||
endef
|
||||
|
||||
define Package/firewall/description
|
||||
|
||||
@@ -3,7 +3,7 @@ config defaults
|
||||
option input ACCEPT
|
||||
option output ACCEPT
|
||||
option forward REJECT
|
||||
option fullcone 1
|
||||
option fullcone 1
|
||||
# Uncomment this line to disable ipv6 rules
|
||||
# option disable_ipv6 1
|
||||
|
||||
@@ -130,10 +130,10 @@ config rule
|
||||
option proto udp
|
||||
option target ACCEPT
|
||||
|
||||
# allow interoperability with traceroute classic
|
||||
# note that traceroute uses a fixed port range, and depends on getting
|
||||
# back ICMP Unreachables. if we're operating in DROP mode, it won't
|
||||
# work so we explicitly REJECT packets on these ports.
|
||||
# Allow interoperability with traceroute classic note that
|
||||
# traceroute uses a fixed port range, and depends on getting
|
||||
# back ICMP Unreachables. If we're operating in DROP mode, it
|
||||
# won't work so we explicitly REJECT packets on these ports.
|
||||
config rule
|
||||
option name Support-UDP-Traceroute
|
||||
option src wan
|
||||
|
||||
@@ -1,34 +1,28 @@
|
||||
index 85a3750..9fac9b1 100644
|
||||
--- a/defaults.c
|
||||
+++ b/defaults.c
|
||||
@@ -46,7 +46,9 @@ const struct fw3_option fw3_flag_opts[] = {
|
||||
@@ -48,7 +48,9 @@ const struct fw3_option fw3_flag_opts[] = {
|
||||
FW3_OPT("synflood_protect", bool, defaults, syn_flood),
|
||||
FW3_OPT("synflood_rate", limit, defaults, syn_flood_rate),
|
||||
FW3_OPT("synflood_burst", int, defaults, syn_flood_rate.burst),
|
||||
-
|
||||
+
|
||||
+ FW3_OPT("fullcone", bool, defaults, fullcone),
|
||||
+
|
||||
+
|
||||
+ FW3_OPT("fullcone", bool, defaults, fullcone),
|
||||
|
||||
FW3_OPT("tcp_syncookies", bool, defaults, tcp_syncookies),
|
||||
FW3_OPT("tcp_ecn", int, defaults, tcp_ecn),
|
||||
FW3_OPT("tcp_window_scaling", bool, defaults, tcp_window_scaling),
|
||||
diff --git a/options.h b/options.h
|
||||
index 6edd174..c02eb97 100644
|
||||
--- a/options.h
|
||||
+++ b/options.h
|
||||
@@ -267,6 +267,7 @@ struct fw3_defaults
|
||||
bool drop_invalid;
|
||||
@@ -296,6 +296,7 @@ struct fw3_defaults
|
||||
enum fw3_reject_code tcp_reject_code;
|
||||
enum fw3_reject_code any_reject_code;
|
||||
|
||||
bool syn_flood;
|
||||
+ bool fullcone;
|
||||
bool syn_flood;
|
||||
struct fw3_limit syn_flood_rate;
|
||||
|
||||
bool tcp_syncookies;
|
||||
diff --git a/zones.c b/zones.c
|
||||
index 2aa7473..57eead0 100644
|
||||
--- a/zones.c
|
||||
+++ b/zones.c
|
||||
@@ -627,6 +627,7 @@ print_zone_rule(struct fw3_ipt_handle *h
|
||||
@@ -670,6 +670,7 @@ print_zone_rule(struct fw3_ipt_handle *h
|
||||
struct fw3_address *msrc;
|
||||
struct fw3_address *mdest;
|
||||
struct fw3_ipt_rule *r;
|
||||
@@ -36,7 +30,7 @@ index 2aa7473..57eead0 100644
|
||||
|
||||
if (!fw3_is_family(zone, handle->family))
|
||||
return;
|
||||
@@ -712,8 +713,22 @@ print_zone_rule(struct fw3_ipt_handle *h
|
||||
@@ -755,8 +756,22 @@ print_zone_rule(struct fw3_ipt_handle *h
|
||||
{
|
||||
r = fw3_ipt_rule_new(handle);
|
||||
fw3_ipt_rule_src_dest(r, msrc, mdest);
|
||||
@@ -20,6 +20,8 @@ PKG_MIRROR_HASH:=e7bb77d9916d190b3c02975faf62d1794557d4a4a774cd0cf1f3a6ddb7403e3
|
||||
PKG_LICENSE:=GPL-2.0
|
||||
PKG_LICENSE_FILES:=LICENSE
|
||||
|
||||
PKG_MAINTAINER:=Chion Tang <tech@chionlab.moe>
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/iptables-mod-fullconenat
|
||||
@@ -28,7 +30,6 @@ define Package/iptables-mod-fullconenat
|
||||
CATEGORY:=Network
|
||||
TITLE:=FULLCONENAT iptables extension
|
||||
DEPENDS:=+iptables +kmod-ipt-fullconenat
|
||||
MAINTAINER:=Chion Tang <tech@chionlab.moe>
|
||||
endef
|
||||
|
||||
define Package/iptables-mod-fullconenat/install
|
||||
@@ -40,8 +41,9 @@ define KernelPackage/ipt-fullconenat
|
||||
SUBMENU:=Netfilter Extensions
|
||||
TITLE:=FULLCONENAT netfilter module
|
||||
DEPENDS:=+kmod-nf-ipt +kmod-nf-nat
|
||||
MAINTAINER:=Chion Tang <tech@chionlab.moe>
|
||||
KCONFIG:=CONFIG_NF_CONNTRACK_EVENTS=y CONFIG_NF_CONNTRACK_CHAIN_EVENTS=y
|
||||
KCONFIG:= \
|
||||
CONFIG_NF_CONNTRACK_EVENTS=y \
|
||||
CONFIG_NF_CONNTRACK_CHAIN_EVENTS=y
|
||||
FILES:=$(PKG_BUILD_DIR)/xt_FULLCONENAT.ko
|
||||
endef
|
||||
|
||||
@@ -4,4 +4,3 @@ libipt_FULLCONENAT.o: libipt_FULLCONENAT.c
|
||||
$(CC) ${CFLAGS} -fPIC -D_INIT=$*_init -c -o $@ $<;
|
||||
|
||||
obj-m += xt_FULLCONENAT.o
|
||||
|
||||
@@ -9,7 +9,6 @@ include $(INCLUDE_DIR)/package.mk
|
||||
define Package/urandom-seed
|
||||
SECTION:=base
|
||||
CATEGORY:=Base system
|
||||
DEPENDS:=+getrandom
|
||||
TITLE:=/etc/urandom.seed handling for OpenWrt
|
||||
URL:=https://openwrt.org/
|
||||
endef
|
||||
@@ -19,11 +18,15 @@ define Build/Prepare
|
||||
endef
|
||||
|
||||
define Build/Compile/Default
|
||||
$(TARGET_CC) $(TARGET_CFLAGS) $(TARGET_CPPFLAGS) $(TARGET_LDFLAGS) \
|
||||
-std=gnu99 -o $(PKG_BUILD_DIR)/seedrng seedrng.c
|
||||
endef
|
||||
Build/Compile = $(Build/Compile/Default)
|
||||
|
||||
define Package/urandom-seed/install
|
||||
$(CP) ./files/* $(1)/
|
||||
$(INSTALL_DIR) $(1)/sbin
|
||||
$(CP) $(PKG_BUILD_DIR)/seedrng $(1)/sbin/
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,urandom-seed))
|
||||
|
||||
@@ -5,7 +5,7 @@ USE_PROCD=1
|
||||
|
||||
start_service() {
|
||||
procd_open_instance "urandom_seed"
|
||||
procd_set_param command "/sbin/urandom_seed"
|
||||
procd_set_param command "/sbin/seedrng"
|
||||
procd_set_param stdout 1
|
||||
procd_set_param stderr 1
|
||||
procd_close_instance
|
||||
|
||||
@@ -2,21 +2,11 @@ log_urandom_seed() {
|
||||
echo "urandom-seed: $1" > /dev/kmsg
|
||||
}
|
||||
|
||||
_do_urandom_seed() {
|
||||
[ -f "$1" ] || { log_urandom_seed "Seed file not found ($1)"; return; }
|
||||
[ -O "$1" -a -G "$1" -a ! -x "$1" ] || { log_urandom_seed "Wrong owner / permissions for $1"; return; }
|
||||
|
||||
log_urandom_seed "Seeding with $1"
|
||||
cat "$1" > /dev/urandom
|
||||
}
|
||||
|
||||
do_urandom_seed() {
|
||||
[ -c /dev/urandom ] || { log_urandom_seed "Something is wrong with /dev/urandom"; return; }
|
||||
|
||||
_do_urandom_seed "/etc/urandom.seed"
|
||||
|
||||
SEED="$(uci -q get system.@system[0].urandom_seed)"
|
||||
[ "${SEED:0:1}" = "/" -a "$SEED" != "/etc/urandom.seed" ] && _do_urandom_seed "$SEED"
|
||||
seedrng 2>&1 | while read -r line; do
|
||||
log_urandom_seed "$line"
|
||||
done
|
||||
}
|
||||
|
||||
boot_hook_add preinit_main do_urandom_seed
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
trap '[ "$?" -eq 0 ] || echo "An error occured" >&2' EXIT
|
||||
|
||||
save() {
|
||||
touch "$1.tmp"
|
||||
chown root:root "$1.tmp"
|
||||
chmod 600 "$1.tmp"
|
||||
getrandom 512 > "$1.tmp"
|
||||
mv "$1.tmp" "$1"
|
||||
echo "Seed saved ($1)"
|
||||
}
|
||||
|
||||
SEED="$(uci -q get system.@system[0].urandom_seed || true)"
|
||||
[ "${SEED:0:1}" = "/" ] && save "$SEED"
|
||||
|
||||
SEED=/etc/urandom.seed
|
||||
[ ! -f $SEED ] && save "$SEED"
|
||||
true
|
||||
438
package/system/urandom-seed/seedrng.c
Normal file
438
package/system/urandom-seed/seedrng.c
Normal file
@@ -0,0 +1,438 @@
|
||||
// SPDX-License-Identifier: (GPL-2.0 OR MIT OR Apache-2.0)
|
||||
/*
|
||||
* Copyright (C) 2022 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
|
||||
*/
|
||||
|
||||
#include <linux/random.h>
|
||||
#include <sys/random.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <poll.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include <endian.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef GRND_INSECURE
|
||||
#define GRND_INSECURE 0x0004
|
||||
#endif
|
||||
|
||||
#define SEED_DIR "/etc/seedrng"
|
||||
#define CREDITABLE_SEED SEED_DIR "/seed.credit"
|
||||
#define NON_CREDITABLE_SEED SEED_DIR "/seed.no-credit"
|
||||
#define LOCK_FILE "/tmp/run/seedrng.lock"
|
||||
|
||||
enum blake2s_lengths {
|
||||
BLAKE2S_BLOCK_LEN = 64,
|
||||
BLAKE2S_HASH_LEN = 32,
|
||||
BLAKE2S_KEY_LEN = 32
|
||||
};
|
||||
|
||||
enum seedrng_lengths {
|
||||
MAX_SEED_LEN = 512,
|
||||
MIN_SEED_LEN = BLAKE2S_HASH_LEN
|
||||
};
|
||||
|
||||
struct blake2s_state {
|
||||
uint32_t h[8];
|
||||
uint32_t t[2];
|
||||
uint32_t f[2];
|
||||
uint8_t buf[BLAKE2S_BLOCK_LEN];
|
||||
unsigned int buflen;
|
||||
unsigned int outlen;
|
||||
};
|
||||
|
||||
#define le32_to_cpup(a) le32toh(*(a))
|
||||
#define cpu_to_le32(a) htole32(a)
|
||||
#ifndef ARRAY_SIZE
|
||||
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
||||
#endif
|
||||
#ifndef DIV_ROUND_UP
|
||||
#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
|
||||
#endif
|
||||
|
||||
static inline void cpu_to_le32_array(uint32_t *buf, unsigned int words)
|
||||
{
|
||||
while (words--) {
|
||||
*buf = cpu_to_le32(*buf);
|
||||
++buf;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void le32_to_cpu_array(uint32_t *buf, unsigned int words)
|
||||
{
|
||||
while (words--) {
|
||||
*buf = le32_to_cpup(buf);
|
||||
++buf;
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint32_t ror32(uint32_t word, unsigned int shift)
|
||||
{
|
||||
return (word >> (shift & 31)) | (word << ((-shift) & 31));
|
||||
}
|
||||
|
||||
static const uint32_t blake2s_iv[8] = {
|
||||
0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL,
|
||||
0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL
|
||||
};
|
||||
|
||||
static const uint8_t blake2s_sigma[10][16] = {
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
|
||||
{ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 },
|
||||
{ 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 },
|
||||
{ 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 },
|
||||
{ 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 },
|
||||
{ 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 },
|
||||
{ 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 },
|
||||
{ 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 },
|
||||
{ 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 },
|
||||
{ 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0 },
|
||||
};
|
||||
|
||||
static void blake2s_set_lastblock(struct blake2s_state *state)
|
||||
{
|
||||
state->f[0] = -1;
|
||||
}
|
||||
|
||||
static void blake2s_increment_counter(struct blake2s_state *state, const uint32_t inc)
|
||||
{
|
||||
state->t[0] += inc;
|
||||
state->t[1] += (state->t[0] < inc);
|
||||
}
|
||||
|
||||
static void blake2s_init_param(struct blake2s_state *state, const uint32_t param)
|
||||
{
|
||||
int i;
|
||||
|
||||
memset(state, 0, sizeof(*state));
|
||||
for (i = 0; i < 8; ++i)
|
||||
state->h[i] = blake2s_iv[i];
|
||||
state->h[0] ^= param;
|
||||
}
|
||||
|
||||
static void blake2s_init(struct blake2s_state *state, const size_t outlen)
|
||||
{
|
||||
blake2s_init_param(state, 0x01010000 | outlen);
|
||||
state->outlen = outlen;
|
||||
}
|
||||
|
||||
static void blake2s_compress(struct blake2s_state *state, const uint8_t *block, size_t nblocks, const uint32_t inc)
|
||||
{
|
||||
uint32_t m[16];
|
||||
uint32_t v[16];
|
||||
int i;
|
||||
|
||||
while (nblocks > 0) {
|
||||
blake2s_increment_counter(state, inc);
|
||||
memcpy(m, block, BLAKE2S_BLOCK_LEN);
|
||||
le32_to_cpu_array(m, ARRAY_SIZE(m));
|
||||
memcpy(v, state->h, 32);
|
||||
v[ 8] = blake2s_iv[0];
|
||||
v[ 9] = blake2s_iv[1];
|
||||
v[10] = blake2s_iv[2];
|
||||
v[11] = blake2s_iv[3];
|
||||
v[12] = blake2s_iv[4] ^ state->t[0];
|
||||
v[13] = blake2s_iv[5] ^ state->t[1];
|
||||
v[14] = blake2s_iv[6] ^ state->f[0];
|
||||
v[15] = blake2s_iv[7] ^ state->f[1];
|
||||
|
||||
#define G(r, i, a, b, c, d) do { \
|
||||
a += b + m[blake2s_sigma[r][2 * i + 0]]; \
|
||||
d = ror32(d ^ a, 16); \
|
||||
c += d; \
|
||||
b = ror32(b ^ c, 12); \
|
||||
a += b + m[blake2s_sigma[r][2 * i + 1]]; \
|
||||
d = ror32(d ^ a, 8); \
|
||||
c += d; \
|
||||
b = ror32(b ^ c, 7); \
|
||||
} while (0)
|
||||
|
||||
#define ROUND(r) do { \
|
||||
G(r, 0, v[0], v[ 4], v[ 8], v[12]); \
|
||||
G(r, 1, v[1], v[ 5], v[ 9], v[13]); \
|
||||
G(r, 2, v[2], v[ 6], v[10], v[14]); \
|
||||
G(r, 3, v[3], v[ 7], v[11], v[15]); \
|
||||
G(r, 4, v[0], v[ 5], v[10], v[15]); \
|
||||
G(r, 5, v[1], v[ 6], v[11], v[12]); \
|
||||
G(r, 6, v[2], v[ 7], v[ 8], v[13]); \
|
||||
G(r, 7, v[3], v[ 4], v[ 9], v[14]); \
|
||||
} while (0)
|
||||
ROUND(0);
|
||||
ROUND(1);
|
||||
ROUND(2);
|
||||
ROUND(3);
|
||||
ROUND(4);
|
||||
ROUND(5);
|
||||
ROUND(6);
|
||||
ROUND(7);
|
||||
ROUND(8);
|
||||
ROUND(9);
|
||||
|
||||
#undef G
|
||||
#undef ROUND
|
||||
|
||||
for (i = 0; i < 8; ++i)
|
||||
state->h[i] ^= v[i] ^ v[i + 8];
|
||||
|
||||
block += BLAKE2S_BLOCK_LEN;
|
||||
--nblocks;
|
||||
}
|
||||
}
|
||||
|
||||
static void blake2s_update(struct blake2s_state *state, const void *inp, size_t inlen)
|
||||
{
|
||||
const size_t fill = BLAKE2S_BLOCK_LEN - state->buflen;
|
||||
const uint8_t *in = inp;
|
||||
|
||||
if (!inlen)
|
||||
return;
|
||||
if (inlen > fill) {
|
||||
memcpy(state->buf + state->buflen, in, fill);
|
||||
blake2s_compress(state, state->buf, 1, BLAKE2S_BLOCK_LEN);
|
||||
state->buflen = 0;
|
||||
in += fill;
|
||||
inlen -= fill;
|
||||
}
|
||||
if (inlen > BLAKE2S_BLOCK_LEN) {
|
||||
const size_t nblocks = DIV_ROUND_UP(inlen, BLAKE2S_BLOCK_LEN);
|
||||
blake2s_compress(state, in, nblocks - 1, BLAKE2S_BLOCK_LEN);
|
||||
in += BLAKE2S_BLOCK_LEN * (nblocks - 1);
|
||||
inlen -= BLAKE2S_BLOCK_LEN * (nblocks - 1);
|
||||
}
|
||||
memcpy(state->buf + state->buflen, in, inlen);
|
||||
state->buflen += inlen;
|
||||
}
|
||||
|
||||
static void blake2s_final(struct blake2s_state *state, uint8_t *out)
|
||||
{
|
||||
blake2s_set_lastblock(state);
|
||||
memset(state->buf + state->buflen, 0, BLAKE2S_BLOCK_LEN - state->buflen);
|
||||
blake2s_compress(state, state->buf, 1, state->buflen);
|
||||
cpu_to_le32_array(state->h, ARRAY_SIZE(state->h));
|
||||
memcpy(out, state->h, state->outlen);
|
||||
}
|
||||
|
||||
static size_t determine_optimal_seed_len(void)
|
||||
{
|
||||
size_t ret = 0;
|
||||
char poolsize_str[11] = { 0 };
|
||||
int fd = open("/proc/sys/kernel/random/poolsize", O_RDONLY);
|
||||
|
||||
if (fd < 0 || read(fd, poolsize_str, sizeof(poolsize_str) - 1) < 0) {
|
||||
fprintf(stderr, "WARNING: Unable to determine pool size, falling back to %u bits: %s\n", MIN_SEED_LEN * 8, strerror(errno));
|
||||
ret = MIN_SEED_LEN;
|
||||
} else
|
||||
ret = DIV_ROUND_UP(strtoul(poolsize_str, NULL, 10), 8);
|
||||
if (fd >= 0)
|
||||
close(fd);
|
||||
if (ret < MIN_SEED_LEN)
|
||||
ret = MIN_SEED_LEN;
|
||||
else if (ret > MAX_SEED_LEN)
|
||||
ret = MAX_SEED_LEN;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int read_new_seed(uint8_t *seed, size_t len, bool *is_creditable)
|
||||
{
|
||||
ssize_t ret;
|
||||
int urandom_fd;
|
||||
|
||||
*is_creditable = false;
|
||||
ret = getrandom(seed, len, GRND_NONBLOCK);
|
||||
if (ret == (ssize_t)len) {
|
||||
*is_creditable = true;
|
||||
return 0;
|
||||
} else if (ret < 0 && errno == ENOSYS) {
|
||||
struct pollfd random_fd = {
|
||||
.fd = open("/dev/random", O_RDONLY),
|
||||
.events = POLLIN
|
||||
};
|
||||
if (random_fd.fd < 0)
|
||||
return -errno;
|
||||
*is_creditable = poll(&random_fd, 1, 0) == 1;
|
||||
close(random_fd.fd);
|
||||
} else if (getrandom(seed, len, GRND_INSECURE) == (ssize_t)len)
|
||||
return 0;
|
||||
urandom_fd = open("/dev/urandom", O_RDONLY);
|
||||
if (urandom_fd < 0)
|
||||
return -errno;
|
||||
ret = read(urandom_fd, seed, len);
|
||||
if (ret == (ssize_t)len)
|
||||
ret = 0;
|
||||
else
|
||||
ret = -errno ? -errno : -EIO;
|
||||
close(urandom_fd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int seed_rng(uint8_t *seed, size_t len, bool credit)
|
||||
{
|
||||
struct {
|
||||
int entropy_count;
|
||||
int buf_size;
|
||||
uint8_t buffer[MAX_SEED_LEN];
|
||||
} req = {
|
||||
.entropy_count = credit ? len * 8 : 0,
|
||||
.buf_size = len
|
||||
};
|
||||
int random_fd, ret;
|
||||
|
||||
if (len > sizeof(req.buffer))
|
||||
return -EFBIG;
|
||||
memcpy(req.buffer, seed, len);
|
||||
|
||||
random_fd = open("/dev/random", O_RDWR);
|
||||
if (random_fd < 0)
|
||||
return -errno;
|
||||
ret = ioctl(random_fd, RNDADDENTROPY, &req);
|
||||
if (ret)
|
||||
ret = -errno ? -errno : -EIO;
|
||||
close(random_fd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int seed_from_file_if_exists(const char *filename, bool credit, struct blake2s_state *hash)
|
||||
{
|
||||
uint8_t seed[MAX_SEED_LEN];
|
||||
ssize_t seed_len;
|
||||
int fd, dfd, ret = 0;
|
||||
|
||||
fd = open(filename, O_RDONLY);
|
||||
if (fd < 0 && errno == ENOENT)
|
||||
return 0;
|
||||
else if (fd < 0) {
|
||||
ret = -errno;
|
||||
fprintf(stderr, "ERROR: Unable to open seed file: %s\n", strerror(errno));
|
||||
return ret;
|
||||
}
|
||||
dfd = open(SEED_DIR, O_DIRECTORY | O_RDONLY);
|
||||
if (dfd < 0) {
|
||||
ret = -errno;
|
||||
close(fd);
|
||||
fprintf(stderr, "ERROR: Unable to open seed directory: %s\n", strerror(errno));
|
||||
return ret;
|
||||
}
|
||||
seed_len = read(fd, seed, sizeof(seed));
|
||||
if (seed_len < 0) {
|
||||
ret = -errno;
|
||||
fprintf(stderr, "ERROR: Unable to read seed file: %s\n", strerror(errno));
|
||||
}
|
||||
close(fd);
|
||||
if (ret) {
|
||||
close(dfd);
|
||||
return ret;
|
||||
}
|
||||
if ((unlink(filename) < 0 || fsync(dfd) < 0) && seed_len) {
|
||||
ret = -errno;
|
||||
fprintf(stderr, "ERROR: Unable to remove seed after reading, so not seeding: %s\n", strerror(errno));
|
||||
}
|
||||
close(dfd);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (!seed_len)
|
||||
return 0;
|
||||
|
||||
blake2s_update(hash, &seed_len, sizeof(seed_len));
|
||||
blake2s_update(hash, seed, seed_len);
|
||||
|
||||
fprintf(stdout, "Seeding %zd bits %s crediting\n", seed_len * 8, credit ? "and" : "without");
|
||||
ret = seed_rng(seed, seed_len, credit);
|
||||
if (ret < 0)
|
||||
fprintf(stderr, "ERROR: Unable to seed: %s\n", strerror(-ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool skip_credit(void)
|
||||
{
|
||||
const char *skip = getenv("SEEDRNG_SKIP_CREDIT");
|
||||
return skip && (!strcmp(skip, "1") || !strcasecmp(skip, "true") ||
|
||||
!strcasecmp(skip, "yes") || !strcasecmp(skip, "y"));
|
||||
}
|
||||
|
||||
int main(int argc __attribute__((unused)), char *argv[] __attribute__((unused)))
|
||||
{
|
||||
static const char seedrng_prefix[] = "SeedRNG v1 Old+New Prefix";
|
||||
static const char seedrng_failure[] = "SeedRNG v1 No New Seed Failure";
|
||||
int ret, fd = -1, lock, program_ret = 0;
|
||||
uint8_t new_seed[MAX_SEED_LEN];
|
||||
size_t new_seed_len;
|
||||
bool new_seed_creditable;
|
||||
struct timespec realtime = { 0 }, boottime = { 0 };
|
||||
struct blake2s_state hash;
|
||||
|
||||
umask(0077);
|
||||
if (getuid()) {
|
||||
fprintf(stderr, "ERROR: This program requires root\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
blake2s_init(&hash, BLAKE2S_HASH_LEN);
|
||||
blake2s_update(&hash, seedrng_prefix, strlen(seedrng_prefix));
|
||||
clock_gettime(CLOCK_REALTIME, &realtime);
|
||||
clock_gettime(CLOCK_BOOTTIME, &boottime);
|
||||
blake2s_update(&hash, &realtime, sizeof(realtime));
|
||||
blake2s_update(&hash, &boottime, sizeof(boottime));
|
||||
|
||||
if (mkdir(SEED_DIR, 0700) < 0 && errno != EEXIST) {
|
||||
fprintf(stderr, "ERROR: Unable to create \"%s\" directory: %s\n", SEED_DIR, strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
lock = open(LOCK_FILE, O_WRONLY | O_CREAT, 0000);
|
||||
if (lock < 0 || flock(lock, LOCK_EX) < 0) {
|
||||
fprintf(stderr, "ERROR: Unable to open lock file: %s\n", strerror(errno));
|
||||
program_ret = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = seed_from_file_if_exists(NON_CREDITABLE_SEED, false, &hash);
|
||||
if (ret < 0)
|
||||
program_ret |= 1 << 1;
|
||||
ret = seed_from_file_if_exists(CREDITABLE_SEED, !skip_credit(), &hash);
|
||||
if (ret < 0)
|
||||
program_ret |= 1 << 2;
|
||||
|
||||
new_seed_len = determine_optimal_seed_len();
|
||||
ret = read_new_seed(new_seed, new_seed_len, &new_seed_creditable);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "ERROR: Unable to read new seed: %s\n", strerror(-ret));
|
||||
new_seed_len = BLAKE2S_HASH_LEN;
|
||||
strncpy((char *)new_seed, seedrng_failure, new_seed_len);
|
||||
program_ret |= 1 << 3;
|
||||
}
|
||||
blake2s_update(&hash, &new_seed_len, sizeof(new_seed_len));
|
||||
blake2s_update(&hash, new_seed, new_seed_len);
|
||||
blake2s_final(&hash, new_seed + new_seed_len - BLAKE2S_HASH_LEN);
|
||||
|
||||
fprintf(stdout, "Saving %zu bits of %s seed for next boot\n", new_seed_len * 8, new_seed_creditable ? "creditable" : "non-creditable");
|
||||
fd = open(NON_CREDITABLE_SEED, O_WRONLY | O_CREAT | O_TRUNC, 0400);
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, "ERROR: Unable to open seed file for writing: %s\n", strerror(errno));
|
||||
program_ret |= 1 << 4;
|
||||
goto out;
|
||||
}
|
||||
if (write(fd, new_seed, new_seed_len) != (ssize_t)new_seed_len || fsync(fd) < 0) {
|
||||
fprintf(stderr, "ERROR: Unable to write seed file: %s\n", strerror(errno));
|
||||
program_ret |= 1 << 5;
|
||||
goto out;
|
||||
}
|
||||
if (new_seed_creditable && rename(NON_CREDITABLE_SEED, CREDITABLE_SEED) < 0) {
|
||||
fprintf(stderr, "WARNING: Unable to make new seed creditable: %s\n", strerror(errno));
|
||||
program_ret |= 1 << 6;
|
||||
}
|
||||
out:
|
||||
if (fd >= 0)
|
||||
close(fd);
|
||||
if (lock >= 0)
|
||||
close(lock);
|
||||
return program_ret;
|
||||
}
|
||||
@@ -72,9 +72,9 @@
|
||||
+
|
||||
+static int do_lock(void)
|
||||
+{
|
||||
+ int pid;
|
||||
+ pid_t pid;
|
||||
+ int flags;
|
||||
+ char pidstr[8];
|
||||
+ char pidstr[12];
|
||||
+
|
||||
+ if ((fd = open(file, O_RDWR | O_CREAT | O_EXCL, 0700)) < 0) {
|
||||
+ if ((fd = open(file, O_RDWR)) < 0) {
|
||||
@@ -109,7 +109,7 @@
|
||||
+ if (!waitonly) {
|
||||
+ lseek(fd, 0, SEEK_SET);
|
||||
+ ftruncate(fd, 0);
|
||||
+ sprintf(pidstr, "%d\n", pid);
|
||||
+ snprintf(pidstr, sizeof(pidstr), "%d\n", pid);
|
||||
+ write(fd, pidstr, strlen(pidstr));
|
||||
+ close(fd);
|
||||
+ }
|
||||
|
||||
@@ -58,7 +58,8 @@ pkg_appears_sane() {
|
||||
|
||||
rm "$CONTROL"/conffiles
|
||||
if [ -f "$CONTROL"/conffiles.resolved ]; then
|
||||
mv "$CONTROL"/conffiles.resolved "$CONTROL"/conffiles
|
||||
sort -o "$CONTROL"/conffiles "$CONTROL"/conffiles.resolved
|
||||
rm "$CONTROL"/conffiles.resolved
|
||||
chmod 0644 "$CONTROL"/conffiles
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -177,6 +177,8 @@ CONFIG_GPIOLIB=y
|
||||
CONFIG_GPIOLIB_IRQCHIP=y
|
||||
CONFIG_GPIO_PCA953X=y
|
||||
CONFIG_GPIO_PCA953X_IRQ=y
|
||||
CONFIG_GPIO_WATCHDOG=y
|
||||
CONFIG_GPIO_WATCHDOG_ARCH_INITCALL=y
|
||||
CONFIG_GRO_CELLS=y
|
||||
CONFIG_HANDLE_DOMAIN_IRQ=y
|
||||
CONFIG_HARDEN_BRANCH_PREDICTOR=y
|
||||
|
||||
@@ -166,6 +166,8 @@ CONFIG_GPIOLIB=y
|
||||
CONFIG_GPIOLIB_IRQCHIP=y
|
||||
CONFIG_GPIO_PCA953X=y
|
||||
CONFIG_GPIO_PCA953X_IRQ=y
|
||||
CONFIG_GPIO_WATCHDOG=y
|
||||
CONFIG_GPIO_WATCHDOG_ARCH_INITCALL=y
|
||||
CONFIG_GRO_CELLS=y
|
||||
CONFIG_HANDLE_DOMAIN_IRQ=y
|
||||
CONFIG_HARDEN_BRANCH_PREDICTOR=y
|
||||
|
||||
@@ -47,6 +47,16 @@
|
||||
linux,code = <KEY_RESTART>;
|
||||
};
|
||||
};
|
||||
|
||||
watchdog {
|
||||
compatible = "linux,wdt-gpio";
|
||||
pinctrl-0 = <&wdt0_pins>;
|
||||
pinctrl-names = "default";
|
||||
gpios = <&qcom_pinmux 17 GPIO_ACTIVE_LOW>;
|
||||
hw_algo = "toggle";
|
||||
hw_margin_ms = <500>;
|
||||
always-running;
|
||||
};
|
||||
};
|
||||
|
||||
&qcom_pinmux {
|
||||
@@ -106,6 +116,15 @@
|
||||
drive-strength = <12>;
|
||||
};
|
||||
};
|
||||
|
||||
wdt0_pins: wdt0_pins {
|
||||
mux {
|
||||
pins = "gpio17";
|
||||
function = "gpio";
|
||||
drive-strength = <2>;
|
||||
bias-pull-down;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&gsbi2 {
|
||||
|
||||
157
tools/dosfstools/patches/source-date-epoch.patch
Normal file
157
tools/dosfstools/patches/source-date-epoch.patch
Normal file
@@ -0,0 +1,157 @@
|
||||
From 8da7bc93315cb0c32ad868f17808468b81fa76ec Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Bj=C3=B8rn=20Forsman?= <bjorn.forsman@gmail.com>
|
||||
Date: Wed, 5 Dec 2018 19:52:51 +0100
|
||||
Subject: [PATCH] Honor the SOURCE_DATE_EPOCH variable
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Implement the SOURCE_DATE_EPOCH specification[1] for reproducible
|
||||
builds. If SOURCE_DATE_EPOCH is set, use it as timestamp instead of the
|
||||
current time.
|
||||
|
||||
[1] https://reproducible-builds.org/specs/source-date-epoch/
|
||||
|
||||
Signed-off-by: Bjørn Forsman <bjorn.forsman@gmail.com>
|
||||
---
|
||||
src/boot.c | 23 +++++++++++++++++++++--
|
||||
src/common.c | 18 ++++++++++++++++--
|
||||
src/mkfs.fat.c | 19 ++++++++++++++++---
|
||||
3 files changed, 53 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/src/boot.c b/src/boot.c
|
||||
index 4de450d..8f78e1c 100644
|
||||
--- a/src/boot.c
|
||||
+++ b/src/boot.c
|
||||
@@ -33,6 +33,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
+#include <errno.h>
|
||||
+#include <ctype.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "fsck.fat.h"
|
||||
@@ -672,6 +674,7 @@ void write_volume_label(DOS_FS * fs, char *label)
|
||||
{
|
||||
time_t now;
|
||||
struct tm *mtime;
|
||||
+ char *source_date_epoch = NULL;
|
||||
off_t offset;
|
||||
int created;
|
||||
DIR_ENT de;
|
||||
@@ -687,8 +690,24 @@ void write_volume_label(DOS_FS * fs, char *label)
|
||||
if (de.name[0] == 0xe5)
|
||||
de.name[0] = 0x05;
|
||||
|
||||
- now = time(NULL);
|
||||
- mtime = (now != (time_t)-1) ? localtime(&now) : NULL;
|
||||
+ source_date_epoch = getenv("SOURCE_DATE_EPOCH");
|
||||
+ if (source_date_epoch) {
|
||||
+ char *tmp = NULL;
|
||||
+ long long conversion = 0;
|
||||
+ errno = 0;
|
||||
+ conversion = strtoll(source_date_epoch, &tmp, 10);
|
||||
+ now = conversion;
|
||||
+ if (!isdigit((unsigned char)*source_date_epoch) || *tmp != '\0'
|
||||
+ || errno != 0 || (long long)now != conversion) {
|
||||
+ die("SOURCE_DATE_EPOCH is too big or contains non-digits: \"%s\"",
|
||||
+ source_date_epoch);
|
||||
+ }
|
||||
+ mtime = gmtime(&now);
|
||||
+ } else {
|
||||
+ now = time(NULL);
|
||||
+ mtime = (now != (time_t)-1) ? localtime(&now) : NULL;
|
||||
+ }
|
||||
+
|
||||
if (mtime && mtime->tm_year >= 80 && mtime->tm_year <= 207) {
|
||||
de.time = htole16((unsigned short)((mtime->tm_sec >> 1) +
|
||||
(mtime->tm_min << 5) +
|
||||
diff --git a/src/common.c b/src/common.c
|
||||
index 6a2e396..4f1afcb 100644
|
||||
--- a/src/common.c
|
||||
+++ b/src/common.c
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <errno.h>
|
||||
+#include <ctype.h>
|
||||
#include <wctype.h>
|
||||
#include <termios.h>
|
||||
#include <sys/time.h>
|
||||
@@ -298,8 +299,21 @@ void check_atari(void)
|
||||
uint32_t generate_volume_id(void)
|
||||
{
|
||||
struct timeval now;
|
||||
-
|
||||
- if (gettimeofday(&now, NULL) != 0 || now.tv_sec == (time_t)-1 || now.tv_sec < 0) {
|
||||
+ char *source_date_epoch = NULL;
|
||||
+
|
||||
+ source_date_epoch = getenv("SOURCE_DATE_EPOCH");
|
||||
+ if (source_date_epoch) {
|
||||
+ char *tmp = NULL;
|
||||
+ long long conversion = 0;
|
||||
+ errno = 0;
|
||||
+ conversion = strtoll(source_date_epoch, &tmp, 10);
|
||||
+ if (!isdigit((unsigned char)*source_date_epoch) || *tmp != '\0'
|
||||
+ || errno != 0) {
|
||||
+ die("SOURCE_DATE_EPOCH is too big or contains non-digits: \"%s\"",
|
||||
+ source_date_epoch);
|
||||
+ }
|
||||
+ return (uint32_t)conversion;
|
||||
+ } else if (gettimeofday(&now, NULL) != 0 || now.tv_sec == (time_t)-1 || now.tv_sec < 0) {
|
||||
srand(getpid());
|
||||
/* rand() returns int from [0,RAND_MAX], therefore only 31 bits */
|
||||
return (((uint32_t)(rand() & 0xFFFF)) << 16) | ((uint32_t)(rand() & 0xFFFF));
|
||||
diff --git a/src/mkfs.fat.c b/src/mkfs.fat.c
|
||||
index 37fc8ff..1948635 100644
|
||||
--- a/src/mkfs.fat.c
|
||||
+++ b/src/mkfs.fat.c
|
||||
@@ -1074,7 +1074,7 @@ static void setup_tables(void)
|
||||
}
|
||||
|
||||
/* If is not available then generate random 32 bit disk signature */
|
||||
- if (invariant)
|
||||
+ if (invariant || getenv("SOURCE_DATE_EPOCH"))
|
||||
disk_sig = volume_id;
|
||||
else if (!disk_sig)
|
||||
disk_sig = generate_volume_id();
|
||||
@@ -1287,7 +1287,7 @@ static void setup_tables(void)
|
||||
de->name[0] = 0x05;
|
||||
de->attr = ATTR_VOLUME;
|
||||
if (create_time != (time_t)-1) {
|
||||
- if (!invariant)
|
||||
+ if (!invariant && !getenv("SOURCE_DATE_EPOCH"))
|
||||
ctime = localtime(&create_time);
|
||||
else
|
||||
ctime = gmtime(&create_time);
|
||||
@@ -1477,6 +1477,7 @@ int main(int argc, char **argv)
|
||||
int blocks_specified = 0;
|
||||
struct timeval create_timeval;
|
||||
long long conversion;
|
||||
+ char *source_date_epoch = NULL;
|
||||
|
||||
enum {OPT_HELP=1000, OPT_INVARIANT, OPT_MBR, OPT_VARIANT, OPT_CODEPAGE, OPT_OFFSET};
|
||||
const struct option long_options[] = {
|
||||
@@ -1497,8 +1498,20 @@ int main(int argc, char **argv)
|
||||
program_name = p + 1;
|
||||
}
|
||||
|
||||
- if (gettimeofday(&create_timeval, NULL) == 0 && create_timeval.tv_sec != (time_t)-1)
|
||||
+ source_date_epoch = getenv("SOURCE_DATE_EPOCH");
|
||||
+ if (source_date_epoch) {
|
||||
+ errno = 0;
|
||||
+ conversion = strtoll(source_date_epoch, &tmp, 10);
|
||||
+ create_time = conversion;
|
||||
+ if (!isdigit((unsigned char)*source_date_epoch) || *tmp != '\0'
|
||||
+ || errno != 0 || (long long)create_time != conversion) {
|
||||
+ die("SOURCE_DATE_EPOCH is too big or contains non-digits: \"%s\"",
|
||||
+ source_date_epoch);
|
||||
+ }
|
||||
+ } else if (gettimeofday(&create_timeval, NULL) == 0 && create_timeval.tv_sec != (time_t)-1) {
|
||||
create_time = create_timeval.tv_sec;
|
||||
+ }
|
||||
+
|
||||
volume_id = generate_volume_id();
|
||||
check_atari();
|
||||
|
||||
@@ -8,12 +8,13 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=zlib
|
||||
PKG_VERSION:=1.2.11
|
||||
PKG_RELEASE:=2
|
||||
PKG_VERSION:=1.2.12
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
|
||||
PKG_SOURCE_URL:=@SF/libpng http://www.zlib.net
|
||||
PKG_HASH:=4ff941449631ace0d4d203e3483be9dbc9da454084111f97ea0a2114e19bf066
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL:=https://github.com/madler/zlib
|
||||
PKG_MIRROR_HASH:=a162fc219763635f0c1591ec515d4b08684e4b0bfb4b1c8e65e4eab18d597c27
|
||||
PKG_SOURCE_VERSION:=21767c654d31d2dccdde4330529775c6c5fd5389
|
||||
|
||||
PKG_LICENSE:=Zlib
|
||||
PKG_LICENSE_FILES:=README
|
||||
|
||||
@@ -1,343 +0,0 @@
|
||||
From 5c44459c3b28a9bd3283aaceab7c615f8020c531 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Adler <madler@alumni.caltech.edu>
|
||||
Date: Tue, 17 Apr 2018 22:09:22 -0700
|
||||
Subject: [PATCH] Fix a bug that can crash deflate on some input when using
|
||||
Z_FIXED.
|
||||
|
||||
This bug was reported by Danilo Ramos of Eideticom, Inc. It has
|
||||
lain in wait 13 years before being found! The bug was introduced
|
||||
in zlib 1.2.2.2, with the addition of the Z_FIXED option. That
|
||||
option forces the use of fixed Huffman codes. For rare inputs with
|
||||
a large number of distant matches, the pending buffer into which
|
||||
the compressed data is written can overwrite the distance symbol
|
||||
table which it overlays. That results in corrupted output due to
|
||||
invalid distances, and can result in out-of-bound accesses,
|
||||
crashing the application.
|
||||
|
||||
The fix here combines the distance buffer and literal/length
|
||||
buffers into a single symbol buffer. Now three bytes of pending
|
||||
buffer space are opened up for each literal or length/distance
|
||||
pair consumed, instead of the previous two bytes. This assures
|
||||
that the pending buffer cannot overwrite the symbol table, since
|
||||
the maximum fixed code compressed length/distance is 31 bits, and
|
||||
since there are four bytes of pending space for every three bytes
|
||||
of symbol space.
|
||||
---
|
||||
deflate.c | 74 ++++++++++++++++++++++++++++++++++++++++---------------
|
||||
deflate.h | 25 +++++++++----------
|
||||
trees.c | 50 +++++++++++--------------------------
|
||||
3 files changed, 79 insertions(+), 70 deletions(-)
|
||||
|
||||
diff --git a/deflate.c b/deflate.c
|
||||
index 425babc00..19cba873a 100644
|
||||
--- a/deflate.c
|
||||
+++ b/deflate.c
|
||||
@@ -255,11 +255,6 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
|
||||
int wrap = 1;
|
||||
static const char my_version[] = ZLIB_VERSION;
|
||||
|
||||
- ushf *overlay;
|
||||
- /* We overlay pending_buf and d_buf+l_buf. This works since the average
|
||||
- * output size for (length,distance) codes is <= 24 bits.
|
||||
- */
|
||||
-
|
||||
if (version == Z_NULL || version[0] != my_version[0] ||
|
||||
stream_size != sizeof(z_stream)) {
|
||||
return Z_VERSION_ERROR;
|
||||
@@ -329,9 +324,47 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
|
||||
|
||||
s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
|
||||
|
||||
- overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
|
||||
- s->pending_buf = (uchf *) overlay;
|
||||
- s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);
|
||||
+ /* We overlay pending_buf and sym_buf. This works since the average size
|
||||
+ * for length/distance pairs over any compressed block is assured to be 31
|
||||
+ * bits or less.
|
||||
+ *
|
||||
+ * Analysis: The longest fixed codes are a length code of 8 bits plus 5
|
||||
+ * extra bits, for lengths 131 to 257. The longest fixed distance codes are
|
||||
+ * 5 bits plus 13 extra bits, for distances 16385 to 32768. The longest
|
||||
+ * possible fixed-codes length/distance pair is then 31 bits total.
|
||||
+ *
|
||||
+ * sym_buf starts one-fourth of the way into pending_buf. So there are
|
||||
+ * three bytes in sym_buf for every four bytes in pending_buf. Each symbol
|
||||
+ * in sym_buf is three bytes -- two for the distance and one for the
|
||||
+ * literal/length. As each symbol is consumed, the pointer to the next
|
||||
+ * sym_buf value to read moves forward three bytes. From that symbol, up to
|
||||
+ * 31 bits are written to pending_buf. The closest the written pending_buf
|
||||
+ * bits gets to the next sym_buf symbol to read is just before the last
|
||||
+ * code is written. At that time, 31*(n-2) bits have been written, just
|
||||
+ * after 24*(n-2) bits have been consumed from sym_buf. sym_buf starts at
|
||||
+ * 8*n bits into pending_buf. (Note that the symbol buffer fills when n-1
|
||||
+ * symbols are written.) The closest the writing gets to what is unread is
|
||||
+ * then n+14 bits. Here n is lit_bufsize, which is 16384 by default, and
|
||||
+ * can range from 128 to 32768.
|
||||
+ *
|
||||
+ * Therefore, at a minimum, there are 142 bits of space between what is
|
||||
+ * written and what is read in the overlain buffers, so the symbols cannot
|
||||
+ * be overwritten by the compressed data. That space is actually 139 bits,
|
||||
+ * due to the three-bit fixed-code block header.
|
||||
+ *
|
||||
+ * That covers the case where either Z_FIXED is specified, forcing fixed
|
||||
+ * codes, or when the use of fixed codes is chosen, because that choice
|
||||
+ * results in a smaller compressed block than dynamic codes. That latter
|
||||
+ * condition then assures that the above analysis also covers all dynamic
|
||||
+ * blocks. A dynamic-code block will only be chosen to be emitted if it has
|
||||
+ * fewer bits than a fixed-code block would for the same set of symbols.
|
||||
+ * Therefore its average symbol length is assured to be less than 31. So
|
||||
+ * the compressed data for a dynamic block also cannot overwrite the
|
||||
+ * symbols from which it is being constructed.
|
||||
+ */
|
||||
+
|
||||
+ s->pending_buf = (uchf *) ZALLOC(strm, s->lit_bufsize, 4);
|
||||
+ s->pending_buf_size = (ulg)s->lit_bufsize * 4;
|
||||
|
||||
if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
|
||||
s->pending_buf == Z_NULL) {
|
||||
@@ -340,8 +373,12 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
|
||||
deflateEnd (strm);
|
||||
return Z_MEM_ERROR;
|
||||
}
|
||||
- s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
|
||||
- s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
|
||||
+ s->sym_buf = s->pending_buf + s->lit_bufsize;
|
||||
+ s->sym_end = (s->lit_bufsize - 1) * 3;
|
||||
+ /* We avoid equality with lit_bufsize*3 because of wraparound at 64K
|
||||
+ * on 16 bit machines and because stored blocks are restricted to
|
||||
+ * 64K-1 bytes.
|
||||
+ */
|
||||
|
||||
s->level = level;
|
||||
s->strategy = strategy;
|
||||
@@ -552,7 +589,7 @@ int ZEXPORT deflatePrime (strm, bits, value)
|
||||
|
||||
if (deflateStateCheck(strm)) return Z_STREAM_ERROR;
|
||||
s = strm->state;
|
||||
- if ((Bytef *)(s->d_buf) < s->pending_out + ((Buf_size + 7) >> 3))
|
||||
+ if (s->sym_buf < s->pending_out + ((Buf_size + 7) >> 3))
|
||||
return Z_BUF_ERROR;
|
||||
do {
|
||||
put = Buf_size - s->bi_valid;
|
||||
@@ -1113,7 +1150,6 @@ int ZEXPORT deflateCopy (dest, source)
|
||||
#else
|
||||
deflate_state *ds;
|
||||
deflate_state *ss;
|
||||
- ushf *overlay;
|
||||
|
||||
|
||||
if (deflateStateCheck(source) || dest == Z_NULL) {
|
||||
@@ -1133,8 +1169,7 @@ int ZEXPORT deflateCopy (dest, source)
|
||||
ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
|
||||
ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos));
|
||||
ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos));
|
||||
- overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2);
|
||||
- ds->pending_buf = (uchf *) overlay;
|
||||
+ ds->pending_buf = (uchf *) ZALLOC(dest, ds->lit_bufsize, 4);
|
||||
|
||||
if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
|
||||
ds->pending_buf == Z_NULL) {
|
||||
@@ -1148,8 +1183,7 @@ int ZEXPORT deflateCopy (dest, source)
|
||||
zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
|
||||
|
||||
ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
|
||||
- ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush);
|
||||
- ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize;
|
||||
+ ds->sym_buf = ds->pending_buf + ds->lit_bufsize;
|
||||
|
||||
ds->l_desc.dyn_tree = ds->dyn_ltree;
|
||||
ds->d_desc.dyn_tree = ds->dyn_dtree;
|
||||
@@ -1925,7 +1959,7 @@ local block_state deflate_fast(s, flush)
|
||||
FLUSH_BLOCK(s, 1);
|
||||
return finish_done;
|
||||
}
|
||||
- if (s->last_lit)
|
||||
+ if (s->sym_next)
|
||||
FLUSH_BLOCK(s, 0);
|
||||
return block_done;
|
||||
}
|
||||
@@ -2056,7 +2090,7 @@ local block_state deflate_slow(s, flush)
|
||||
FLUSH_BLOCK(s, 1);
|
||||
return finish_done;
|
||||
}
|
||||
- if (s->last_lit)
|
||||
+ if (s->sym_next)
|
||||
FLUSH_BLOCK(s, 0);
|
||||
return block_done;
|
||||
}
|
||||
@@ -2131,7 +2165,7 @@ local block_state deflate_rle(s, flush)
|
||||
FLUSH_BLOCK(s, 1);
|
||||
return finish_done;
|
||||
}
|
||||
- if (s->last_lit)
|
||||
+ if (s->sym_next)
|
||||
FLUSH_BLOCK(s, 0);
|
||||
return block_done;
|
||||
}
|
||||
@@ -2170,7 +2204,7 @@ local block_state deflate_huff(s, flush)
|
||||
FLUSH_BLOCK(s, 1);
|
||||
return finish_done;
|
||||
}
|
||||
- if (s->last_lit)
|
||||
+ if (s->sym_next)
|
||||
FLUSH_BLOCK(s, 0);
|
||||
return block_done;
|
||||
}
|
||||
diff --git a/deflate.h b/deflate.h
|
||||
index 23ecdd312..d4cf1a98b 100644
|
||||
--- a/deflate.h
|
||||
+++ b/deflate.h
|
||||
@@ -217,7 +217,7 @@ typedef struct internal_state {
|
||||
/* Depth of each subtree used as tie breaker for trees of equal frequency
|
||||
*/
|
||||
|
||||
- uchf *l_buf; /* buffer for literals or lengths */
|
||||
+ uchf *sym_buf; /* buffer for distances and literals/lengths */
|
||||
|
||||
uInt lit_bufsize;
|
||||
/* Size of match buffer for literals/lengths. There are 4 reasons for
|
||||
@@ -239,13 +239,8 @@ typedef struct internal_state {
|
||||
* - I can't count above 4
|
||||
*/
|
||||
|
||||
- uInt last_lit; /* running index in l_buf */
|
||||
-
|
||||
- ushf *d_buf;
|
||||
- /* Buffer for distances. To simplify the code, d_buf and l_buf have
|
||||
- * the same number of elements. To use different lengths, an extra flag
|
||||
- * array would be necessary.
|
||||
- */
|
||||
+ uInt sym_next; /* running index in sym_buf */
|
||||
+ uInt sym_end; /* symbol table full when sym_next reaches this */
|
||||
|
||||
ulg opt_len; /* bit length of current block with optimal trees */
|
||||
ulg static_len; /* bit length of current block with static trees */
|
||||
@@ -325,20 +320,22 @@ void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf,
|
||||
|
||||
# define _tr_tally_lit(s, c, flush) \
|
||||
{ uch cc = (c); \
|
||||
- s->d_buf[s->last_lit] = 0; \
|
||||
- s->l_buf[s->last_lit++] = cc; \
|
||||
+ s->sym_buf[s->sym_next++] = 0; \
|
||||
+ s->sym_buf[s->sym_next++] = 0; \
|
||||
+ s->sym_buf[s->sym_next++] = cc; \
|
||||
s->dyn_ltree[cc].Freq++; \
|
||||
- flush = (s->last_lit == s->lit_bufsize-1); \
|
||||
+ flush = (s->sym_next == s->sym_end); \
|
||||
}
|
||||
# define _tr_tally_dist(s, distance, length, flush) \
|
||||
{ uch len = (uch)(length); \
|
||||
ush dist = (ush)(distance); \
|
||||
- s->d_buf[s->last_lit] = dist; \
|
||||
- s->l_buf[s->last_lit++] = len; \
|
||||
+ s->sym_buf[s->sym_next++] = dist; \
|
||||
+ s->sym_buf[s->sym_next++] = dist >> 8; \
|
||||
+ s->sym_buf[s->sym_next++] = len; \
|
||||
dist--; \
|
||||
s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
|
||||
s->dyn_dtree[d_code(dist)].Freq++; \
|
||||
- flush = (s->last_lit == s->lit_bufsize-1); \
|
||||
+ flush = (s->sym_next == s->sym_end); \
|
||||
}
|
||||
#else
|
||||
# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
|
||||
diff --git a/trees.c b/trees.c
|
||||
index 4f4a65011..decaeb7c3 100644
|
||||
--- a/trees.c
|
||||
+++ b/trees.c
|
||||
@@ -416,7 +416,7 @@ local void init_block(s)
|
||||
|
||||
s->dyn_ltree[END_BLOCK].Freq = 1;
|
||||
s->opt_len = s->static_len = 0L;
|
||||
- s->last_lit = s->matches = 0;
|
||||
+ s->sym_next = s->matches = 0;
|
||||
}
|
||||
|
||||
#define SMALLEST 1
|
||||
@@ -948,7 +948,7 @@ void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last)
|
||||
|
||||
Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
|
||||
opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
|
||||
- s->last_lit));
|
||||
+ s->sym_next / 3));
|
||||
|
||||
if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
|
||||
|
||||
@@ -1017,8 +1017,9 @@ int ZLIB_INTERNAL _tr_tally (s, dist, lc)
|
||||
unsigned dist; /* distance of matched string */
|
||||
unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */
|
||||
{
|
||||
- s->d_buf[s->last_lit] = (ush)dist;
|
||||
- s->l_buf[s->last_lit++] = (uch)lc;
|
||||
+ s->sym_buf[s->sym_next++] = dist;
|
||||
+ s->sym_buf[s->sym_next++] = dist >> 8;
|
||||
+ s->sym_buf[s->sym_next++] = lc;
|
||||
if (dist == 0) {
|
||||
/* lc is the unmatched char */
|
||||
s->dyn_ltree[lc].Freq++;
|
||||
@@ -1033,30 +1034,7 @@ int ZLIB_INTERNAL _tr_tally (s, dist, lc)
|
||||
s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++;
|
||||
s->dyn_dtree[d_code(dist)].Freq++;
|
||||
}
|
||||
-
|
||||
-#ifdef TRUNCATE_BLOCK
|
||||
- /* Try to guess if it is profitable to stop the current block here */
|
||||
- if ((s->last_lit & 0x1fff) == 0 && s->level > 2) {
|
||||
- /* Compute an upper bound for the compressed length */
|
||||
- ulg out_length = (ulg)s->last_lit*8L;
|
||||
- ulg in_length = (ulg)((long)s->strstart - s->block_start);
|
||||
- int dcode;
|
||||
- for (dcode = 0; dcode < D_CODES; dcode++) {
|
||||
- out_length += (ulg)s->dyn_dtree[dcode].Freq *
|
||||
- (5L+extra_dbits[dcode]);
|
||||
- }
|
||||
- out_length >>= 3;
|
||||
- Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
|
||||
- s->last_lit, in_length, out_length,
|
||||
- 100L - out_length*100L/in_length));
|
||||
- if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1;
|
||||
- }
|
||||
-#endif
|
||||
- return (s->last_lit == s->lit_bufsize-1);
|
||||
- /* We avoid equality with lit_bufsize because of wraparound at 64K
|
||||
- * on 16 bit machines and because stored blocks are restricted to
|
||||
- * 64K-1 bytes.
|
||||
- */
|
||||
+ return (s->sym_next == s->sym_end);
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
@@ -1069,13 +1047,14 @@ local void compress_block(s, ltree, dtree)
|
||||
{
|
||||
unsigned dist; /* distance of matched string */
|
||||
int lc; /* match length or unmatched char (if dist == 0) */
|
||||
- unsigned lx = 0; /* running index in l_buf */
|
||||
+ unsigned sx = 0; /* running index in sym_buf */
|
||||
unsigned code; /* the code to send */
|
||||
int extra; /* number of extra bits to send */
|
||||
|
||||
- if (s->last_lit != 0) do {
|
||||
- dist = s->d_buf[lx];
|
||||
- lc = s->l_buf[lx++];
|
||||
+ if (s->sym_next != 0) do {
|
||||
+ dist = s->sym_buf[sx++] & 0xff;
|
||||
+ dist += (unsigned)(s->sym_buf[sx++] & 0xff) << 8;
|
||||
+ lc = s->sym_buf[sx++];
|
||||
if (dist == 0) {
|
||||
send_code(s, lc, ltree); /* send a literal byte */
|
||||
Tracecv(isgraph(lc), (stderr," '%c' ", lc));
|
||||
@@ -1100,11 +1079,10 @@ local void compress_block(s, ltree, dtree)
|
||||
}
|
||||
} /* literal or match pair ? */
|
||||
|
||||
- /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
|
||||
- Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx,
|
||||
- "pendingBuf overflow");
|
||||
+ /* Check that the overlay between pending_buf and sym_buf is ok: */
|
||||
+ Assert(s->pending < s->lit_bufsize + sx, "pendingBuf overflow");
|
||||
|
||||
- } while (lx < s->last_lit);
|
||||
+ } while (sx < s->sym_next);
|
||||
|
||||
send_code(s, END_BLOCK, ltree);
|
||||
}
|
||||
Reference in New Issue
Block a user