From 1b7d5242c36d82242f1148cc583ea362d3e83577 Mon Sep 17 00:00:00 2001 From: Mark H Weaver Date: Sat, 11 Oct 2014 22:49:15 -0400 Subject: gnu: libarchive: Apply fixes including for CVE-2013-0211. * gnu/packages/patches/libarchive-CVE-2013-0211.patch, gnu/packages/patches/libarchive-fix-lzo-test-case.patch, gnu/packages/patches/libarchive-mtree-filename-length-fix.patch: New files. * gnu-system.am (dist_patch_DATA): Add them. * gnu/packages/backup.scm (libarchive)[source]: Add patches. --- gnu/packages/backup.scm | 6 +- .../patches/libarchive-CVE-2013-0211.patch | 21 ++++++ .../patches/libarchive-fix-lzo-test-case.patch | 83 ++++++++++++++++++++++ .../libarchive-mtree-filename-length-fix.patch | 18 +++++ 4 files changed, 127 insertions(+), 1 deletion(-) create mode 100644 gnu/packages/patches/libarchive-CVE-2013-0211.patch create mode 100644 gnu/packages/patches/libarchive-fix-lzo-test-case.patch create mode 100644 gnu/packages/patches/libarchive-mtree-filename-length-fix.patch (limited to 'gnu/packages') diff --git a/gnu/packages/backup.scm b/gnu/packages/backup.scm index f4f6d0c42c..1aef75e05b 100644 --- a/gnu/packages/backup.scm +++ b/gnu/packages/backup.scm @@ -138,7 +138,11 @@ backups (called chunks) to allow easy burning to CD/DVD.") version ".tar.gz")) (sha256 (base32 - "0pixqnrcf35dnqgv0lp7qlcw7k13620qkhgxr288v7p4iz6ym1zb")))) + "0pixqnrcf35dnqgv0lp7qlcw7k13620qkhgxr288v7p4iz6ym1zb")) + (patches + (list (search-patch "libarchive-mtree-filename-length-fix.patch") + (search-patch "libarchive-fix-lzo-test-case.patch") + (search-patch "libarchive-CVE-2013-0211.patch"))))) (build-system gnu-build-system) (inputs `(("zlib" ,zlib) diff --git a/gnu/packages/patches/libarchive-CVE-2013-0211.patch b/gnu/packages/patches/libarchive-CVE-2013-0211.patch new file mode 100644 index 0000000000..b024a7d4a8 --- /dev/null +++ b/gnu/packages/patches/libarchive-CVE-2013-0211.patch @@ -0,0 +1,21 @@ +Description: Fix CVE-2013-0211: read buffer overflow on 64-bit systems +Origin: upstream +Bug-Debian: http://bugs.debian.org/703957 +Forwarded: not-needed + +--- libarchive-3.0.4.orig/libarchive/archive_write.c ++++ libarchive-3.0.4/libarchive/archive_write.c +@@ -665,8 +665,13 @@ static ssize_t + _archive_write_data(struct archive *_a, const void *buff, size_t s) + { + struct archive_write *a = (struct archive_write *)_a; ++ const size_t max_write = INT_MAX; ++ + archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC, + ARCHIVE_STATE_DATA, "archive_write_data"); ++ /* In particular, this catches attempts to pass negative values. */ ++ if (s > max_write) ++ s = max_write; + archive_clear_error(&a->archive); + return ((a->format_write_data)(a, buff, s)); + } diff --git a/gnu/packages/patches/libarchive-fix-lzo-test-case.patch b/gnu/packages/patches/libarchive-fix-lzo-test-case.patch new file mode 100644 index 0000000000..ffdc0db922 --- /dev/null +++ b/gnu/packages/patches/libarchive-fix-lzo-test-case.patch @@ -0,0 +1,83 @@ +Description: This patch fixes test cases for LZO write support in various + architectures, such as armhf. Writing a certain amount of files would + cause the LZO compressor level 9 to produce a bigger archive than the + default compressor level. +Author: Andres Mejia + +--- a/libarchive/test/test_write_filter_lzop.c ++++ b/libarchive/test/test_write_filter_lzop.c +@@ -39,7 +39,7 @@ + size_t buffsize, datasize; + char path[16]; + size_t used1, used2; +- int i, r, use_prog = 0; ++ int i, r, use_prog = 0, filecount; + + assert((a = archive_write_new()) != NULL); + r = archive_write_add_filter_lzop(a); +@@ -58,9 +58,10 @@ + + datasize = 10000; + assert(NULL != (data = (char *)calloc(1, datasize))); ++ filecount = 10; + + /* +- * Write a 100 files and read them all back. ++ * Write a filecount files and read them all back. + */ + assert((a = archive_write_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); +@@ -77,7 +78,7 @@ + assert((ae = archive_entry_new()) != NULL); + archive_entry_set_filetype(ae, AE_IFREG); + archive_entry_set_size(ae, datasize); +- for (i = 0; i < 100; i++) { ++ for (i = 0; i < filecount; i++) { + sprintf(path, "file%03d", i); + archive_entry_copy_pathname(ae, path); + assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); +@@ -97,7 +98,7 @@ + } else { + assertEqualIntA(a, ARCHIVE_OK, + archive_read_open_memory(a, buff, used1)); +- for (i = 0; i < 100; i++) { ++ for (i = 0; i < filecount; i++) { + sprintf(path, "file%03d", i); + if (!assertEqualInt(ARCHIVE_OK, + archive_read_next_header(a, &ae))) +@@ -133,7 +134,7 @@ + archive_write_set_options(a, "lzop:compression-level=9")); + assertEqualIntA(a, ARCHIVE_OK, + archive_write_open_memory(a, buff, buffsize, &used2)); +- for (i = 0; i < 100; i++) { ++ for (i = 0; i < filecount; i++) { + sprintf(path, "file%03d", i); + assert((ae = archive_entry_new()) != NULL); + archive_entry_copy_pathname(ae, path); +@@ -161,7 +162,7 @@ + archive_read_support_filter_all(a)); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_open_memory(a, buff, used2)); +- for (i = 0; i < 100; i++) { ++ for (i = 0; i < filecount; i++) { + sprintf(path, "file%03d", i); + if (!assertEqualInt(ARCHIVE_OK, + archive_read_next_header(a, &ae))) +@@ -186,7 +187,7 @@ + archive_write_set_filter_option(a, NULL, "compression-level", "1")); + assertEqualIntA(a, ARCHIVE_OK, + archive_write_open_memory(a, buff, buffsize, &used2)); +- for (i = 0; i < 100; i++) { ++ for (i = 0; i < filecount; i++) { + sprintf(path, "file%03d", i); + assert((ae = archive_entry_new()) != NULL); + archive_entry_copy_pathname(ae, path); +@@ -216,7 +217,7 @@ + } else { + assertEqualIntA(a, ARCHIVE_OK, + archive_read_open_memory(a, buff, used2)); +- for (i = 0; i < 100; i++) { ++ for (i = 0; i < filecount; i++) { + sprintf(path, "file%03d", i); + if (!assertEqualInt(ARCHIVE_OK, + archive_read_next_header(a, &ae))) diff --git a/gnu/packages/patches/libarchive-mtree-filename-length-fix.patch b/gnu/packages/patches/libarchive-mtree-filename-length-fix.patch new file mode 100644 index 0000000000..ad94592c05 --- /dev/null +++ b/gnu/packages/patches/libarchive-mtree-filename-length-fix.patch @@ -0,0 +1,18 @@ +Description: Patch to fix filename length calculation when writing mtree archives. +Author: Dave Reisner +Origin: upstream + +--- a/libarchive/archive_write_set_format_mtree.c ++++ b/libarchive/archive_write_set_format_mtree.c +@@ -1855,9 +1855,9 @@ + return (ret); + } + +- /* Make a basename from dirname and slash */ ++ /* Make a basename from file->parentdir.s and slash */ + *slash = '\0'; +- file->parentdir.length = slash - dirname; ++ file->parentdir.length = slash - file->parentdir.s; + archive_strcpy(&(file->basename), slash + 1); + return (ret); + } -- cgit v1.2.3 '#n125'>125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281
#!/bin/sh

