{"id":"CLSA-2026-1788335736","summary":"Fix of 13 CVEs","details":"   * SECURITY UPDATE: peer-driven one-byte heap out-of-bounds write in\n     add_implied_include() from a files-from entry carrying both an interior\n     and a trailing backslash:\n     - debian/patches/els/0009-CVE-2026-70461.patch: count a trailing\n       backslash when sizing the appended-wildcard pattern.\n     - CVE-2026-70461.\n   * SECURITY UPDATE: heap out-of-bounds write in read_args() when the peer's\n     argument count lands exactly on the argv allocation:\n     - debian/patches/els/0010-CVE-2026-70456.patch: reserve room for the\n       trailing NULL terminator.\n     - CVE-2026-70456.\n   * SECURITY UPDATE: out-of-bounds write from a file entry marked\n     FLAG_HLINKED that the receiver accepted with hard-link preservation\n     inactive:\n     - debian/patches/els/0011-CVE-2026-70458.patch: gate FLAG_HLINKED on\n       preserve_hard_links and exclude directories.\n     - CVE-2026-70458.\n   * SECURITY UPDATE: sender-side out-of-bounds read driven by a malicious\n     receiver's checksum header with a non-zero block count and a zero block\n     length:\n     - debian/patches/els/0012-CVE-2026-53792.patch: reject a zero block\n       length in read_sum_head().\n     - CVE-2026-53792.\n   * SECURITY UPDATE: CPU exhaustion in the sending process via\n     quadratic-time behaviour in hash_search(), driven by a malicious\n     receiver's crafted equal-weak-checksum block list. The attacker is the\n     receiver, but the cycles burned are the sender's: hash_search() is\n     reached only through match_sums(), whose sole caller is send_files() in\n     sender.c. NVD's text attributes the CPU to the receiver; the direction\n     stated here is what the code does:\n     - debian/patches/els/0013-CVE-2026-70453.patch: bound the per-offset\n       chain walk.\n     - CVE-2026-70453.\n   * SECURITY UPDATE: daemon \"hosts deny\" failing open when a configured\n     hostname token cannot be resolved:\n     - debian/patches/els/0014-CVE-2026-70452.patch: treat an unresolvable\n       deny-list token as a match.\n     - CVE-2026-70452.\n   * SECURITY UPDATE: daemon \"auth users\" ignoring its documented comma-only\n     parsing, silently discarding a deny rule that names a group whose name\n     contains a space:\n     - debian/patches/els/0015-CVE-2026-70463.patch: parse the list with\n       conf_strtok().\n     - CVE-2026-70463.\n   * SECURITY UPDATE: peer-supplied MSG_IO_TIMEOUT disabling the client's own\n     I/O timeout through a non-positive or overflowing value:\n     - debian/patches/els/0016-CVE-2026-70462.patch: cap the received value\n       and make set_io_timeout() arithmetic overflow-safe.\n     - CVE-2026-70462.\n   * SECURITY UPDATE: client-supplied --filter merge file bypassing the daemon\n     module filter list:\n     - debian/patches/els/0017-CVE-2026-53786.patch: strip the module-dir\n       prefix before the daemon-filter check.\n     - CVE-2026-53786.\n   * SECURITY UPDATE: per-connection daemon child crash on a crafted first\n     incremental file list whose transfer root is a non-directory dot entry:\n     - debian/patches/els/0018-CVE-2026-70459.patch: reject a non-directory\n       transfer-root entry and require a dir_flist entry before trusting\n       parent_ndx 0.\n     - CVE-2026-70459.\n   * SECURITY UPDATE: malicious sender widening the receiver's --delete scope\n     beyond the destination subtree via implied-parent reclassification:\n     - debian/patches/els/0019-CVE-2026-53789.patch: force implied-parent\n       directories non-content on the receiver, including the synthetic\n       transfer root and the pre-protocol-30 encoding.\n     - CVE-2026-53789.\n   * SECURITY UPDATE: unauthenticated pre-transfer handshake stall holding a\n     per-connection daemon child past the module's max connections limit:\n     - debian/patches/els/0020-CVE-2026-70464.patch: bound every\n       peer-controlled handshake read with an absolute deadline and cap the\n       early-protocol argument count.\n     - CVE-2026-70464.\n   * SECURITY UPDATE: command and argument injection through the\n     RSYNC_CONNECT_PROG %H host substitution, through unquoted arguments in a\n     --write-batch replay script, and through remote-shell argument quoting\n     that did not escape the newline, the carriage return or the backtick:\n     - debian/patches/els/0021-CVE-2026-53790.patch: shell-quote and validate\n       the connect host, and quote every replay-script argument.\n     - debian/patches/els/0025-CVE-2026-53790-safe-arg-shell-chars.patch: add\n       the newline, the carriage return and the backtick to safe_arg()'s\n       SHELL_CHARS escape set. safe_arg() escapes metacharacters because the\n       remote end is reached as \"ssh \u003chost\u003e rsync --server ...\", where ssh\n       joins the command words and the remote sshd hands the string to the\n       remote user's login shell, which re-parses it; an unescaped newline\n       therefore ended the transfer command and ran what followed, and an\n       unescaped backtick opened a command substitution. This package\n       acquired safe_arg() from els/0001-CVE-2022-29154.patch, whose donor\n       predates the backtick's addition upstream.\n     - Partial fix: the daemon %RSYNC_*% exec-hook expansions do not exist in\n       3.1.3 and rsync-ssl is not installed by debian/rules, so those two of\n       the four sinks named in the advisory are not present in this package.\n     - CVE-2026-53790.\n   * SECURITY UPDATE: further out-of-bounds F_SUM() reads where the checksum\n     extra slot was never reserved -- a daemon sender with \"%C\" in its log\n     format, a hard-linked non-regular entry compared against a basis dir,\n     and \"%C\" on a deletion:\n     - debian/patches/els/0022-CVE-2026-70458.patch: set\n       sender_keeps_checksum in start_server(), require S_ISREG(file-\u003emode)\n       before the content compare in hard_link_check(), and skip the\n       checksum for an ITEM_DELETED entry.\n     - CVE-2026-70458.\n   * Drop two peer-reachable assert() aborts (no CVE assigned; carried from\n     the same upstream commit as several of the fixes above, and live in the\n     shipped binary because nothing in the build defines NDEBUG):\n     - debian/patches/els/0023-peer-reachable-asserts.patch: turn an\n       undeclared cross-flist hard-link gnum into a protocol error instead of\n       an assert, and stop asserting !is_utf8 when a daemon receiver\n       forwards a peer message to the generator.\n   * Bound merge-file include recursion (no CVE assigned; the remaining\n     peer-reachable crash hunk of the same upstream commit several of the\n     fixes above come from). A merge file's content may name another merge\n     file, so parse_filter_file() re-enters itself with a BIGPATHBUFLEN\n     stack buffer per level; a self-referencing per-directory merge file,\n     whose content the peer supplies through the transferred tree, recursed\n     until the stack was exhausted (SIGSEGV):\n     - debian/patches/els/0024-merge-file-depth-cap.patch: add\n       MAX_MERGE_DEPTH and a nesting counter.\n   * Add committed regression tests to the shipped test suite for the six\n     fixes that a black-box test can observe, each carried by the patch it\n     proves and each failing without that patch:\n     - testsuite/cve-2026-70452.test (els/0014), an unresolvable \"hosts deny\"\n       token must deny.\n     - testsuite/cve-2026-70463.test (els/0015), the first word of a\n       space-bearing \"auth users\" entry must not become an allow rule.\n     - testsuite/cve-2026-53786.test (els/0017), a daemon filter rule must\n       govern a client merge file, and an \"exclude from\" path that only shares\n       the module path's textual prefix must not be truncated.\n     - testsuite/cve-2026-53790.test (els/0021), a newline-bearing filter rule\n       must not reach the replay script and an injected RSYNC_CONNECT_PROG %H\n       host must not execute.\n     - testsuite/cve-2026-53790-shell-chars.test (els/0025), a newline, a\n       carriage return or a backtick in a path must not execute a command on\n       the remote shell, and an ordinary transfer over the same remote shell\n       must still work.\n     - testsuite/cve-2026-70458.test (els/0022), the daemon's logged \"%C\" must\n       be the file's checksum, not adjacent pool memory.\n     - testsuite/merge-depth.test (els/0024), a self-referencing merge file\n       must be refused, not crash the process.\n     - testsuite/cve-2026-53790-safe-arg-uninit.test (els/0027), a trailing\n       backslash in a path must reach the remote shell doubled, and no stray\n       byte may follow a path that carries a backslash.\n   * SECURITY UPDATE: safe_arg() sized its result one byte larger than it\n     wrote for every backslash that precedes a wildcard and for a trailing\n     backslash, so the closing NUL landed past the last byte written and\n     uninitialised heap was returned inside the string handed to the remote\n     shell (--protect-args is off by default in 3.1.3). The same defect left a\n     trailing backslash unescaped there, where it escapes the following space\n     and joins the next word:\n     - debian/patches/els/0027-CVE-2026-53790-safe-arg-uninit.patch: make the\n       escape counter mirror the writer and guard the WILD_CHARS lookup with\n       f[1]. Upstream's own stable-branch backport (1aef79e1 on\n       v3.2.7-sec-patches3, from 22efd249), applied unchanged.\n     - CVE-2026-53790.\n   * SECURITY UPDATE: a fourth out-of-bounds F_SUM() read, specific to this\n     package. generator.c unchanged_file() guards the checksum compare on the\n     destination's on-disk mode while the slot is reserved from the\n     peer-supplied file-\u003emode; Debian's copy-devices.diff lets a device entry\n     reach it, so with -c --copy-devices a sender's device entry whose\n     destination is an existing regular file reads below its pool slot:\n     - debian/patches/els/0030-CVE-2026-70458-copy-devices.patch: require\n       S_ISREG(file-\u003emode) as well.\n     - CVE-2026-70458.\n   * Carry the four remaining hunks of upstream 3eeedf8d that land in\n     functions this series already patches (no CVE assigned; the same\n     malicious-peer hardening commit seven of the patches above cite):\n     - debian/patches/els/0026-donor-parity-3eeedf8d.patch: re-check the block\n       length before adopting want_i in hash_search(), clamp a peer-supplied\n       s-\u003eflength to the local length in match_sums(), and refuse a sub-flist\n       that arrives after the final flist was freed or that names a cleared\n       dir_flist slot in recv_file_list().\n   * Fix secure_relative_open() never returning a directory descriptor. The\n     per-component walk only assigned the result in its ENOTDIR arm, so a\n     path that resolved to a directory fell through to \"errno = EINVAL\" and\n     returned -1. Every permission change on a daemon receiver running with\n     \"use chroot = no\" therefore failed with \"failed to set permissions ...\n     Invalid argument (22)\" and the transfer exited 23. Introduced by\n     els/0006-CVE-2026-29518.patch, which added both the helper and its\n     O_DIRECTORY callers:\n     - debian/patches/els/0029-secure-relative-open-dirfd.patch.\n   * Run the upstream testsuite during the build, so the regression tests\n     above are load-bearing:\n     - debian/patches/els/0028-testsuite-harness.patch: add the missing\n       syscall.o stubs (noatime, am_daemon, am_chrooted) to tls.c,\n       trimslash.c and t_unsafe.c, without which \"make check\" could not even\n       link its helper programs, and let runtests.sh honour a $skiptests list.\n     - debian/rules: run \"make check\" from build-stamp unless\n       DEB_BUILD_OPTIONS=nocheck, excluding devices and devices-fake, which\n       fail identically on 3.1.3 with only the Debian patches applied.","modified":"2026-10-26T09:43:29.311029583Z","published":"2026-09-02T07:58:24Z","upstream":["CVE-2022-29154","CVE-2026-29518","CVE-2026-53786","CVE-2026-53789","CVE-2026-53790","CVE-2026-53792","CVE-2026-70452","CVE-2026-70453","CVE-2026-70456","CVE-2026-70458","CVE-2026-70459","CVE-2026-70461","CVE-2026-70462","CVE-2026-70463","CVE-2026-70464"],"references":[{"type":"ADVISORY","url":"https://errata.tuxcare.com/els_os/debian10els/CLSA-2026-1788335736.html"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-53786"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-53789"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-53790"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-53792"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-70452"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-70453"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-70456"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-70458"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-70459"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-70461"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-70462"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-70463"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-70464"}],"affected":[{"package":{"name":"rsync","ecosystem":"TuxCare:Debian:10","purl":"pkg:deb/tuxcare/rsync?distro=debian-10"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"3.1.3-6+tuxcare.els5"}]}],"database_specific":{"source":"https://github.com/cloudlinux/tuxcare-osv/tree/main/data/els_os/debian10els/CLSA-2026-1788335736.json"}}],"schema_version":"1.9.0"}