qemu-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-commits] [qemu/qemu] 89fbea: 9pfs: Fully restart unreclaim loop (C


From: Peter Maydell
Subject: [Qemu-commits] [qemu/qemu] 89fbea: 9pfs: Fully restart unreclaim loop (CVE-2021-20181)
Date: Fri, 15 Jan 2021 07:41:02 -0800

  Branch: refs/heads/staging
  Home:   https://github.com/qemu/qemu
  Commit: 89fbea8737e8f7b954745a1ffc4238d377055305
      
https://github.com/qemu/qemu/commit/89fbea8737e8f7b954745a1ffc4238d377055305
  Author: Greg Kurz <groug@kaod.org>
  Date:   2021-01-15 (Fri, 15 Jan 2021)

  Changed paths:
    M hw/9pfs/9p.c

  Log Message:
  -----------
  9pfs: Fully restart unreclaim loop (CVE-2021-20181)

Depending on the client activity, the server can be asked to open a huge
number of file descriptors and eventually hit RLIMIT_NOFILE. This is
currently mitigated using a reclaim logic : the server closes the file
descriptors of idle fids, based on the assumption that it will be able
to re-open them later. This assumption doesn't hold of course if the
client requests the file to be unlinked. In this case, we loop on the
entire fid list and mark all related fids as unreclaimable (the reclaim
logic will just ignore them) and, of course, we open or re-open their
file descriptors if needed since we're about to unlink the file.

This is the purpose of v9fs_mark_fids_unreclaim(). Since the actual
opening of a file can cause the coroutine to yield, another client
request could possibly add a new fid that we may want to mark as
non-reclaimable as well. The loop is thus restarted if the re-open
request was actually transmitted to the backend. This is achieved
by keeping a reference on the first fid (head) before traversing
the list.

This is wrong in several ways:
- a potential clunk request from the client could tear the first
  fid down and cause the reference to be stale. This leads to a
  use-after-free error that can be detected with ASAN, using a
  custom 9p client
- fids are added at the head of the list : restarting from the
  previous head will always miss fids added by a some other
  potential request

All these problems could be avoided if fids were being added at the
end of the list. This can be achieved with a QSIMPLEQ, but this is
probably too much change for a bug fix. For now let's keep it
simple and just restart the loop from the current head.

Fixes: CVE-2021-20181
Buglink: https://bugs.launchpad.net/qemu/+bug/1911666
Reported-by: Zero Day Initiative <zdi-disclosures@trendmicro.com>
Reviewed-by: Christian Schoenebeck <qemu_oss@crudebyte.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
Message-Id: <161064025265.1838153.15185571283519390907.stgit@bahia.lan>
Signed-off-by: Greg Kurz <groug@kaod.org>


  Commit: a968a38005bf2568605cac7f86b9fba7fc089726
      
https://github.com/qemu/qemu/commit/a968a38005bf2568605cac7f86b9fba7fc089726
  Author: Peter Maydell <peter.maydell@linaro.org>
  Date:   2021-01-15 (Fri, 15 Jan 2021)

  Changed paths:
    M hw/9pfs/9p.c

  Log Message:
  -----------
  Merge remote-tracking branch 'remotes/gkurz-gitlab/tags/9p-next-2021-01-15' 
into staging

Fix for CVE-2021-20181

# gpg: Signature made Fri 15 Jan 2021 08:52:19 GMT
# gpg:                using RSA key B4828BAF943140CEF2A3491071D4D5E5822F73D6
# gpg: Good signature from "Greg Kurz <groug@kaod.org>" [full]
# gpg:                 aka "Gregory Kurz <gregory.kurz@free.fr>" [full]
# gpg:                 aka "[jpeg image of size 3330]" [full]
# Primary key fingerprint: B482 8BAF 9431 40CE F2A3  4910 71D4 D5E5 822F 73D6

* remotes/gkurz-gitlab/tags/9p-next-2021-01-15:
  9pfs: Fully restart unreclaim loop (CVE-2021-20181)

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>


Compare: https://github.com/qemu/qemu/compare/256af05f52b5...a968a38005bf



reply via email to

[Prev in Thread] Current Thread [Next in Thread]