Lucene search
+L

Fedora 43 : btrfs-backup-ng (2026-28cd8623c6)

🗓️ 01 Nov 2026 00:00:00Reported by TenableType 
nessus
 nessus
🔗 www.tenable.com👁 9 Views

Local privilege escalation in btrfs-backup-ng via symlink following in lock store.

Refs
Code
#%NASL_MIN_LEVEL 80900
##
# (C) Tenable, Inc.
##
# The descriptive text and package checks in this plugin were
# extracted from Fedora Security Advisory FEDORA-2026-28cd8623c6
#

include('compat.inc');

if (description)
{
  script_id(374734);
  script_version("1.1");
  script_set_attribute(attribute:"plugin_modification_date", value:"2026/11/01");
  script_xref(name:"FEDORA", value:"2026-28cd8623c6");

  script_name(english:"Fedora 43 : btrfs-backup-ng (2026-28cd8623c6)");

  script_set_attribute(attribute:"synopsis", value:
"The remote Fedora host is missing one or more security updates.");
  script_set_attribute(attribute:"description", value:
"The remote Fedora 43 host has a package installed that is affected by a vulnerability as referenced in the
FEDORA-2026-28cd8623c6 advisory.

    Update to 0.9.20. This replaces the 0.9.19 update before it reached
    testing. It carries the 0.9.17 security fix (GHSA-5xvm-66c9-p5ph), the
    0.9.18 fix for 0.9.17's btrfs lock regression, three concurrency and
    accounting fixes from 0.9.19, and 0.9.20's fix for the shared-lock
    retry bound, which the previous Fedora build carried as a patch.
    0.9.17 through 0.9.19 were not shipped to this release.

    Security: the lock store created directories, wrote holder records and
    read them back with operations that followed a symbolic link. If the
    lock-store directory on a backup location was writable by another
    local account, a planted symlink could redirect those writes and
    reads; with a backup run as root, as a scheduled backup usually is,
    that let a less privileged local user steer a root write or read.
    Locally the lock store now works on O_NOFOLLOW file descriptors, and
    over ssh each directory component is created with a plain mkdir,
    records are written under set -C, and a record that is a link or not
    a regular file is refused.

    Breaking: a lock-store directory writable by its group or by everyone
    is now refused with an error naming the directory and the remedy
    (chmod go-w <path>). A store created by an earlier version under an
    interactive umask 002 is mode 0775 and will be refused until tightened;
    stores created by a root timer or over ssh are 0755 and unaffected.
    New stores are created 0755 regardless of umask.

    Also fixed since 0.9.16:
    - A pruned raw stream whose .meta sidecar could not be removed was
    counted as both deleted and failed; the sidecar is now a warning.
    - A shared snapshot pin no longer fails with could not lock ...
    refusing to continue when another holder releases at the same
    instant, including under heavy contention on a slow machine.
    - A released shared pin can no longer be revived by an orphaned
    keep-alive, and the sweep of abandoned holder records re-checks a
    record's age at the moment it removes it.

    No configuration or on-disk format changes. This update includes all
    changes since 0.9.16.

    Advisory:
    https://github.com/berrym/btrfs-backup-ng/security/advisories/GHSA-5xvm-66c9-p5ph
    Full changelog:
    https://github.com/berrym/btrfs-backup-ng/blob/v0.9.20/CHANGELOG.md

    ----

    Update to 0.9.19. This replaces the 0.9.18 update before it reached
    testing, so it carries the 0.9.17 security fix (GHSA-5xvm-66c9-p5ph),
    the 0.9.18 fix for 0.9.17's btrfs lock regression, and three
    concurrency and accounting fixes from 0.9.19. 0.9.17 and 0.9.18 were
    not shipped to this release.

    Security: the lock store created directories, wrote holder records and
    read them back with operations that followed a symbolic link. If the
    lock-store directory on a backup location was writable by another
    local account, a planted symlink could redirect those writes and
    reads; with a backup run as root, as a scheduled backup usually is,
    that let a less privileged local user steer a root write or read.
    Locally the lock store now works on O_NOFOLLOW file descriptors, and
    over ssh each directory component is created with a plain mkdir,
    records are written under set -C, and a record that is a link or not
    a regular file is refused.

    Breaking: a lock-store directory writable by its group or by everyone
    is now refused with an error naming the directory and the remedy
    (chmod go-w <path>). A store created by an earlier version under an
    interactive umask 002 is mode 0775 and will be refused until tightened;
    stores created by a root timer or over ssh are 0755 and unaffected.
    New stores are created 0755 regardless of umask.

    Also fixed since 0.9.16:
    - A pruned raw stream whose .meta sidecar could not be removed was
    counted as both deleted and failed; the sidecar is now a warning.
    - A shared snapshot pin no longer fails with could not lock ...
    refusing to continue when another holder releases at the same
    instant; the acquire retries like the exclusive one does.
    - A released shared pin can no longer be revived by an orphaned
    keep-alive, and the sweep of abandoned holder records re-checks a
    record's age at the moment it removes it.

    No configuration or on-disk format changes. This update includes all
    changes since 0.9.16.

    Carries a patch raising the shared-lock retry bound, sent upstream.

    Advisory:
    https://github.com/berrym/btrfs-backup-ng/security/advisories/GHSA-5xvm-66c9-p5ph
    Full changelog:
    https://github.com/berrym/btrfs-backup-ng/blob/v0.9.19/CHANGELOG.md

    ----

    notes=Update to 0.9.18, which carries the 0.9.17 security fix
    (GHSA-5xvm-66c9-p5ph) and a fix for a regression in 0.9.17. 0.9.17 was
    not shipped to this release.

    Security: the lock store created directories, wrote holder records and
    read them back with operations that followed a symbolic link. If the
    lock-store directory on a backup location was writable by another
    local account, a planted symlink could redirect those writes and
    reads; with a backup run as root, as a scheduled backup usually is,
    that let a less privileged local user steer a root write or read.
    Locally the lock store now works on O_NOFOLLOW file descriptors, and
    over ssh each directory component is created with a plain mkdir,
    records are written under set -C, and a record that is a link or not
    a regular file is refused.

    Breaking: a lock-store directory writable by its group or by everyone
    is now refused with an error naming the directory and the remedy
    (chmod go-w <path>). A store created by an earlier version under an
    interactive umask 002 is mode 0775 and will be refused until tightened;
    stores created by a root timer or over ssh are 0755 and unaffected.
    New stores are created 0755 regardless of umask.

    0.9.18 fixes the 0.9.17 regression where every exclusive lock on a
    local btrfs destination on kernel 6.6 or newer failed with remote
    lock ... is busy, so a receive or prune into a local btrfs location
    could not run.

    This update includes all changes since 0.9.16.

    Advisory:
    https://github.com/berrym/btrfs-backup-ng/security/advisories/GHSA-5xvm-66c9-p5ph
    Full changelog:
    https://github.com/berrym/btrfs-backup-ng/blob/v0.9.18/CHANGELOG.md

    ----

    Update to 0.9.16.

    - A source could keep a snapshot forever and send it again in full on
    every run; fixed on the first run after upgrading.
    - On a root-owned destination with ssh_sudo, locks went stale while a
    transfer was still running; the heartbeat now elevates like the
    acquire (expect one sudo -n sh -c per beat in the sudo log).
    - restore --unlock no longer erases a pin a running restore has just
    taken.
    - doctor reports who holds each pin, and --fix repairs only what it can
    prove is stale.

    A .btrfs-backup-ng.locks.holders directory now appears beside each lock
    file; it is runtime state, and older versions ignore it.

    This update includes all changes since 0.9.12.

    Full changelog:
    https://github.com/berrym/btrfs-backup-ng/blob/v0.9.16/CHANGELOG.md

    ----

    Update to 0.9.15.

    - Pins on the source could be lost or left behind when several targets
    sent in parallel; fixed.
    - A compressed ssh:// backup to a remote without the decompressor is
    refused before the transfer starts, instead of failing after the
    stream has been sent.
    - estimate exits 2 when it could not measure and 3 when the destination
    is short of space (it exited 0), and can now measure an ssh:// source.
    - Pins on the source could be lost or left behind when several targets
    sent in parallel; fixed. Backups on the targets were not affected

    This update includes all changes since 0.9.12, including 0.9.13's fixes
    for systems without sudo, openssl or bash as sh.

    Full changelog:
    https://github.com/berrym/btrfs-backup-ng/blob/v0.9.15/CHANGELOG.md

    ----

    Update to 0.9.14.

    Fixes the test suite failing at startup with pytest older than 8.4
    (upstream #121). There are no changes to the program itself.
    0.9.14 also includes all of 0.9.13's fixes.

    Full changelog:
    https://github.com/berrym/btrfs-backup-ng/blob/v0.9.14/CHANGELOG.md

    ----

    Update to 0.9.13.

    This release fixes failures on systems without the usual privileges or
    tools:

    - A compressed backup to an ssh:// target whose remote sh is dash
    0.5.13.0-0.5.13.4 failed. Nothing was written, and existing backups
    are not affected.
    - A machine without sudo failed with No such file or directory:
    'sudo'. It now says what is needed; run stops at startup and doctor
    reports it.
    - Size estimates failed when sudo refused or was missing, although the
    snapshot was readable. du is now retried as the user.
    - A restore without openssl reported a missing passphrase instead of
    the missing program.

    Changes you may notice after upgrading:

    - config validate and doctor now check the snapper configuration and
    snapshot_dir that run depends on, so they can report an error for a
    configuration they accepted before.
    - A space check based on a du figure (an upper bound) warns and
    proceeds instead of refusing.
    - A sudo password containing a line break is refused with a message
    saying why.
    - doctor has a new local_privilege check.

    Packaging: the package now requires lzop (the program used for lzo
    compression) instead of the lzo library, and the build runs the full
    test suite, including the compression tests.

    Full changelog:
    https://github.com/berrym/btrfs-backup-ng/blob/v0.9.13/CHANGELOG.md

    ----

    Update to 0.9.12

Tenable has extracted the preceding description block directly from the Fedora security advisory.

Note that Nessus has not tested for this issue but has instead relied only on the application's self-reported version
number.");
  script_set_attribute(attribute:"see_also", value:"https://bodhi.fedoraproject.org/updates/FEDORA-2026-28cd8623c6");
  script_set_attribute(attribute:"solution", value:
"Update the affected btrfs-backup-ng package.");
  script_set_attribute(attribute:"risk_factor", value:"High");

  script_set_attribute(attribute:"exploitability_ease", value:"No known exploits are available");
  script_set_attribute(attribute:"exploit_available", value:"false");

  script_set_attribute(attribute:"vuln_publication_date", value:"2026/10/23");
  script_set_attribute(attribute:"patch_publication_date", value:"2026/10/23");
  script_set_attribute(attribute:"plugin_publication_date", value:"2026/11/01");

  script_set_attribute(attribute:"plugin_type", value:"local");
  script_set_attribute(attribute:"cpe", value:"cpe:/o:fedoraproject:fedora:43");
  script_set_attribute(attribute:"cpe", value:"p-cpe:/a:fedoraproject:fedora:btrfs-backup-ng");
  script_set_attribute(attribute:"generated_plugin", value:"current");
  script_end_attributes();

  script_category(ACT_GATHER_INFO);
  script_family(english:"Fedora Local Security Checks");

  script_copyright(english:"This script is Copyright (C) 2026 and is owned by Tenable, Inc. or an Affiliate thereof.");

  script_dependencies("ssh_get_info2.nasl");
  script_require_keys("Host/local_checks_enabled", "Host/RedHat/release", "Host/RedHat/rpm-list");

  exit(0);
}


include('rpm2.inc');

if (!get_kb_item('Host/local_checks_enabled')) audit(AUDIT_LOCAL_CHECKS_NOT_ENABLED);
var os_product = get_kb_item('installed_os/local/SSH/0/product');
if (isnull(os_product) || 'Fedora' >!< os_product) audit(AUDIT_OS_NOT, 'Fedora');
var os_version = get_kb_item('installed_os/local/SSH/0/version');
if (isnull(os_version)) audit(AUDIT_UNKNOWN_APP_VER, 'Fedora');
if (! preg(pattern:"^43([^0-9]|$)", string:os_version)) audit(AUDIT_OS_NOT, 'Fedora 43', 'Fedora ' + os_version);

if (!get_kb_item('Host/RedHat/rpm-list')) audit(AUDIT_PACKAGE_LIST_MISSING);

var cpu = get_kb_item('Host/cpu');
if (isnull(cpu)) audit(AUDIT_UNKNOWN_ARCH);
if ('x86_64' >!< cpu && cpu !~ "^i[3-6]86$" && 's390' >!< cpu && 'aarch64' >!< cpu) audit(AUDIT_LOCAL_CHECKS_NOT_IMPLEMENTED, 'Fedora', cpu);

var constraints = [
  {
    'release': '43',
    'pkgs': [
      {'reference':'btrfs-backup-ng-0.9.20-2.fc43', 'rpm_spec_vers_cmp':TRUE}
    ]
  }
];

var os_release = get_one_kb_item('installed_os/local/SSH/0/release');
var os_sp = get_one_kb_item('Host/*/minor_release');

var flag = 0;
var reference;
var sp;
var _cpu;
var el_string;
var rpm_spec_vers_cmp;
var epoch;
var allowmaj;
var exists_check;
var cves;
foreach var constraint ( constraints ) {
  # Check that the target release is equal to the affected release
  if (!empty_or_null(constraint['release'])){
    if (constraint['release'] != os_release) continue;
  }
  if (!empty_or_null(constraint['sp'])){
    if (constraint['sp'] != os_sp) continue;
  }
  foreach var pkg ( constraint['pkgs'] ) {
    reference = NULL;
    sp = NULL;
    _cpu = NULL;
    el_string = NULL;
    rpm_spec_vers_cmp = NULL;
    epoch = NULL;
    allowmaj = NULL;
    exists_check = NULL;
    cves = NULL;
    if (!empty_or_null(pkg['reference'])) reference = pkg['reference'];
    if (!empty_or_null(pkg['sp'])) sp = pkg['sp'];
    if (!empty_or_null(pkg['cpu'])) _cpu = pkg['cpu'];
    if (!empty_or_null(pkg['el_string'])) el_string = pkg['el_string'];
    if (!empty_or_null(pkg['rpm_spec_vers_cmp'])) rpm_spec_vers_cmp = pkg['rpm_spec_vers_cmp'];
    if (!empty_or_null(pkg['epoch'])) epoch = pkg['epoch'];
    if (!empty_or_null(pkg['allowmaj'])) allowmaj = pkg['allowmaj'];
    if (!empty_or_null(pkg['exists_check'])) exists_check = pkg['exists_check'];
    if (!empty_or_null(pkg['cves'])) cves = pkg['cves'];
    if (reference &&
        ## (no known rpm to check OR known rpm_exists)
        (!exists_check || rpm_exists(rpm:exists_check)) &&
        rpm_check(sp:sp, cpu:_cpu, reference:reference, epoch:epoch, el_string:el_string, rpm_spec_vers_cmp:rpm_spec_vers_cmp, allowmaj:allowmaj, cves:cves)) flag++;
  }
}

if (flag)
{
  security_report_v4(
      port       : 0,
      severity   : SECURITY_HOLE,
      extra      : rpm_report_get()
  );
  exit(0);
}
else
{
  var tested = pkg_tests_get();
  if (tested) audit(AUDIT_PACKAGE_NOT_AFFECTED, tested);
  else audit(AUDIT_PACKAGE_NOT_INSTALLED, 'btrfs-backup-ng');
}

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

01 Nov 2026 00:00Current
5.8Medium risk
Vulners AI Score5.8
9