From 6bafcc9e5abf5cb3ea17bd78dd17ff21eabc2c67 Mon Sep 17 00:00:00 2001 From: eaglegai Date: Fri, 15 Jan 2021 15:38:58 +0800 Subject: [PATCH] use libtdb instead of libdb --- squid-add-TrivialDB-support-223.patch | 555 ++++++++++++++++++++++++++ squid.spec | 18 +- 2 files changed, 568 insertions(+), 5 deletions(-) create mode 100644 squid-add-TrivialDB-support-223.patch diff --git a/squid-add-TrivialDB-support-223.patch b/squid-add-TrivialDB-support-223.patch new file mode 100644 index 0000000..470c872 --- /dev/null +++ b/squid-add-TrivialDB-support-223.patch @@ -0,0 +1,555 @@ +From acd207af1bf340df75a64e8bc4d1e93caa13bbb2 Mon Sep 17 00:00:00 2001 +From: Amos Jeffries +Date: Tue, 17 Jul 2018 23:36:31 +0000 +Subject: [PATCH] TrivialDB support (#223) + +Allow use of Samba TrivialDB instead of outdated BerkleyDB in +the session helper. + +Require TrivialDB support for use of the time_quota helper. +libdb v1.85 is no longer supported by distributors and +upgrading to v5 only to deprecate use does not seem to be +worthwhile. +--- + acinclude/tdb.m4 | 49 ++++++++ + configure.ac | 1 + + src/acl/external/session/Makefile.am | 3 +- + src/acl/external/session/ext_session_acl.cc | 143 ++++++++++++++++++---- + src/acl/external/session/required.m4 | 26 ++-- + src/acl/external/time_quota/Makefile.am | 2 +- + src/acl/external/time_quota/ext_time_quota_acl.cc | 93 +++++++------- + src/acl/external/time_quota/required.m4 | 13 +- + test-suite/buildtests/layer-01-minimal.opts | 1 + + test-suite/buildtests/layer-02-maximus.opts | 1 + + 11 files changed, 253 insertions(+), 86 deletions(-) + create mode 100644 acinclude/tdb.m4 + +diff --git a/acinclude/tdb.m4 b/acinclude/tdb.m4 +new file mode 100644 +index 0000000..20b2b2a +--- /dev/null ++++ b/acinclude/tdb.m4 +@@ -0,0 +1,49 @@ ++## Copyright (C) 1996-2018 The Squid Software Foundation and contributors ++## ++## Squid software is distributed under GPLv2+ license and includes ++## contributions from numerous individuals and organizations. ++## Please see the COPYING and CONTRIBUTORS files for details. ++## ++ ++dnl check for --with-tdb option ++AC_DEFUN([SQUID_CHECK_LIBTDB],[ ++AC_ARG_WITH(tdb, ++ AS_HELP_STRING([--without-tdb], ++ [Do not use Samba TrivialDB. Default: auto-detect]), [ ++case "$with_tdb" in ++ yes|no|auto) ++ : # Nothing special to do here ++ ;; ++ *) ++ AS_IF([test ! -d "$withval"], ++ AC_MSG_ERROR([--with-tdb path ($with_tdb) does not point to a directory]) ++ ) ++ LIBTDB_PATH="-L$withval/lib" ++ CPPFLAGS="-I$withval/include $CPPFLAGS" ++ ;; ++esac ++]) ++AH_TEMPLATE(USE_TRIVIALDB,[Samba TrivialDB support is available]) ++AS_IF([test "x$with_tdb" != "xno"],[ ++ SQUID_STATE_SAVE(squid_libtdb_state) ++ LIBS="$LIBS $LIBTDB_PATH" ++ PKG_CHECK_MODULES([LIBTDB],[tdb],[CPPFLAGS="$CPPFLAGS $LIBTDB_CFLAGS"],[:]) ++ AC_CHECK_HEADERS([sys/stat.h tdb.h],,,[ ++#if HAVE_SYS_STAT_H ++#include ++#endif ++ ]) ++ SQUID_STATE_ROLLBACK(squid_libtdb_state) #de-pollute LIBS ++ ++ AS_IF([test "x$with_tdb" = "xyes" -a "x$LIBTDB_LIBS" = "x"], ++ AC_MSG_ERROR([Required TrivialDB library not found]) ++ ) ++ AS_IF([test "x$LIBTDB_LIBS" != "x"],[ ++ CXXFLAGS="$LIBTDB_CFLAGS $CXXFLAGS" ++ LIBTDB_LIBS="$LIBTDB_PATH $LIBTDB_LIBS" ++ AC_DEFINE_UNQUOTED(USE_TRIVIALDB, HAVE_TDB_H, [Samba TrivialDB support is available]) ++ ],[with_tdb=no]) ++]) ++AC_MSG_NOTICE([Samba TrivialDB library support: ${with_tdb:=auto} ${LIBTDB_PATH} ${LIBTDB_LIBS}]) ++AC_SUBST(LIBTDB_LIBS) ++]) +diff --git a/configure.ac b/configure.ac +index 1ec245a..c8cd996 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -23,6 +23,7 @@ m4_include([acinclude/os-deps.m4]) + m4_include([acinclude/krb5.m4]) + m4_include([acinclude/pam.m4]) + m4_include([acinclude/pkg.m4]) ++m4_include([acinclude/tdb.m4]) + m4_include([acinclude/lib-checks.m4]) + m4_include([acinclude/ax_cxx_compile_stdcxx_11.m4]) + m4_include([acinclude/ax_cxx_0x_types.m4]) +diff --git a/src/acl/external/session/Makefile.am b/src/acl/external/session/Makefile.am +index e54f22b..7509848 100644 +--- a/src/acl/external/session/Makefile.am ++++ b/src/acl/external/session/Makefile.am +@@ -14,6 +14,7 @@ ext_session_acl_SOURCES= \ + ext_session_acl.cc + ext_session_acl_LDADD = \ + $(COMPAT_LIB) \ +- -ldb ++ $(LIBBDB_LIBS) \ ++ $(LIBTDB_LIBS) + + EXTRA_DIST= ext_session_acl.8 required.m4 +diff --git a/src/acl/external/session/ext_session_acl.cc b/src/acl/external/session/ext_session_acl.cc +index 09a35ca..64ffb60 100644 +--- a/src/acl/external/session/ext_session_acl.cc ++++ b/src/acl/external/session/ext_session_acl.cc +@@ -43,6 +43,9 @@ + #endif + #include + #include ++#if HAVE_TDB_H ++#include ++#endif + #if HAVE_UNISTD_H + #include + #endif +@@ -60,8 +63,36 @@ static int fixed_timeout = 0; + char *db_path = NULL; + const char *program_name; + ++#if USE_BERKLEYDB + DB *db = NULL; + DB_ENV *db_env = NULL; ++typedef DBT DB_ENTRY; ++ ++#elif USE_TRIVIALDB ++TDB_CONTEXT *db = nullptr; ++typedef TDB_DATA DB_ENTRY; ++ ++#endif ++ ++static void ++shutdown_db() ++{ ++ if (db) { ++#if USE_BERKLEYDB ++ db->close(db, 0); ++ } ++ if (db_env) { ++ db_env->close(db_env, 0); ++ ++#elif USE_TRIVIALDB ++ if (tdb_close(db) != 0) { ++ fprintf(stderr, "%s| WARNING: error closing session db '%s'\n", program_name, db_path); ++ exit(1); ++ } ++#endif ++ } ++ xfree(db_path); ++} + + static void init_db(void) + { +@@ -70,6 +101,7 @@ static void init_db(void) + if (db_path) { + if (!stat(db_path, &st_buf)) { + if (S_ISDIR (st_buf.st_mode)) { ++#if USE_BERKLEYDB + /* If directory then open database environment. This prevents sync problems + between different processes. Otherwise fallback to single file */ + db_env_create(&db_env, 0); +@@ -79,10 +111,16 @@ static void init_db(void) + exit(1); + } + db_create(&db, db_env, 0); ++#elif USE_TRIVIALDB ++ std::string newPath(db_path); ++ newPath.append("session", 7); ++ db_path = xstrdup(newPath.c_str()); ++#endif + } + } + } + ++#if USE_BERKLEYDB + if (db_env) { + if (db->open(db, NULL, "session", NULL, DB_BTREE, DB_CREATE, 0666)) { + fprintf(stderr, "FATAL: %s: Failed to open db file '%s' in dir '%s'\n", +@@ -93,60 +131,121 @@ static void init_db(void) + } else { + db_create(&db, NULL, 0); + if (db->open(db, NULL, db_path, NULL, DB_BTREE, DB_CREATE, 0666)) { +- fprintf(stderr, "FATAL: %s: Failed to open session db '%s'\n", program_name, db_path); +- exit(1); ++ db = nullptr; + } + } ++#elif USE_TRIVIALDB ++ db = tdb_open(db_path, 0, TDB_CLEAR_IF_FIRST, O_CREAT|O_DSYNC, 0666); ++#endif ++ if (!db) { ++ fprintf(stderr, "FATAL: %s: Failed to open session db '%s'\n", program_name, db_path); ++ shutdown_db(); ++ exit(1); ++ } + } + +-static void shutdown_db(void) ++int session_is_active = 0; ++ ++static size_t ++dataSize(DB_ENTRY *data) + { +- db->close(db, 0); +- if (db_env) { +- db_env->close(db_env, 0); +- } ++#if USE_BERKLEYDB ++ return data->size; ++#elif USE_TRIVIALDB ++ return data->dsize; ++#endif + } + +-int session_is_active = 0; ++static bool ++fetchKey(/*const*/ DB_ENTRY &key, DB_ENTRY *data) ++{ ++#if USE_BERKLEYDB ++ return (db->get(db, nullptr, &key, data, 0) == 0); ++#elif USE_TRIVIALDB ++ // NP: API says returns NULL on errors, but return is a struct type WTF?? ++ *data = tdb_fetch(db, key); ++ return (data->dptr != nullptr); ++#endif ++} ++ ++static void ++deleteEntry(/*const*/ DB_ENTRY &key) ++{ ++#if USE_BERKLEYDB ++ db->del(db, nullptr, &key, 0); ++#elif USE_TRIVIALDB ++ tdb_delete(db, key); ++#endif ++} ++ ++static void ++copyValue(void *dst, const DB_ENTRY *src, size_t sz) ++{ ++#if USE_BERKLEYDB ++ memcpy(dst, src->data, sz); ++#elif USE_TRIVIALDB ++ memcpy(dst, src->dptr, sz); ++#endif ++} + + static int session_active(const char *details, size_t len) + { ++#if USE_BERKLEYDB + DBT key = {0}; + DBT data = {0}; + key.data = (void *)details; + key.size = len; +- if (db->get(db, NULL, &key, &data, 0) == 0) { ++#elif USE_TRIVIALDB ++ TDB_DATA key; ++ TDB_DATA data; ++#endif ++ if (fetchKey(key, &data)) { + time_t timestamp; +- if (data.size != sizeof(timestamp)) { ++ if (dataSize(&data) != sizeof(timestamp)) { + fprintf(stderr, "ERROR: %s: CORRUPTED DATABASE (%s)\n", program_name, details); +- db->del(db, NULL, &key, 0); ++ deleteEntry(key); + return 0; + } +- memcpy(×tamp, data.data, sizeof(timestamp)); ++ copyValue(×tamp, &data, sizeof(timestamp)); + if (timestamp + session_ttl >= time(NULL)) + return 1; + } + return 0; + } + +-static void session_login(const char *details, size_t len) ++static void ++session_login(/*const*/ char *details, size_t len) + { +- DBT key = {0}; +- DBT data = {0}; +- key.data = (void *)details; ++ DB_ENTRY key = {0}; ++ DB_ENTRY data = {0}; ++ time_t now = time(0); ++#if USE_BERKLEYDB ++ key.data = static_cast(details); + key.size = len; +- time_t now = time(NULL); + data.data = &now; + data.size = sizeof(now); + db->put(db, NULL, &key, &data, 0); ++#elif USE_TRIVIALDB ++ key.dptr = reinterpret_cast(details); ++ key.dsize = len; ++ data.dptr = reinterpret_cast(&now); ++ data.dsize = sizeof(now); ++ tdb_store(db, key, data, 0); ++#endif + } + +-static void session_logout(const char *details, size_t len) ++static void ++session_logout(/*const*/ char *details, size_t len) + { +- DBT key = {0}; +- key.data = (void *)details; ++ DB_ENTRY key = {0}; ++#if USE_BERKLEYDB ++ key.data = static_cast(details); + key.size = len; +- db->del(db, NULL, &key, 0); ++#elif USE_TRIVIALDB ++ key.dptr = reinterpret_cast(details); ++ key.dsize = len; ++#endif ++ deleteEntry(key); + } + + static void usage(void) +@@ -173,7 +272,7 @@ int main(int argc, char **argv) + session_ttl = strtol(optarg, NULL, 0); + break; + case 'b': +- db_path = optarg; ++ db_path = xstrdup(optarg); + break; + case 'a': + default_action = 0; +diff --git a/src/acl/external/session/required.m4 b/src/acl/external/session/required.m4 +index 229774b..1fe8a0e 100755 +--- a/src/acl/external/session/required.m4 ++++ b/src/acl/external/session/required.m4 +@@ -5,11 +5,23 @@ + ## Please see the COPYING and CONTRIBUTORS files for details. + ## + +-AC_CHECK_HEADERS(db.h,[ +- AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]],[[ +- DB_ENV *db_env = nullptr; +- db_env_create(&db_env, 0); +- ]])],[ ++SQUID_CHECK_LIBTDB ++if test "$with_tdb" != "no"; then + BUILD_HELPER="session" +- ],[]) +-]) ++fi ++ ++LIBBDB_LIBS= ++AH_TEMPLATE(USE_BERKLEYDB,[BerkleyDB support is available]) ++if test "x$with_tdb" = "xno"; then ++ AC_CHECK_HEADERS(db.h,[ ++ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]],[[ ++ DB_ENV *db_env = nullptr; ++ db_env_create(&db_env, 0); ++ ]])],[ ++ AC_DEFINE_UNQUOTED(USE_BERKLEYDB, HAVE_DB_H, [BerkleyDB support is available]) ++ BUILD_HELPER="session" ++ LIBBDB_LIBS="-ldb" ++ ],[]) ++ ]) ++fi ++AC_SUBST(LIBBDB_LIBS) +diff --git a/src/acl/external/time_quota/Makefile.am b/src/acl/external/time_quota/Makefile.am +index 4684637..20eba22 100644 +--- a/src/acl/external/time_quota/Makefile.am ++++ b/src/acl/external/time_quota/Makefile.am +@@ -16,6 +16,6 @@ ext_time_quota_acl_SOURCES= \ + ext_time_quota_acl.cc + ext_time_quota_acl_LDADD = \ + $(COMPAT_LIB) \ +- -ldb ++ $(LIBTDB_LIBS) + + EXTRA_DIST= ext_time_quota_acl.8 required.m4 +diff --git a/src/acl/external/time_quota/ext_time_quota_acl.cc b/src/acl/external/time_quota/ext_time_quota_acl.cc +index 764fa86..8f1bbef 100644 +--- a/src/acl/external/time_quota/ext_time_quota_acl.cc ++++ b/src/acl/external/time_quota/ext_time_quota_acl.cc +@@ -41,19 +41,8 @@ + #if HAVE_GETOPT_H + #include + #endif +- +-/* At this point all Bit Types are already defined, so we must +- protect from multiple type definition on platform where +- __BIT_TYPES_DEFINED__ is not defined. +- */ +-#ifndef __BIT_TYPES_DEFINED__ +-#define __BIT_TYPES_DEFINED__ +-#endif +- +-#if HAVE_DB_185_H +-#include +-#elif HAVE_DB_H +-#include ++#if HAVE_TDB_H ++#include + #endif + + #ifndef DEFAULT_QUOTA_DB +@@ -63,7 +52,7 @@ + const char *db_path = DEFAULT_QUOTA_DB; + const char *program_name; + +-DB *db = NULL; ++TDB_CONTEXT *db = nullptr; + + #define KEY_LAST_ACTIVITY "last-activity" + #define KEY_PERIOD_START "period-start" +@@ -147,7 +136,7 @@ static void log_fatal(const char *format, ...) + static void init_db(void) + { + log_info("opening time quota database \"%s\".\n", db_path); +- db = dbopen(db_path, O_CREAT | O_RDWR, 0666, DB_BTREE, NULL); ++ db = tdb_open(db_path, 0, TDB_CLEAR_IF_FIRST, O_CREAT | O_RDWR, 0666); + if (!db) { + log_fatal("Failed to open time_quota db '%s'\n", db_path); + exit(1); +@@ -156,52 +145,68 @@ static void init_db(void) + + static void shutdown_db(void) + { +- db->close(db); ++ tdb_close(db); + } + +-static void writeTime(const char *user_key, const char *sub_key, time_t t) ++static char *KeyString(int &len, const char *user_key, const char *sub_key) + { +- char keybuffer[TQ_BUFFERSIZE]; +- DBT key, data; ++ static char keybuffer[TQ_BUFFERSIZE]; ++ *keybuffer = 0; ++ ++ len = snprintf(keybuffer, sizeof(keybuffer), "%s-%s", user_key, sub_key); ++ if (len < 0) { ++ log_error("Cannot add entry: %s-%s", user_key, sub_key); ++ len = 0; + +- if ( strlen(user_key) + strlen(sub_key) + 1 + 1 > sizeof(keybuffer) ) { ++ } else if (static_cast(len) >= sizeof(keybuffer)) { + log_error("key too long (%s,%s)\n", user_key, sub_key); +- } else { +- snprintf(keybuffer, sizeof(keybuffer), "%s-%s", user_key, sub_key); ++ len = 0; ++ } ++ ++ return keybuffer; ++} ++ ++static void writeTime(const char *user_key, const char *sub_key, time_t t) ++{ ++ int len = 0; ++ if (/* const */ char *keybuffer = KeyString(len, user_key, sub_key)) { ++ ++ TDB_DATA key, data; ++ ++ key.dptr = reinterpret_cast(keybuffer); ++ key.dsize = len; + +- key.data = (void *)keybuffer; +- key.size = strlen(keybuffer); +- data.data = &t; +- data.size = sizeof(t); +- db->put(db, &key, &data, 0); ++ data.dptr = reinterpret_cast(&t); ++ data.dsize = sizeof(t); ++ ++ tdb_store(db, key, data, TDB_REPLACE); + log_debug("writeTime(\"%s\", %d)\n", keybuffer, t); + } + } + + static time_t readTime(const char *user_key, const char *sub_key) + { +- char keybuffer[TQ_BUFFERSIZE]; +- DBT key, data; +- time_t t = 0; ++ int len = 0; ++ if (/* const */ char *keybuffer = KeyString(len, user_key, sub_key)) { + +- if ( strlen(user_key) + 1 + strlen(sub_key) + 1 > sizeof(keybuffer) ) { +- log_error("key too long (%s,%s)\n", user_key, sub_key); +- } else { +- snprintf(keybuffer, sizeof(keybuffer), "%s-%s", user_key, sub_key); ++ TDB_DATA key; ++ key.dptr = reinterpret_cast(keybuffer); ++ key.dsize = len; + +- key.data = (void *)keybuffer; +- key.size = strlen(keybuffer); +- if (db->get(db, &key, &data, 0) == 0) { +- if (data.size != sizeof(t)) { +- log_error("CORRUPTED DATABASE (%s)\n", keybuffer); +- } else { +- memcpy(&t, data.data, sizeof(t)); +- } ++ auto data = tdb_fetch(db, key); ++ ++ time_t t = 0; ++ if (data.dsize != sizeof(t)) { ++ log_error("CORRUPTED DATABASE (%s)\n", keybuffer); ++ } else { ++ memcpy(&t, data.dptr, sizeof(t)); + } ++ + log_debug("readTime(\"%s\")=%d\n", keybuffer, t); ++ return t; + } + +- return t; ++ return 0; + } + + static void parseTime(const char *s, time_t *secs, time_t *start) +@@ -388,8 +393,6 @@ static void processActivity(const char *user_key) + log_debug("ERR %s\n", message); + SEND_ERR("Time budget exceeded."); + } +- +- db->sync(db, 0); + } + + static void usage(void) +diff --git a/src/acl/external/time_quota/required.m4 b/src/acl/external/time_quota/required.m4 +index a54daae..c9e52bf 100644 +--- a/src/acl/external/time_quota/required.m4 ++++ b/src/acl/external/time_quota/required.m4 +@@ -5,12 +5,7 @@ + ## Please see the COPYING and CONTRIBUTORS files for details. + ## + +-AC_CHECK_HEADERS(db_185.h,[BUILD_HELPER="time_quota"],[ +- AC_CHECK_HEADERS(db.h,[ +- AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]],[[ +- DB *db = dbopen("/tmp", O_CREAT | O_RDWR, 0666, DB_BTREE, NULL); +- ]])],[ +- BUILD_HELPER="time_quota" +- ],[]) +- ]) +-]) ++SQUID_CHECK_LIBTDB ++if test "$with_tdb" != "no"; then ++ BUILD_HELPER="time_quota" ++fi +-- +1.8.3.1 + diff --git a/squid.spec b/squid.spec index 27a01eb..a574e5d 100644 --- a/squid.spec +++ b/squid.spec @@ -2,7 +2,7 @@ Name: squid Version: 4.9 -Release: 3 +Release: 4 Summary: The Squid proxy caching server Epoch: 7 License: GPLv2+ and (LGPLv2+ and MIT and BSD and Public Domain) @@ -26,6 +26,7 @@ Patch5: CVE-2019-12528.patch Patch6: CVE-2020-8517.patch Patch7: CVE-2020-8449_CVE-2020-8450.patch Patch8: CVE-2019-12519.patch +Patch9: squid-add-TrivialDB-support-223.patch Buildroot: %{_tmppath}/squid-4.9-1-root-%(%{__id_u} -n) Requires: bash >= 2.0 @@ -35,7 +36,7 @@ Requires(preun): /sbin/chkconfig Requires(post): systemd Requires(preun): systemd Requires(postun): systemd -BuildRequires: openldap-devel pam-devel openssl-devel krb5-devel libdb-devel expat-devel +BuildRequires: openldap-devel pam-devel openssl-devel krb5-devel libtdb-devel expat-devel BuildRequires: libxml2-devel libcap-devel libecap-devel gcc-c++ libtool libtool-ltdl-devel BuildRequires: perl-generators pkgconfig(cppunit) autoconf @@ -47,8 +48,8 @@ non-blocking, I/O-driven process and keeps meta data and implements negative cac %autosetup -p1 %build -autoconf - +autoreconf +automake CXXFLAGS="$RPM_OPT_FLAGS -fPIC" CFLAGS="$RPM_OPT_FLAGS -fPIC" LDFLAGS="$RPM_LD_FLAGS -pie -Wl,-z,relro -Wl,-z,now -Wl,--warn-shared-textrel" @@ -75,7 +76,8 @@ LDFLAGS="$RPM_LD_FLAGS -pie -Wl,-z,relro -Wl,-z,now -Wl,--warn-shared-textrel" --enable-storeio="aufs,diskd,ufs,rock" --enable-diskio --enable-wccpv2 \ --enable-esi --enable-ecap --with-aio --with-default-user="squid" \ --with-dl --with-openssl --with-pthreads --disable-arch-native \ - --with-pic --disable-security-cert-validators + --with-pic --disable-security-cert-validators \ + --with-tdb make DEFAULT_SWAP_DIR=%{_localstatedir}/spool/squid %{?_smp_mflags} @@ -204,6 +206,12 @@ fi chgrp squid /var/cache/samba/winbindd_privileged >/dev/null 2>&1 || : %changelog +* Fri Jan 15 2021 gaihuiying - 4.9-4 +- Type:requirement +- ID:NA +- SUG:NA +- DESC:use libtdb instead of libdb + * Mon Jan 11 2021 openEuler Buildteam - 4.9-3 - Type:cves - ID:CVE-2019-12519 -- Gitee