diff options
| -rw-r--r-- | meta/recipes-extended/tar/tar/CVE-2018-20482.patch | 405 | ||||
| -rw-r--r-- | meta/recipes-extended/tar/tar_1.30.bb | 1 |
2 files changed, 406 insertions, 0 deletions
diff --git a/meta/recipes-extended/tar/tar/CVE-2018-20482.patch b/meta/recipes-extended/tar/tar/CVE-2018-20482.patch new file mode 100644 index 0000000000..2a13148427 --- /dev/null +++ b/meta/recipes-extended/tar/tar/CVE-2018-20482.patch | |||
| @@ -0,0 +1,405 @@ | |||
| 1 | From 331be56598b284d41370c67046df25673b040a55 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Sergey Poznyakoff <gray@gnu.org> | ||
| 3 | Date: Thu, 27 Dec 2018 17:48:57 +0200 | ||
| 4 | Subject: [PATCH] Fix CVE-2018-20482 | ||
| 5 | |||
| 6 | * NEWS: Update. | ||
| 7 | * src/sparse.c (sparse_dump_region): Handle short read condition. | ||
| 8 | (sparse_extract_region,check_data_region): Fix dumped_size calculation. | ||
| 9 | Handle short read condition. | ||
| 10 | (pax_decode_header): Fix dumped_size calculation. | ||
| 11 | * tests/Makefile.am: Add new testcases. | ||
| 12 | * tests/testsuite.at: Likewise. | ||
| 13 | |||
| 14 | * tests/sptrcreat.at: New file. | ||
| 15 | * tests/sptrdiff00.at: New file. | ||
| 16 | * tests/sptrdiff01.at: New file. | ||
| 17 | |||
| 18 | CVE: CVE-2018-20482 | ||
| 19 | Upstream-Status: Backport | ||
| 20 | [http://git.savannah.gnu.org/cgit/tar.git/commit/?id=c15c42ccd1e2377945fd0414eca1a49294bff454] | ||
| 21 | |||
| 22 | Signed-off-by: Dan Tran <dantran@microsoft.com> | ||
| 23 | --- | ||
| 24 | src/sparse.c | 50 +++++++++++++++++++++++++++++++----- | ||
| 25 | tests/Makefile.am | 5 +++- | ||
| 26 | tests/sptrcreat.at | 62 +++++++++++++++++++++++++++++++++++++++++++++ | ||
| 27 | tests/sptrdiff00.at | 55 ++++++++++++++++++++++++++++++++++++++++ | ||
| 28 | tests/sptrdiff01.at | 55 ++++++++++++++++++++++++++++++++++++++++ | ||
| 29 | tests/testsuite.at | 5 +++- | ||
| 30 | 6 files changed, 224 insertions(+), 8 deletions(-) | ||
| 31 | create mode 100644 tests/sptrcreat.at | ||
| 32 | create mode 100644 tests/sptrdiff00.at | ||
| 33 | create mode 100644 tests/sptrdiff01.at | ||
| 34 | |||
| 35 | diff --git a/src/sparse.c b/src/sparse.c | ||
| 36 | index 0830f62..e8e8259 100644 | ||
| 37 | --- a/src/sparse.c | ||
| 38 | +++ b/src/sparse.c | ||
| 39 | @@ -1,6 +1,6 @@ | ||
| 40 | /* Functions for dealing with sparse files | ||
| 41 | |||
| 42 | - Copyright 2003-2007, 2010, 2013-2017 Free Software Foundation, Inc. | ||
| 43 | + Copyright 2003-2007, 2010, 2013-2018 Free Software Foundation, Inc. | ||
| 44 | |||
| 45 | This program is free software; you can redistribute it and/or modify it | ||
| 46 | under the terms of the GNU General Public License as published by the | ||
| 47 | @@ -427,6 +427,30 @@ sparse_dump_region (struct tar_sparse_file *file, size_t i) | ||
| 48 | bufsize); | ||
| 49 | return false; | ||
| 50 | } | ||
| 51 | + else if (bytes_read == 0) | ||
| 52 | + { | ||
| 53 | + char buf[UINTMAX_STRSIZE_BOUND]; | ||
| 54 | + struct stat st; | ||
| 55 | + size_t n; | ||
| 56 | + if (fstat (file->fd, &st) == 0) | ||
| 57 | + n = file->stat_info->stat.st_size - st.st_size; | ||
| 58 | + else | ||
| 59 | + n = file->stat_info->stat.st_size | ||
| 60 | + - (file->stat_info->sparse_map[i].offset | ||
| 61 | + + file->stat_info->sparse_map[i].numbytes | ||
| 62 | + - bytes_left); | ||
| 63 | + | ||
| 64 | + WARNOPT (WARN_FILE_SHRANK, | ||
| 65 | + (0, 0, | ||
| 66 | + ngettext ("%s: File shrank by %s byte; padding with zeros", | ||
| 67 | + "%s: File shrank by %s bytes; padding with zeros", | ||
| 68 | + n), | ||
| 69 | + quotearg_colon (file->stat_info->orig_file_name), | ||
| 70 | + STRINGIFY_BIGINT (n, buf))); | ||
| 71 | + if (! ignore_failed_read_option) | ||
| 72 | + set_exit_status (TAREXIT_DIFFERS); | ||
| 73 | + return false; | ||
| 74 | + } | ||
| 75 | |||
| 76 | memset (blk->buffer + bytes_read, 0, BLOCKSIZE - bytes_read); | ||
| 77 | bytes_left -= bytes_read; | ||
| 78 | @@ -464,9 +488,9 @@ sparse_extract_region (struct tar_sparse_file *file, size_t i) | ||
| 79 | return false; | ||
| 80 | } | ||
| 81 | set_next_block_after (blk); | ||
| 82 | + file->dumped_size += BLOCKSIZE; | ||
| 83 | count = blocking_write (file->fd, blk->buffer, wrbytes); | ||
| 84 | write_size -= count; | ||
| 85 | - file->dumped_size += count; | ||
| 86 | mv_size_left (file->stat_info->archive_file_size - file->dumped_size); | ||
| 87 | file->offset += count; | ||
| 88 | if (count != wrbytes) | ||
| 89 | @@ -598,6 +622,12 @@ check_sparse_region (struct tar_sparse_file *file, off_t beg, off_t end) | ||
| 90 | rdsize); | ||
| 91 | return false; | ||
| 92 | } | ||
| 93 | + else if (bytes_read == 0) | ||
| 94 | + { | ||
| 95 | + report_difference (file->stat_info, _("Size differs")); | ||
| 96 | + return false; | ||
| 97 | + } | ||
| 98 | + | ||
| 99 | if (!zero_block_p (diff_buffer, bytes_read)) | ||
| 100 | { | ||
| 101 | char begbuf[INT_BUFSIZE_BOUND (off_t)]; | ||
| 102 | @@ -609,6 +639,7 @@ check_sparse_region (struct tar_sparse_file *file, off_t beg, off_t end) | ||
| 103 | |||
| 104 | beg += bytes_read; | ||
| 105 | } | ||
| 106 | + | ||
| 107 | return true; | ||
| 108 | } | ||
| 109 | |||
| 110 | @@ -635,6 +666,7 @@ check_data_region (struct tar_sparse_file *file, size_t i) | ||
| 111 | return false; | ||
| 112 | } | ||
| 113 | set_next_block_after (blk); | ||
| 114 | + file->dumped_size += BLOCKSIZE; | ||
| 115 | bytes_read = safe_read (file->fd, diff_buffer, rdsize); | ||
| 116 | if (bytes_read == SAFE_READ_ERROR) | ||
| 117 | { | ||
| 118 | @@ -645,7 +677,11 @@ check_data_region (struct tar_sparse_file *file, size_t i) | ||
| 119 | rdsize); | ||
| 120 | return false; | ||
| 121 | } | ||
| 122 | - file->dumped_size += bytes_read; | ||
| 123 | + else if (bytes_read == 0) | ||
| 124 | + { | ||
| 125 | + report_difference (¤t_stat_info, _("Size differs")); | ||
| 126 | + return false; | ||
| 127 | + } | ||
| 128 | size_left -= bytes_read; | ||
| 129 | mv_size_left (file->stat_info->archive_file_size - file->dumped_size); | ||
| 130 | if (memcmp (blk->buffer, diff_buffer, rdsize)) | ||
| 131 | @@ -1213,7 +1249,8 @@ pax_decode_header (struct tar_sparse_file *file) | ||
| 132 | union block *blk; | ||
| 133 | char *p; | ||
| 134 | size_t i; | ||
| 135 | - | ||
| 136 | + off_t start; | ||
| 137 | + | ||
| 138 | #define COPY_BUF(b,buf,src) do \ | ||
| 139 | { \ | ||
| 140 | char *endp = b->buffer + BLOCKSIZE; \ | ||
| 141 | @@ -1229,7 +1266,6 @@ pax_decode_header (struct tar_sparse_file *file) | ||
| 142 | if (src == endp) \ | ||
| 143 | { \ | ||
| 144 | set_next_block_after (b); \ | ||
| 145 | - file->dumped_size += BLOCKSIZE; \ | ||
| 146 | b = find_next_block (); \ | ||
| 147 | if (!b) \ | ||
| 148 | FATAL_ERROR ((0, 0, _("Unexpected EOF in archive"))); \ | ||
| 149 | @@ -1242,8 +1278,8 @@ pax_decode_header (struct tar_sparse_file *file) | ||
| 150 | dst[-1] = 0; \ | ||
| 151 | } while (0) | ||
| 152 | |||
| 153 | + start = current_block_ordinal (); | ||
| 154 | set_next_block_after (current_header); | ||
| 155 | - file->dumped_size += BLOCKSIZE; | ||
| 156 | blk = find_next_block (); | ||
| 157 | if (!blk) | ||
| 158 | FATAL_ERROR ((0, 0, _("Unexpected EOF in archive"))); | ||
| 159 | @@ -1282,6 +1318,8 @@ pax_decode_header (struct tar_sparse_file *file) | ||
| 160 | sparse_add_map (file->stat_info, &sp); | ||
| 161 | } | ||
| 162 | set_next_block_after (blk); | ||
| 163 | + | ||
| 164 | + file->dumped_size += BLOCKSIZE * (current_block_ordinal () - start); | ||
| 165 | } | ||
| 166 | |||
| 167 | return true; | ||
| 168 | diff --git a/tests/Makefile.am b/tests/Makefile.am | ||
| 169 | index 2d7939d..ac3b6e7 100644 | ||
| 170 | --- a/tests/Makefile.am | ||
| 171 | +++ b/tests/Makefile.am | ||
| 172 | @@ -1,6 +1,6 @@ | ||
| 173 | # Makefile for GNU tar regression tests. | ||
| 174 | |||
| 175 | -# Copyright 1996-1997, 1999-2001, 2003-2007, 2009, 2012-2015 Free Software | ||
| 176 | +# Copyright 1996-1997, 1999-2001, 2003-2007, 2009, 2012-2018 Free Software | ||
| 177 | |||
| 178 | # This file is part of GNU tar. | ||
| 179 | |||
| 180 | @@ -228,6 +228,9 @@ TESTSUITE_AT = \ | ||
| 181 | spmvp00.at\ | ||
| 182 | spmvp01.at\ | ||
| 183 | spmvp10.at\ | ||
| 184 | + sptrcreat.at\ | ||
| 185 | + sptrdiff00.at\ | ||
| 186 | + sptrdiff01.at\ | ||
| 187 | time01.at\ | ||
| 188 | time02.at\ | ||
| 189 | truncate.at\ | ||
| 190 | diff --git a/tests/sptrcreat.at b/tests/sptrcreat.at | ||
| 191 | new file mode 100644 | ||
| 192 | index 0000000..8e28f0e | ||
| 193 | --- /dev/null | ||
| 194 | +++ b/tests/sptrcreat.at | ||
| 195 | @@ -0,0 +1,62 @@ | ||
| 196 | +# Process this file with autom4te to create testsuite. -*- Autotest -*- | ||
| 197 | + | ||
| 198 | +# Test suite for GNU tar. | ||
| 199 | +# Copyright 2018 Free Software Foundation, Inc. | ||
| 200 | + | ||
| 201 | +# This file is part of GNU tar. | ||
| 202 | + | ||
| 203 | +# GNU tar is free software; you can redistribute it and/or modify | ||
| 204 | +# it under the terms of the GNU General Public License as published by | ||
| 205 | +# the Free Software Foundation; either version 3 of the License, or | ||
| 206 | +# (at your option) any later version. | ||
| 207 | + | ||
| 208 | +# GNU tar is distributed in the hope that it will be useful, | ||
| 209 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 210 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 211 | +# GNU General Public License for more details. | ||
| 212 | + | ||
| 213 | +# You should have received a copy of the GNU General Public License | ||
| 214 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 215 | + | ||
| 216 | +# Tar up to 1.30 would loop endlessly if a sparse file had been truncated | ||
| 217 | +# while being archived (with --sparse flag). | ||
| 218 | +# | ||
| 219 | +# The bug has been assigned id CVE-2018-20482 (on the grounds that it is a | ||
| 220 | +# denial of service possibility). | ||
| 221 | +# | ||
| 222 | +# Reported by: Chris Siebenmann <cks.gnutar-01@cs.toronto.edu> | ||
| 223 | +# References: <20181226223948.781EB32008E@apps1.cs.toronto.edu>, | ||
| 224 | +# <http://lists.gnu.org/archive/html/bug-tar/2018-12/msg00023.html> | ||
| 225 | +# <https://utcc.utoronto.ca/~cks/space/blog/sysadmin/TarFindingTruncateBug> | ||
| 226 | +# <https://nvd.nist.gov/vuln/detail/CVE-2018-20482> | ||
| 227 | + | ||
| 228 | +AT_SETUP([sparse file truncated while archiving]) | ||
| 229 | +AT_KEYWORDS([truncate filechange sparse sptr sptrcreat]) | ||
| 230 | + | ||
| 231 | +AT_TAR_CHECK([ | ||
| 232 | +genfile --sparse --block-size=1024 --file foo \ | ||
| 233 | + 0 ABCDEFGHIJ 1M ABCDEFGHIJ 10M ABCDEFGHIJ 200M ABCDEFGHIJ | ||
| 234 | +genfile --file baz | ||
| 235 | +genfile --run --checkpoint 3 --length 200m --truncate foo -- \ | ||
| 236 | + tar --checkpoint=1 \ | ||
| 237 | + --checkpoint-action=echo \ | ||
| 238 | + --checkpoint-action=sleep=1 \ | ||
| 239 | + --sparse -vcf bar foo baz | ||
| 240 | +echo Exit status: $? | ||
| 241 | +echo separator | ||
| 242 | +genfile --file foo --seek 200m --length 11575296 --pattern=zeros | ||
| 243 | +tar dvf bar], | ||
| 244 | +[1], | ||
| 245 | +[foo | ||
| 246 | +baz | ||
| 247 | +Exit status: 1 | ||
| 248 | +separator | ||
| 249 | +foo | ||
| 250 | +foo: Mod time differs | ||
| 251 | +baz | ||
| 252 | +], | ||
| 253 | +[tar: foo: File shrank by 11575296 bytes; padding with zeros | ||
| 254 | +], | ||
| 255 | +[],[],[posix, gnu, oldgnu]) | ||
| 256 | + | ||
| 257 | +AT_CLEANUP | ||
| 258 | diff --git a/tests/sptrdiff00.at b/tests/sptrdiff00.at | ||
| 259 | new file mode 100644 | ||
| 260 | index 0000000..c410561 | ||
| 261 | --- /dev/null | ||
| 262 | +++ b/tests/sptrdiff00.at | ||
| 263 | @@ -0,0 +1,55 @@ | ||
| 264 | +# Process this file with autom4te to create testsuite. -*- Autotest -*- | ||
| 265 | +# | ||
| 266 | +# Test suite for GNU tar. | ||
| 267 | +# Copyright 2018 Free Software Foundation, Inc. | ||
| 268 | +# | ||
| 269 | +# This file is part of GNU tar. | ||
| 270 | +# | ||
| 271 | +# GNU tar is free software; you can redistribute it and/or modify | ||
| 272 | +# it under the terms of the GNU General Public License as published by | ||
| 273 | +# the Free Software Foundation; either version 3 of the License, or | ||
| 274 | +# (at your option) any later version. | ||
| 275 | +# | ||
| 276 | +# GNU tar is distributed in the hope that it will be useful, | ||
| 277 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 278 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 279 | +# GNU General Public License for more details. | ||
| 280 | +# | ||
| 281 | +# You should have received a copy of the GNU General Public License | ||
| 282 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 283 | + | ||
| 284 | +# While fixing CVE-2018-20482 (see sptrcreat.at) it has been discovered | ||
| 285 | +# that similar bug exists in file checking code (tar d). | ||
| 286 | +# This test case checks if tar correctly handles a short read condition | ||
| 287 | +# appearing in check_sparse_region. | ||
| 288 | + | ||
| 289 | +AT_SETUP([file truncated in sparse region while comparing]) | ||
| 290 | +AT_KEYWORDS([truncate filechange sparse sptr sptrdiff diff]) | ||
| 291 | + | ||
| 292 | +# This triggers short read in check_sparse_region. | ||
| 293 | +AT_TAR_CHECK([ | ||
| 294 | +genfile --sparse --block-size=1024 --file foo \ | ||
| 295 | + 0 ABCDEFGHIJ 1M ABCDEFGHIJ 10M ABCDEFGHIJ 200M ABCDEFGHIJ | ||
| 296 | +genfile --file baz | ||
| 297 | +echo creating | ||
| 298 | +tar --sparse -vcf bar foo baz | ||
| 299 | +echo comparing | ||
| 300 | +genfile --run --checkpoint 3 --length 200m --truncate foo -- \ | ||
| 301 | + tar --checkpoint=1 \ | ||
| 302 | + --checkpoint-action=echo='Write checkpoint %u' \ | ||
| 303 | + --checkpoint-action=sleep=1 \ | ||
| 304 | + --sparse -vdf bar | ||
| 305 | +], | ||
| 306 | +[1], | ||
| 307 | +[creating | ||
| 308 | +foo | ||
| 309 | +baz | ||
| 310 | +comparing | ||
| 311 | +foo | ||
| 312 | +foo: Size differs | ||
| 313 | +baz | ||
| 314 | +], | ||
| 315 | +[], | ||
| 316 | +[],[],[posix, gnu, oldgnu]) | ||
| 317 | + | ||
| 318 | +AT_CLEANUP | ||
| 319 | diff --git a/tests/sptrdiff01.at b/tests/sptrdiff01.at | ||
| 320 | new file mode 100644 | ||
| 321 | index 0000000..2da2267 | ||
| 322 | --- /dev/null | ||
| 323 | +++ b/tests/sptrdiff01.at | ||
| 324 | @@ -0,0 +1,55 @@ | ||
| 325 | +# Process this file with autom4te to create testsuite. -*- Autotest -*- | ||
| 326 | +# | ||
| 327 | +# Test suite for GNU tar. | ||
| 328 | +# Copyright 2018 Free Software Foundation, Inc. | ||
| 329 | +# | ||
| 330 | +# This file is part of GNU tar. | ||
| 331 | +# | ||
| 332 | +# GNU tar is free software; you can redistribute it and/or modify | ||
| 333 | +# it under the terms of the GNU General Public License as published by | ||
| 334 | +# the Free Software Foundation; either version 3 of the License, or | ||
| 335 | +# (at your option) any later version. | ||
| 336 | +# | ||
| 337 | +# GNU tar is distributed in the hope that it will be useful, | ||
| 338 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 339 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 340 | +# GNU General Public License for more details. | ||
| 341 | +# | ||
| 342 | +# You should have received a copy of the GNU General Public License | ||
| 343 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 344 | + | ||
| 345 | +# While fixing CVE-2018-20482 (see sptrcreat.at) it has been discovered | ||
| 346 | +# that similar bug exists in file checking code (tar d). | ||
| 347 | +# This test case checks if tar correctly handles a short read condition | ||
| 348 | +# appearing in check_data_region. | ||
| 349 | + | ||
| 350 | +AT_SETUP([file truncated in data region while comparing]) | ||
| 351 | +AT_KEYWORDS([truncate filechange sparse sptr sptrdiff diff]) | ||
| 352 | + | ||
| 353 | +# This triggers short read in check_data_region. | ||
| 354 | +AT_TAR_CHECK([ | ||
| 355 | +genfile --sparse --block-size=1024 --file foo \ | ||
| 356 | + 0 ABCDEFGHIJ 1M ABCDEFGHIJ 10M ABCDEFGHIJ 200M ABCDEFGHIJ | ||
| 357 | +genfile --file baz | ||
| 358 | +echo creating | ||
| 359 | +tar --sparse -vcf bar foo baz | ||
| 360 | +echo comparing | ||
| 361 | +genfile --run --checkpoint 5 --length 221278210 --truncate foo -- \ | ||
| 362 | + tar --checkpoint=1 \ | ||
| 363 | + --checkpoint-action=echo='Write checkpoint %u' \ | ||
| 364 | + --checkpoint-action=sleep=1 \ | ||
| 365 | + --sparse -vdf bar | ||
| 366 | +], | ||
| 367 | +[1], | ||
| 368 | +[creating | ||
| 369 | +foo | ||
| 370 | +baz | ||
| 371 | +comparing | ||
| 372 | +foo | ||
| 373 | +foo: Size differs | ||
| 374 | +baz | ||
| 375 | +], | ||
| 376 | +[], | ||
| 377 | +[],[],[posix, gnu, oldgnu]) | ||
| 378 | + | ||
| 379 | +AT_CLEANUP | ||
| 380 | diff --git a/tests/testsuite.at b/tests/testsuite.at | ||
| 381 | index 2a83757..23386f7 100644 | ||
| 382 | --- a/tests/testsuite.at | ||
| 383 | +++ b/tests/testsuite.at | ||
| 384 | @@ -1,7 +1,7 @@ | ||
| 385 | # Process this file with autom4te to create testsuite. -*- Autotest -*- | ||
| 386 | |||
| 387 | # Test suite for GNU tar. | ||
| 388 | -# Copyright 2004-2008, 2010-2017 Free Software Foundation, Inc. | ||
| 389 | +# Copyright 2004-2008, 2010-2018 Free Software Foundation, Inc. | ||
| 390 | |||
| 391 | # This file is part of GNU tar. | ||
| 392 | |||
| 393 | @@ -405,6 +405,9 @@ m4_include([sparsemv.at]) | ||
| 394 | m4_include([spmvp00.at]) | ||
| 395 | m4_include([spmvp01.at]) | ||
| 396 | m4_include([spmvp10.at]) | ||
| 397 | +m4_include([sptrcreat.at]) | ||
| 398 | +m4_include([sptrdiff00.at]) | ||
| 399 | +m4_include([sptrdiff01.at]) | ||
| 400 | |||
| 401 | AT_BANNER([Updates]) | ||
| 402 | m4_include([update.at]) | ||
| 403 | -- | ||
| 404 | 2.22.0.vfs.1.1.57.gbaf16c8 | ||
| 405 | |||
diff --git a/meta/recipes-extended/tar/tar_1.30.bb b/meta/recipes-extended/tar/tar_1.30.bb index ab1b33b378..7cf0522455 100644 --- a/meta/recipes-extended/tar/tar_1.30.bb +++ b/meta/recipes-extended/tar/tar_1.30.bb | |||
| @@ -10,6 +10,7 @@ SRC_URI = "${GNU_MIRROR}/tar/tar-${PV}.tar.bz2 \ | |||
| 10 | file://remove-gets.patch \ | 10 | file://remove-gets.patch \ |
| 11 | file://musl_dirent.patch \ | 11 | file://musl_dirent.patch \ |
| 12 | file://CVE-2019-9923.patch \ | 12 | file://CVE-2019-9923.patch \ |
| 13 | file://CVE-2018-20482.patch \ | ||
| 13 | " | 14 | " |
| 14 | 15 | ||
| 15 | SRC_URI[md5sum] = "8404e4c1fc5a3000228ab2b8ad674a65" | 16 | SRC_URI[md5sum] = "8404e4c1fc5a3000228ab2b8ad674a65" |
