{"record":{"id":"d7d7655c4aaa31f5","repo":"unslothai/unsloth","slug":"file-escaped-the-linked-folder","errorCode":null,"errorMessage":"File escaped the linked folder","messagePattern":"File escaped the linked folder","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"studio/backend/core/rag/folder_sync.py","lineNumber":1019,"sourceCode":"                    \"inode\": st.st_ino,\n                    # A recovered identity is comparable to the next scan's, but not to os.fstat's:\n                    # shared-folder and WebDAV drivers report different ids for the two call paths.\n                    \"identity_from_path\": from_path,\n                }\n                if config.FOLDER_MAX_FILES and len(found) > config.FOLDER_MAX_FILES:\n                    raise RuntimeError(\n                        f\"Folder contains more than the {config.FOLDER_MAX_FILES} supported files limit\"\n                    )\n    if _root_identity(root) != identity:\n        raise RuntimeError(\"Linked folder root identity changed during scan\")\n    return found, identity\n\n\ndef _snapshot(root: str, metadata: dict) -> str:\n    source = metadata[\"path\"]\n    resolved = os.path.realpath(source)\n    if not _is_within(root, resolved):\n        raise RuntimeError(\"File escaped the linked folder\")\n    # os.fdopen already forces this descriptor binary on Windows; O_BINARY only guards a raw os.read.\n    flags = os.O_RDONLY | getattr(os, \"O_NOFOLLOW\", 0) | getattr(os, \"O_BINARY\", 0)\n    fd = os.open(source, flags)\n    target = None\n    try:\n        ext = os.path.splitext(source)[1].lower()\n        target = ensure_dir(rag_uploads_root()) / f\"linked-{uuid.uuid4().hex}{ext}\"\n        before = os.fstat(fd)\n        if not stat.S_ISREG(before.st_mode):\n            raise RuntimeError(\"Linked source is not a regular file\")\n        expected = (\n            metadata[\"size_bytes\"],\n            metadata[\"mtime_ns\"],\n            metadata[\"device\"],\n            metadata[\"inode\"],\n        )\n        actual = (before.st_size, before.st_mtime_ns, before.st_dev, before.st_ino)\n        # Only an identity os.fstat can reproduce is comparable here: os.scandir reports none at all","sourceCodeStart":1001,"sourceCodeEnd":1037,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/studio/backend/core/rag/folder_sync.py#L1001-L1037","documentation":"_snapshot() opens each scanned file for copy into the RAG uploads area; before copying it resolves realpath(source) and requires the result to stay inside the linked root via _is_within. Because _scan already skips symlinked entries, an escape means the file was swapped to or overlaid by a symlink between scan and snapshot — a defense against TOCTOU symlink attacks and files moved outside the tree.","triggerScenarios":"Between _scan recording a file and _snapshot processing it, the file is replaced by a symlink pointing outside the root (classic symlink race), or the whole subtree is symlinked during an atomic swap; also hit when a bind-mounted file resolves outside on platforms where realpath crosses bind mounts.","commonSituations":"Malicious or clumsy automation rewriting files into symlinks while a sync runs; partial directory swaps mid-sync; overlay filesystems whose realpath escapes the root.","solutions":["Re-run the sync when the tree is quiescent; the next scan will record the new (symlink-free) state or skip the symlinked file.","Stop whatever is replacing files with symlinks during sync windows (schedule migrations around syncs).","Treat repeated occurrences as a security signal: audit what is mutating the linked folder."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"import os\n\ndef snapshot_target_safe(root: str, source: str) -> bool:\n    if os.path.islink(source):\n        return False\n    resolved = os.path.realpath(source)\n    return os.path.normcase(os.path.commonpath([root, resolved])) == os.path.normcase(root)","typeGuard":null,"tryCatchPattern":"try:\n    ingest_folder(folder_id)\nexcept RuntimeError as e:\n    if \"escaped the linked folder\" in str(e):\n        quarantine_and_alert(folder_id)  # possible symlink attack; do not auto-retry\n    else:\n        raise","preventionTips":["Never replace files inside a linked folder with symlinks while syncing.","Audit automated tooling that rewrites files as symlinks in shared data dirs.","Treat repeated escapes as a security event, not a flaky failure."],"tags":["rag","folder-sync","security","symlink","toctou"],"backgroundTag":null,"analyzedSha":"203007d19051dcd2ae33876786d117c99f6b0368","analyzedAt":"2026-08-15T02:48:39.846Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}