Skip to content

tests: skip test_create_no_permission_file if read access can not be revoked - #10155

Merged
ThomasWaldmann merged 1 commit into
borgbackup:masterfrom
ThomasWaldmann:cygwin-revoke-read-access
Aug 19, 2026
Merged

tests: skip test_create_no_permission_file if read access can not be revoked#10155
ThomasWaldmann merged 1 commit into
borgbackup:masterfrom
ThomasWaldmann:cygwin-revoke-read-access

Conversation

@ThomasWaldmann

Copy link
Copy Markdown
Member

Problem

test_create_no_permission_file revokes read permissions on file2 and then expects borg create to warn about not being able to back it up (rc 105).

On cygwin (running as an elevated Administrator) it fails with assert 0 == 105: borg happily backs up all 3 files.

chmod(0o000) is not the problem — it maps to a correct NTFS DACL, and a native Windows read of the file does get UnauthorizedAccessException. The problem is that cygwin always opens files with FILE_OPEN_FOR_BACKUP_INTENT, which makes the kernel bypass the DACL check for any token holding SeBackupPrivilege (enabled for an elevated admin). Verified by toggling just that privilege in the running process:

SeBackupPrivilege ENABLED : READ SUCCEEDED -> b'hello\n'
  disable SeBackupPrivilege: ok=True
SeBackupPrivilege DISABLED: READ FAILED -> [Errno 13] Permission denied

So borg behaved correctly here — the test's precondition just was not met.

The existing guard @pytest.mark.skipif(is_root(), ...) did not catch it, because is_root() only checks os.getuid() == 0 and such an admin has a non-zero uid.

Change

Add can_revoke_read_access() to borg.testsuite and guard the test with it. Rather than enumerating privileged identities per platform, it just tries to revoke read access on a temp file and looks at whether it worked, so it also covers root, CAP_DAC_OVERRIDE and similar cases.

Also use the well-known SID *S-1-1-0 instead of the everyone group name in the icacls call, so that path also works on non-English Windows installations.

Notes for review

  • This replaces the is_root() guard rather than adding to it. For real root the two agree (root reads the file, so the probe returns False and we skip). Under fakeroot they can differ: is_root() is True (skip), while the probe reports what actually happens on the real filesystem — if the read really fails there, the test now runs and should pass. Worth an eye on the fakeroot CI run.
  • can_revoke_read_access() short-circuits to True on win32, where tests revoke access via a deny ACE instead of chmod, and such an ACE is honoured also for privileged users.

Testing

  • macOS: test passes (unchanged behaviour).
  • cygwin/Windows 11, Python 3.12, elevated admin: previously 2 failures (archiver + remote_archiver), now skipped with can not revoke our own read permissions.
  • ruff check / ruff format --check clean.

🤖 Generated with Claude Code

…revoked

test_create_no_permission_file revokes read permissions on a file and then
expects borg to warn about not being able to back it up. That only works if
we really can not read the file afterwards.

is_root() was used to guard this, but it only checks for uid 0. On cygwin,
an elevated Administrator has a non-zero uid, but still reads the file just
fine: cygwin always opens files with FILE_OPEN_FOR_BACKUP_INTENT, and that
bypasses the ACL checks for a token holding SeBackupPrivilege. So borg backed
up all 3 files and returned rc 0 while the test expected rc 105.

Guard with the new can_revoke_read_access() instead, which just tries it and
looks at the result. Being behavioural rather than identity based, it also
covers root, CAP_DAC_OVERRIDE and similar cases.

Also use the well-known SID *S-1-1-0 instead of the "everyone" group name in
the icacls call, so it also works on non-English Windows installations.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@codecov

codecov Bot commented Aug 19, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 84.73%. Comparing base (69acada) to head (f6a006e).
⚠️ Report is 31 commits behind head on master.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@            Coverage Diff             @@
##           master   #10155      +/-   ##
==========================================
- Coverage   86.88%   84.73%   -2.15%     
==========================================
  Files         101      101              
  Lines       17857    17983     +126     
  Branches     2709     2737      +28     
==========================================
- Hits        15515    15238     -277     
- Misses       1636     2044     +408     
+ Partials      706      701       -5     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

@ThomasWaldmann
ThomasWaldmann force-pushed the cygwin-revoke-read-access branch from f6a006e to 65ed0be Compare August 19, 2026 13:31
@ThomasWaldmann
ThomasWaldmann merged commit f5f53d6 into borgbackup:master Aug 19, 2026
22 of 23 checks passed
@ThomasWaldmann
ThomasWaldmann deleted the cygwin-revoke-read-access branch August 19, 2026 14:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant