Repository navigation
Conversation
vaintroub
force-pushed
the
11.4-MDEV-39533
branch
from
September 15, 2026 17:18
27036f7 to
ef5f555
Compare
vaintroub
force-pushed
the
11.4-MDEV-39533
branch
from
September 15, 2026 18:28
ef5f555 to
c8e9423
Compare
vaintroub
force-pushed
the
11.4-MDEV-39533
branch
from
September 25, 2026 10:46
c8e9423 to
66f2da1
Compare
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Unresolved critical deletion-safety issues and Windows path-resolution contract findings remain.
Get a fresh assessment by requesting another Copilot review.
Review effort: Lite
Findings: 2
Open (2)
Resolved since last review (2)
Comment on lines
+177
to
+180
| if (win_unlink_check_nosymlinks(handle, name, MyFlags)) | ||
| { | ||
| CloseHandle(handle); | ||
| DBUG_RETURN(-1); /* errno set by my_win_verify_nosymlinks() */ |
Comment on lines
+209
to
+213
| if (win_unlink_check_nosymlinks(handle, name, MyFlags)) | ||
| { | ||
| CloseHandle(handle); | ||
| DBUG_RETURN(-1); /* errno set by my_win_verify_nosymlinks() */ | ||
| } |
vaintroub
force-pushed
the
11.4-MDEV-39533
branch
2 times, most recently
from
October 2, 2026 23:17
5a514a3 to
49f9c91
Compare
Comment on lines
+421
to
+425
| /* NORMALIZED fails outright on some SMB servers; OPENED still names | ||
| the same resolved file (just a possibly different spelling), so | ||
| it's a safe fallback even for MY_NOSYMLINKS verification. */ | ||
| len= GetFinalPathNameByHandle(handle, buf, (DWORD) sizeof(buf), | ||
| FILE_NAME_OPENED | VOLUME_NAME_DOS); |
Comment on lines
+680
to
+681
| DBUG_EXECUTE_IF("force_posix_delete_fail", goto nonposix_delete;); | ||
| FILE_DISPOSITION_INFO_EX disp_ex; |
vaintroub
force-pushed
the
11.4-MDEV-39533
branch
from
October 3, 2026 15:58
49f9c91 to
5d39563
Compare
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Critical and moderate issues remain in path verification, deletion behavior, build compatibility, and test cleanup.
Review effort: Lite
Findings: 4
Open (6)
Fail closed when realpath resolution falls back unresolved · New Fallback path can bypass nosymlink checks using unresolved opened names Prevent path-based fallback rename from bypassing handle verification Cancel pending deletion when rejecting symlink or junction Debug build fails due to goto crossing disp_ex initialization Wrap documentation lines exceeding 80 characters · New
Comment on lines
+436
to
+440
| /* NORMALIZED fails outright on some SMB servers; fall back to OPENED | ||
| so such shares remain usable, though it may not fully resolve | ||
| reparse points, weakening MY_NOSYMLINKS verification. */ | ||
| warn_final_path_fallback_once(name); | ||
| len= GetFinalPathNameByHandle(handle, buf, (DWORD) sizeof(buf), |
Comment on lines
+646
to
+649
| falls back to renaming to a unique name, then marking for classic delete-on-close. | ||
| The fallback is needed for FAT32/ExFAT, which do not have "POSIX-semantics" delete. | ||
| Renaming to unique name is needed, otherwise recreating file with the same name might | ||
| fail if another handle on file is still open. |
vaintroub
force-pushed
the
11.4-MDEV-39533
branch
from
October 4, 2026 13:13
5d39563 to
b7b23c1
Compare
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
The fallback path can fail open and bypass MY_NOSYMLINKS protection.
Review effort: Balanced
Findings: 4
Open (7)
Fail closed when realpath resolution falls back unresolved Fallback path can bypass nosymlink checks using unresolved opened names Prevent path-based fallback rename from bypassing handle verification Cancel pending deletion when rejecting symlink or junction Debug build fails due to goto crossing disp_ex initialization Line exceeds the 80-character limit · New Wrap documentation lines exceeding 80 characters
| */ | ||
| DBUG_EXECUTE_IF("force_posix_delete_fail", goto nonposix_delete;); | ||
| FILE_DISPOSITION_INFO_EX disp_ex; | ||
| disp_ex.Flags= FILE_DISPOSITION_FLAG_DELETE|FILE_DISPOSITION_FLAG_POSIX_SEMANTICS; |
vaintroub
force-pushed
the
11.4-MDEV-39533
branch
2 times, most recently
from
October 9, 2026 23:16
675880d to
1aceefa
Compare
On Windows, my_realpath() only called GetFullPathName(), which doesn't resolve symlinks, junctions or mount points, unlike POSIX realpath(). At the same time, my_open() and my_delete() ignored MY_NOSYMLINKS entirely, so Windows silently lacked the symlink-attack protection MyISAM/Aria rely on for DATA DIRECTORY/INDEX DIRECTORY. Fix my_realpath() to resolve reparse points via CreateFile() + GetFinalPathNameByHandle(). A missing path now correctly returns 1/ENOENT on Windows too, matching POSIX. Make my_open()/my_delete() honor MY_NOSYMLINKS by comparing the caller-supplied (already-resolved) name against the opened handle's resolved path, mirroring the realpath()-equality branch of POSIX's NOSYMLINK_FUNCTION_BODY macro, rejecting a mismatch with ENOTDIR. Known limitation: GetFinalPathNameByHandle(FILE_NAME_NORMALIZED) can fail on some SMB shares; both my_realpath() and MY_NOSYMLINKS then fall back to the weaker FILE_NAME_OPENED query, logging a one-time warning naming the affected path. O_NOFOLLOW was plain 0 on Windows, so MyISAM/Aria's data-file open never actually got MY_NOSYMLINKS (only the index file did); it's now a real, reserved bit so that gating works as intended. my_win_unlink() (moved from my_delete.c to my_winfile.cc) now verifies no symlinks before any delete disposition is set, renames through the handle rather than by path, and reports real posix-delete errors (e.g. a read-only file) instead of masking them with a fallback attempt. Add unittest/mysys/my_symlink-t.c and extend my_delete-t.c with my_win_unlink()'s own fallback paths. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
vaintroub
force-pushed
the
11.4-MDEV-39533
branch
from
October 12, 2026 11:16
1aceefa to
7cc18d0
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Summary
On Windows,
my_realpath()only calledGetFullPathName(), whichcanonicalizes
.,..and drive letters but does not resolve NTFSsymlinks, junctions or mount points (unlike POSIX
realpath()). Atthe same time,
my_open()andmy_delete()ignoredMY_NOSYMLINKSentirely, so the symlink-attack protection used for MyISAM/Aria's
DATA DIRECTORY/INDEX DIRECTORY(mi_open()/ma_open(),my_handler_delete_with_symlink()) was silently absent on Windows.my_realpath()to actually resolve reparse points, usingCreateFile()+GetFinalPathNameByHandle(). A missing path nowcorrectly returns
1/ENOENTon Windows too (previously alwaysreturned
0), matching POSIXrealpath().my_open()/my_delete()honorMY_NOSYMLINKSon Windows bycomparing the caller-supplied (expected already-resolved) name
against the actually-opened handle's resolved path, mirroring the
realpath()-equality branch of the POSIXNOSYMLINK_FUNCTION_BODYmacro (same
ENOTDIRerrno for a mismatch).GetFinalPathNameByHandle(FILE_NAME_NORMALIZED)can fail on someSMB shares; both
my_realpath()andMY_NOSYMLINKSverificationfall back to the weaker
FILE_NAME_OPENEDquery in that case, andlog a one-time warning naming the affected path.
MY_NOSYMLINKSwhenO_NOFOLLOWwas set, andO_NOFOLLOWwas plain0on Windows, sothe data file was never actually protected (only the index file
was). Give
O_NOFOLLOWa real, reserved bit on Windows so thatgating works as intended.
my_win_unlink()(moved frommy_delete.ctomy_winfile.cc): verify no symlinks before any delete dispositionis set (closes a window where a rejected delete could still commit
via delete-on-close), rename through the handle rather than by
path, and report real posix-delete errors (e.g. a read-only file)
instead of masking them with a fallback attempt.
Test plan
unittest/mysys/my_symlink-t(17/17): junction resolution andMY_NOSYMLINKSenforcement formy_open()/my_delete().unittest/mysys/my_delete-t(31/31):my_win_unlink()'s ownfallback paths (posix-semantics failure, rename failure,
read-only files, orphan-rename-back).
mainmtr suite (1195/1195) and the full buildbot-matchingsuite set (
vcol,gcol,period,perfschema,parts,main,innodb, versioning,plugins,mariabackup,roles,auth_gssapi,mysql_sha2, rocksdb,sysschema, 2641/2655 -- the 14 failures are unrelatedinnochecksum-tool and audit/error-log-plugin tests, verified
against an unmodified baseline build).
🤖 Generated with Claude Code