# Copyright (C) 2021 Wojtek Kosior
# Redistribution terms are gathered in the `copyright' file.

. ./shell_utils.sh

handle_export_line() {
    if [ "x$1" = "xEXPORTS_START" ]; then
	if [ "$STATE" = "before_block" ]; then
	    STATE="in_block"
	fi
    elif [ "x$1" = "xEXPORT" ]; then
	if [ "$STATE" != "in_block" ]; then
	    return
	fi

	EXPORTCODE="${EXPORTCODE}window.killtheweb.$2 = $2;$ENDL"

	PREVIOUS_FILE="$(map_get EXPORTS $2)"
	if [ "x$PREVIOUS_FILE" != "x" ]; then
	    errcho "export $2 present in both $PREVIOUS_FILE and $FILE"
	    return 1
	fi

	map_set_instr EXPORTS $2 "$FILE"

    elif [ "x$1" = "xEXPORTS_END" ]; then
	if [ "$STATE" = "in_block" ]; then
	    STATE="after_block"
	fi
    fi
}

translate_exports() {
    STATE="before_block"
    EXPORTCODE=''

    while read EXPORT_LINE; do
	handle_export_line $EXPORT_LINE || return 1
    done

    map_set_instr EXPORTCODES $FILEKEY "$EXPORTCODE"
}

