Merge commit from fork

docs/testing/security-regressions.md requires every fixed advisory to map to a
named, greppable regression test. Rename the tests added with the fixes to carry
their advisory id so `rg -i ghsa` finds them, and add the four rows to the
advisory -> test map.

Adds the FTPS MKD regression test that was missing. It primes the dummy backend
with a successful create_bucket, so the assertion distinguishes "denied at the
authorization boundary" from "backend refused" — without the queued success an
unconfigured create_bucket fails on its own and the test would pass even with
the authorization check removed. Verified it fails when the check is reverted.

DummyBackend gains a Debug impl (FtpsDriver's trait bounds require it) and a
queue_create_bucket_ok helper.

Records in the CI-execution map why ghsa_g3vq_* runs in the default pass despite
sitting behind the ftps feature: the rustfs crate defaults to ["ftps", "webdav"]
and cargo unifies features across the workspace build, so the test executes
there even though `cargo test -p rustfs-protocols` alone would skip it.
This commit is contained in:
Zhengchao An
2026-07-26 07:10:50 +08:00
committed by GitHub
parent 92f83bfe15
commit 7f19e9a465
6 changed files with 75 additions and 9 deletions
@@ -217,6 +217,15 @@ pub struct DummyBackend {
inner: Mutex<Inner>,
}
// Drivers whose trait bounds require `Debug` (for example FtpsDriver) cannot be
// instantiated with this double otherwise. The queues themselves are not worth
// rendering, and locking to print them would risk deadlocking a failing test.
impl std::fmt::Debug for DummyBackend {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("DummyBackend").finish_non_exhaustive()
}
}
impl Default for DummyBackend {
fn default() -> Self {
Self::new()
@@ -263,6 +272,18 @@ impl DummyBackend {
.push_back(Ok(PutObjectOutput::default()));
}
/// Queue a successful create_bucket. Authorization tests use this to tell
/// "denied before the backend" apart from "backend refused": an unqueued
/// create_bucket returns `Unconfigured`, so only a queued success proves the
/// driver reached the backend.
pub fn queue_create_bucket_ok(&self) {
self.inner
.lock()
.expect("lock")
.create_bucket
.push_back(Ok(CreateBucketOutput::default()));
}
/// Queue a put_object error. Used by the commit_write retry tests
/// to script SlowDown / AccessDenied sequences against the
/// rustfs_utils::retry::is_s3code_in_message_retryable predicate.