diff --git a/include/autotools.mk b/include/autotools.mk index 0f0d608b26..e9a7a82248 100644 --- a/include/autotools.mk +++ b/include/autotools.mk @@ -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; \ diff --git a/package/boot/grub2/Makefile b/package/boot/grub2/Makefile index 9c67ff589b..f78b1c895e 100644 --- a/package/boot/grub2/Makefile +++ b/package/boot/grub2/Makefile @@ -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 diff --git a/package/devel/gdb/patches/010-aarch64-headers.patch b/package/devel/gdb/patches/010-aarch64-headers.patch new file mode 100644 index 0000000000..676b012206 --- /dev/null +++ b/package/devel/gdb/patches/010-aarch64-headers.patch @@ -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 + #include + +-#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) */ + diff --git a/package/libs/argp-standalone/Makefile b/package/libs/argp-standalone/Makefile index f431aacbdc..1a48dcb2cd 100644 --- a/package/libs/argp-standalone/Makefile +++ b/package/libs/argp-standalone/Makefile @@ -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)) diff --git a/package/libs/toolchain/Makefile b/package/libs/toolchain/Makefile index 52a4cda19f..424fadaaef 100644 --- a/package/libs/toolchain/Makefile +++ b/package/libs/toolchain/Makefile @@ -7,7 +7,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=toolchain -PKG_RELEASE:=3 +PKG_RELEASE:=4 PKG_MAINTAINER:=Felix Fietkau 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 diff --git a/package/libs/zlib/Makefile b/package/libs/zlib/Makefile index 7321ec51c5..8512394ff4 100644 --- a/package/libs/zlib/Makefile +++ b/package/libs/zlib/Makefile @@ -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 diff --git a/package/libs/zlib/patches/001-neon-implementation-of-adler32.patch b/package/libs/zlib/patches/001-neon-implementation-of-adler32.patch index 843ef45c7d..c5517299d7 100644 --- a/package/libs/zlib/patches/001-neon-implementation-of-adler32.patch +++ b/package/libs/zlib/patches/001-neon-implementation-of-adler32.patch @@ -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 - 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 + ARM optimizations (NEON and ARMv8 code). + - asm686/ by Brian Raiter - 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 + Decompressor for output of PKWare Data Compression Library (DCL) + --- /dev/null +++ b/contrib/arm/neon_adler32.c @@ -0,0 +1,137 @@ diff --git a/package/libs/zlib/patches/006-fix-compressor-crash-on-certain-inputs.patch b/package/libs/zlib/patches/006-fix-compressor-crash-on-certain-inputs.patch deleted file mode 100644 index 9f37ba5c58..0000000000 --- a/package/libs/zlib/patches/006-fix-compressor-crash-on-certain-inputs.patch +++ /dev/null @@ -1,343 +0,0 @@ -From 5c44459c3b28a9bd3283aaceab7c615f8020c531 Mon Sep 17 00:00:00 2001 -From: Mark Adler -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); - } diff --git a/package/network/config/firewall/Makefile b/package/network/config/firewall/Makefile index d7bb91b6ad..57f0abd797 100644 --- a/package/network/config/firewall/Makefile +++ b/package/network/config/firewall/Makefile @@ -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 diff --git a/package/network/config/firewall/files/firewall.config b/package/network/config/firewall/files/firewall.config index 8d9462f25b..994d71a21e 100644 --- a/package/network/config/firewall/files/firewall.config +++ b/package/network/config/firewall/files/firewall.config @@ -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 diff --git a/package/network/config/firewall/patches/fullconenat.patch b/package/network/config/firewall/patches/0100-fullconenat.patch similarity index 76% rename from package/network/config/firewall/patches/fullconenat.patch rename to package/network/config/firewall/patches/0100-fullconenat.patch index d69e7129ec..28f5925647 100644 --- a/package/network/config/firewall/patches/fullconenat.patch +++ b/package/network/config/firewall/patches/0100-fullconenat.patch @@ -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); diff --git a/package/kernel/fullconenat/Makefile b/package/network/utils/fullconenat/Makefile similarity index 91% rename from package/kernel/fullconenat/Makefile rename to package/network/utils/fullconenat/Makefile index 6e3fdb17de..7a66000264 100644 --- a/package/kernel/fullconenat/Makefile +++ b/package/network/utils/fullconenat/Makefile @@ -20,6 +20,8 @@ PKG_MIRROR_HASH:=e7bb77d9916d190b3c02975faf62d1794557d4a4a774cd0cf1f3a6ddb7403e3 PKG_LICENSE:=GPL-2.0 PKG_LICENSE_FILES:=LICENSE +PKG_MAINTAINER:=Chion Tang + 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 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 - 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 diff --git a/package/kernel/fullconenat/files/Makefile b/package/network/utils/fullconenat/files/Makefile similarity index 99% rename from package/kernel/fullconenat/files/Makefile rename to package/network/utils/fullconenat/files/Makefile index da52a2a4ed..b2f88db33f 100644 --- a/package/kernel/fullconenat/files/Makefile +++ b/package/network/utils/fullconenat/files/Makefile @@ -4,4 +4,3 @@ libipt_FULLCONENAT.o: libipt_FULLCONENAT.c $(CC) ${CFLAGS} -fPIC -D_INIT=$*_init -c -o $@ $<; obj-m += xt_FULLCONENAT.o - diff --git a/package/kernel/fullconenat/patches/000-printk.patch b/package/network/utils/fullconenat/patches/000-printk.patch similarity index 100% rename from package/kernel/fullconenat/patches/000-printk.patch rename to package/network/utils/fullconenat/patches/000-printk.patch diff --git a/package/system/urandom-seed/Makefile b/package/system/urandom-seed/Makefile index 7c5524a9db..0c8d77f445 100644 --- a/package/system/urandom-seed/Makefile +++ b/package/system/urandom-seed/Makefile @@ -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)) diff --git a/package/system/urandom-seed/files/etc/init.d/urandom_seed b/package/system/urandom-seed/files/etc/init.d/urandom_seed index 17d9c13400..d6e81c6079 100755 --- a/package/system/urandom-seed/files/etc/init.d/urandom_seed +++ b/package/system/urandom-seed/files/etc/init.d/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 diff --git a/package/system/urandom-seed/files/lib/preinit/81_urandom_seed b/package/system/urandom-seed/files/lib/preinit/81_urandom_seed index 2adc6c47f0..b3014daeaf 100644 --- a/package/system/urandom-seed/files/lib/preinit/81_urandom_seed +++ b/package/system/urandom-seed/files/lib/preinit/81_urandom_seed @@ -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 diff --git a/package/system/urandom-seed/files/sbin/urandom_seed b/package/system/urandom-seed/files/sbin/urandom_seed deleted file mode 100755 index 7043e8af4e..0000000000 --- a/package/system/urandom-seed/files/sbin/urandom_seed +++ /dev/null @@ -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 diff --git a/package/system/urandom-seed/seedrng.c b/package/system/urandom-seed/seedrng.c new file mode 100644 index 0000000000..276affa53e --- /dev/null +++ b/package/system/urandom-seed/seedrng.c @@ -0,0 +1,438 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT OR Apache-2.0) +/* + * Copyright (C) 2022 Jason A. Donenfeld . All Rights Reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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; +} diff --git a/package/utils/busybox/patches/220-add_lock_util.patch b/package/utils/busybox/patches/220-add_lock_util.patch index 4e46b74f0e..579b705f34 100644 --- a/package/utils/busybox/patches/220-add_lock_util.patch +++ b/package/utils/busybox/patches/220-add_lock_util.patch @@ -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); + } diff --git a/scripts/ipkg-build b/scripts/ipkg-build index c112270a2b..32bc4b6d50 100755 --- a/scripts/ipkg-build +++ b/scripts/ipkg-build @@ -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 diff --git a/target/linux/ipq806x/config-5.10 b/target/linux/ipq806x/config-5.10 index 01ef88f0e9..1ad6842241 100644 --- a/target/linux/ipq806x/config-5.10 +++ b/target/linux/ipq806x/config-5.10 @@ -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 diff --git a/target/linux/ipq806x/config-5.4 b/target/linux/ipq806x/config-5.4 index 41e15c4eb1..0317e7cf50 100644 --- a/target/linux/ipq806x/config-5.4 +++ b/target/linux/ipq806x/config-5.4 @@ -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 diff --git a/target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8064-rg-mtfi-m520.dts b/target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8064-rg-mtfi-m520.dts index 8d2e35ec7d..32ebba2dd4 100644 --- a/target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8064-rg-mtfi-m520.dts +++ b/target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8064-rg-mtfi-m520.dts @@ -47,6 +47,16 @@ linux,code = ; }; }; + + 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 { diff --git a/tools/dosfstools/patches/source-date-epoch.patch b/tools/dosfstools/patches/source-date-epoch.patch new file mode 100644 index 0000000000..fb46753f24 --- /dev/null +++ b/tools/dosfstools/patches/source-date-epoch.patch @@ -0,0 +1,157 @@ +From 8da7bc93315cb0c32ad868f17808468b81fa76ec Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bj=C3=B8rn=20Forsman?= +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 +--- + 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 + #include + #include ++#include ++#include + + #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 + #include + #include ++#include + #include + #include + #include +@@ -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(); + \ No newline at end of file diff --git a/tools/zlib/Makefile b/tools/zlib/Makefile index c83cc6d55b..58315b8083 100644 --- a/tools/zlib/Makefile +++ b/tools/zlib/Makefile @@ -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 diff --git a/tools/zlib/patches/006-fix-compressor-crash-on-certain-inputs.patch b/tools/zlib/patches/006-fix-compressor-crash-on-certain-inputs.patch deleted file mode 100644 index 9f37ba5c58..0000000000 --- a/tools/zlib/patches/006-fix-compressor-crash-on-certain-inputs.patch +++ /dev/null @@ -1,343 +0,0 @@ -From 5c44459c3b28a9bd3283aaceab7c615f8020c531 Mon Sep 17 00:00:00 2001 -From: Mark Adler -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); - }