add_exports() {
    FILE="$1"
    FILEKEY="$(sanitize "$FILE")"

    eval "$(grep -o 'EXPORT.\+' "$1" | translate_exports || exit 1)"
}

handle_import_line() {
    if [ "x$1" = "xIMPORTS_START" ]; then
	if [ "$STATE" = "before_block" ]; then
	    STATE="in_block"
	fi
    elif [ "x$1" = "xIMPORT" ]; then
	if [ "$STATE" != "in_block" ]; then
	    return
	fi

	IMPORTCODE="${IMPORTCODE}const $2 = window.killtheweb.$2;$ENDL"

	IMPORTS="$IMPORTS $2"

    elif [ "x$1" = "xIMPORTS_END" ]; then
	if [ "$STATE" = "in_block" ]; then
	    STATE="after_block"
	fi
    fi
}

translate_imports() {
    STATE="before_block"
    IMPORTCODE=''
    IMPORTS=''

    while read IMPORT_LINE; do
	handle_import_line $IMPORT_LINE || return 1
    done

    map_set_instr IMPORTCODES $FILEKEY "$IMPORTCODE"
    map_set_instr IMPORTS $FILEKEY "$IMPORTS"
}

add_imports() {
    FILE="$1"
    FILEKEY="$(sanitize "$FILE")"

    eval "$(grep -o 'IMPORT.\+' "$1" | translate_imports || exit 1)"
}

compute_scripts_list_rec() {
    local FILE="$1"
    local FILEKEY=$(sanitize "$1")

    local FILESTATE="$(map_get FILESTATES $FILEKEY)"
    if [ "xprocessed" = "x$FILESTATE" ]; then
	return
    fi
    if [ "xprocessing" = "x$FILESTATE" ]; then
	errcho "import loop on $FILE"
	return 1
    fi

    USED="$USED $FILEKEY"

    map_set FILESTATES $FILEKEY "processing"

    local IMPORT
    for IMPORT in $(map_get IMPORTS $FILEKEY); do
	NEXT_FILE="$(map_get EXPORTS $IMPORT)"
	if [ "x" = "x$NEXT_FILE" ]; then
	    errcho "nothing exports $IMPORT, required by $FILE"
	    return 1
	fi
	if ! compute_scripts_list_rec "$NEXT_FILE"; then
	    errcho "when satisfying $IMPORT for $FILE"
	    return 1
	fi
    done

    [ "x$FILE" = "xexports_init.js" ] || echo $FILE # exports_init.js is hardcoded to load first; the entire export system depends on it
    map_set FILESTATES $FILEKEY "processed"
}

