T09 · Insecure Skill Coding Practices
- Location
scripts/office/soffice.py:28- Finding
Predictable Shared Temporary Library Enables LD_PRELOAD Code Execution
- Content
View full analysis
Vulnerability Details
File Location:
scripts/office/soffice.py:28-30, 41, 49-64
Vulnerability Type: Unsafe temporary file handling leading to local code execution
Risk Level: HighVulnerable Code
python def get_soffice_env() -> dict: env = os.environ.copy() env["SAL_USE_VCLPLUGIN"] = "svp" if _needs_shim(): shim = _ensure_shim() env["LD_PRELOAD"] = str(shim) return envpython _SHIM_SO = Path(tempfile.gettempdir()) / "lo_socket_shim.so"python def _ensure_shim() -> Path: if _SHIM_SO.exists(): return _SHIM_SO src = Path(tempfile.gettempdir()) / "lo_socket_shim.c" src.write_text(_SHIM_SOURCE) subprocess.run( ["gcc", "-shared", "-fPIC", "-o", str(_SHIM_SO), str(src), "-ldl"], check=True, capture_output=True, ) src.unlink() return _SHIM_SOThe resulting environment is used at
scripts/thumbnail.py:161-174when launching LibreOffice:python result = subprocess.run( [ "soffice", "--headless", "--convert-to", "pdf", "--outdir", str(temp_dir), str(pptx_path), ], capture_output=True, text=True, env=get_soffice_env(), )Technical Analysis
When the host blocks creation of
AF_UNIXsockets,_needs_shim()returnsTrueand_ensure_shim()supplies a native library throughLD_PRELOAD.The library path is the fixed, predictable name
/tmp/lo_socket_shim.so. If that path already exists, the code trusts it solely based onPath.exists(). It does not verify that the object:- Is a regular file rather than a symlink or another special object.
- Is owned by the current user.
- Has safe permissions.
- Was generated from the embedded source.
- Has an expected digest or other integrity property.
The source path
/tmp/lo_socket_shim.cis likewise predictable and created without a private temporary directory or exclusive file creation. These pro ...[truncated 2006 chars]- Remediation
View remediation
Remediation Suggestions
- Create a unique private temporary directory with permissions set to
0700, such as throughtempfile.TemporaryDirectory(). - Place both the C source and compiled library inside that private directory rather than directly under the shared system temporary directory.
- Use exclusive creation semantics and reject symlinks when creating files.
- Do not reuse a library merely because a fixed path exists. Generate it for each trusted execution or maintain it in an application-owned directory unavailable to other users.
- Before assigning the library to
LD_PRELOAD, verify withlstat()that it is a regular file, is owned by the current effective user, and is not writable by group or other users. - Where reuse is necessary, verify the library against a trusted digest and protect both the directory and file from modification.
- Compile to a unique temporary output and atomically rename it only within the same private directory.
- Remove the source, library, and private directory after LibreOffice exits.
- Consider avoiding
LD_PRELOADentirely by configuring LibreOffice through a supported sandbox-compatible mechanism.
- Create a unique private temporary directory with permissions set to