compute_scripts_list() {
    USED=''
    echo COMPUTED_SCRIPTS=\"exports_init.js
    compute_scripts_list_rec "$1"
    echo \"

    for FILEKEY in $USED; do
	map_set_instr USED $FILEKEY yes
    done
}

as_json_list() {
    while true; do
	if [ "x" = "x$2" ]; then
	    echo -n '\\n'"\t\t\"$1\""'\\n\t'
	    return
	fi
	echo -n '\\n'"\t\t\"$1\","
	shift
    done
}

as_html_list() {
    while [ "x" != "x$1" ]; do
	echo -n '\\n'"    <script src=\"/$1\"></script>"
	shift
    done
}

set_browser() {
    if [ "x$1" = "xmozilla" -o "x$1" = "xchromium" ]; then
	BROWSER="$1"
    else
	errcho "usage:  $0 mozilla|chromium"
	exit 1
    fi
}

main() {
    set_browser "$1"

    # placate importers of these, as they are exported by the yet-to-be-created exports_init.js
    EXPORTS__browser=exports_init.js
    EXPORTS__is_chrome=exports_init.js
    EXPORTS__is_mozilla=exports_init.js

    SCRIPTDIRS='background html common content'

    SCRIPTS=$(find $SCRIPTDIRS -name '[^.#]*.js')

    for SCRIPT in $SCRIPTS; do
	add_exports $SCRIPT
	add_imports $SCRIPT
    done

    eval "$(compute_scripts_list background/main.js || exit 1)"
    BGSCRIPTS="$(as_json_list $COMPUTED_SCRIPTS)"
    eval "$(compute_scripts_list content/main.js || exit 1)"
    CONTENTSCRIPTS="$(as_json_list $COMPUTED_SCRIPTS)"
    eval "$(compute_scripts_list html/display-panel.js || exit 1)"
    POPUPSCRIPTS="$(as_html_list $COMPUTED_SCRIPTS)"
    eval "$(compute_scripts_list html/options_main.js || exit 1)"
    OPTIONSSCRIPTS="$(as_html_list $COMPUTED_SCRIPTS)"

    BUILDDIR=build_$BROWSER
    rm -rf $BUILDDIR
    mkdir $BUILDDIR
    for DIR in $(find $SCRIPTDIRS -type d); do
	mkdir -p $BUILDDIR/$DIR
    done

    CHROMIUM_KEY=''
    GECKO_APPLICATIONS=''

    if [ "$BROWSER" = "chromium" ]; then
	CHROMIUM_KEY="\n\
\n\
    // WARNING!!!\n\
    // EACH USER SHOULD REPLACE \"key\" WITH A UNIQUE VALUE!!!\n\
    // OTHERWISE, SECURITY CAN BE TRIVIALLY COMPROMISED!\n\
    //\n\
    // A unique key can be generated with:\n\
    // $ ssh-keygen -f /path/to/new/key.pem -t rsa -b 1024\n\
    //\n\
    // Only relevant to users of chrome-based browsers.\n\
    // Users of Firefox forks are safe.\n\
\n\
    \"key\": \"b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAlwAAAAdzc2gtcnNhAAAAAwEAAQAAAIEA+0GT5WNmRRo8e5tL9+BmNtY6aBPwLIgbPnLShYBMSR40iYwLTsccrkwBXb3bs1o4p6q5WJugI8Lsia+GXZc/XHGFkq7D1aWiTxlJLs8z0JC2TQ2/yatYmBMchogYGeeUfP7aI7JJZwpATts+VhIvgga/4FYj+DijMIEpwdckqFEAAAII4Dh7HOA4exwAAAAHc3NoLXJzYQAAAIEA+0GT5WNmRRo8e5tL9+BmNtY6aBPwLIgbPnLShYBMSR40iYwLTsccrkwBXb3bs1o4p6q5WJugI8Lsia+GXZc/XHGFkq7D1aWiTxlJLs8z0JC2TQ2/yatYmBMchogYGeeUfP7aI7JJZwpATts+VhIvgga/4FYj+DijMIEpwdckqFEAAAADAQABAAAAgEHB5/MhEKMFOs8e1cMJ97ZiWubiUPlWpcqyQmauLUj1nspg3JTBh8AWJEVkaxuFgU5gYCHQmRjC6yUdywyziOEkFA4r/WpX4WmbIe+GQHRHhitLN0dgF8N6/fVNOoa5StTdfZqyl23pVXyepoDNjrJFKyupqPMmpwfH5lGr9RwBAAAAQG76HflB/5j8P2YgIYX6dQT4Ei0SqiIjNVy7jFJUQDKSJg/PYkedE02JZJBJPcMYxEJUxXtMgq+upamNILfkmY0AAABBAP4v0O5dqjy16xDDFzb4DPNAcw5Za9KJaXKVkUuKXMNZOKTR0RC/upjNTmttY980RKdIx5zA25dO8cx563bSDIsAAABBAP0MaOpBiai/eRmLqhlthHODa+Mur6W3uc9PyhWhgDBjLNMR/doaYeyfVKxtIiN3a+HkN++G+vbokRweQv++bhMAAAANdXJ6QGxvY2FsaG9zdAECAwQFBg==\","
    else
	GECKO_APPLICATIONS="\n\
    \"applications\": {\n\
	\"gecko\": {\n\
	    \"id\": \"{6fe13369-88e9-440f-b837-5012fb3bedec}\",\n\
	    \"strict_min_version\": \"60.0\"\n\
	}\n\
    },"
    fi

    sed "\
s^_GECKO_APPLICATIONS_^$GECKO_APPLICATIONS^
s^_CHROMIUM_KEY_^$CHROMIUM_KEY^
s^_BGSCRIPTS_^$BGSCRIPTS^
s^_CONTENTSCRIPTS_^$CONTENTSCRIPTS^" \
	< manifest.json > $BUILDDIR/manifest.json

    ./process_html_file.sh html/display-panel.html |
	sed "s^_POPUPSCRIPTS_^$POPUPSCRIPTS^" \
	    > $BUILDDIR/html/display-panel.html

    ./process_html_file.sh html/options.html |
	sed "s^_OPTIONSSCRIPTS_^$OPTIONSSCRIPTS^" \
	    > $BUILDDIR/html/options.html

    for FILE in $SCRIPTS; do
	FILEKEY=$(sanitize "$FILE")
	if [ "xyes" != "x$(map_get USED $FILEKEY)" ]; then
	    errcho "WARNING! $FILE not used"
	else
	    (echo "\
\"use strict\";

(() => {
$(map_get IMPORTCODES $FILEKEY)

";

# A hack to insert the contents of default_settings.json at the appropriate location in background/main.js
if [ "$FILE" = "background/main.js" ]; then
    # Uses an internal sed expression to escape and indent the JSON file for use in the external sed expression
    sed 's/^        `DEFAULT SETTINGS`$/'"$(sed -E 's/([\\\&\/])/\\\1/g; s/^/        /; s/$/\\/' < default_settings.json) "/g < "$FILE"
else
    cat $FILE
fi

echo "

$(map_get EXPORTCODES $FILEKEY)
})();") > $BUILDDIR/$FILE
	fi
    done

    if [ "$BROWSER" = "chromium" ]; then
	echo "window.killtheweb={is_chrome: true, browser: window.chrome};" > $BUILDDIR/exports_init.js
    else
	echo "window.killtheweb={is_mozilla: true, browser: this.browser};" > $BUILDDIR/exports_init.js
    fi

    cp -r copyright licenses/ $BUILDDIR
    cp html/*.css $BUILDDIR/html
    mkdir $BUILDDIR/icons
    cp icons/*.png $BUILDDIR/icons
}

main "$@"