Goal Reached Thanks to every supporter — we hit 100%!

Goal: 1000 CNY · Raised: 1000 CNY

100.0%

CVE-2025-52881 PoC — runc: LSM labels can be bypassed with malicious config using dummy procfs files

Source
Associated Vulnerability
Title:runc: LSM labels can be bypassed with malicious config using dummy procfs files (CVE-2025-52881)
Description:runc is a CLI tool for spawning and running containers according to the OCI specification. In versions 1.2.7, 1.3.2 and 1.4.0-rc.2, an attacker can trick runc into misdirecting writes to /proc to other procfs files through the use of a racing container with shared mounts (we have also verified this attack is possible to exploit using a standard Dockerfile with docker buildx build as that also permits triggering parallel execution of containers with custom shared mounts configured). This redirect could be through symbolic links in a tmpfs or theoretically other methods such as regular bind-mounts. While similar, the mitigation applied for the related CVE, CVE-2019-19921, was fairly limited and effectively only caused runc to verify that when LSM labels are written they are actually procfs files. This issue is fixed in versions 1.2.8, 1.3.3, and 1.4.0-rc.3.
Description
Workaround for CVE-2025-52881: Fixes Docker/Podman breakage in Proxmox LXC containers caused by AppArmor incompatibility with runc 1.2.7+. Universal wrapper for community-scripts with automatic AppArmor configuration.
Readme
# Proxmox LXC AppArmor Fix for Docker/Containers

> **Workaround for CVE-2025-52881**: Fixes Docker, Podman, and container runtime breakage in Proxmox LXC containers caused by AppArmor incompatibility with runc 1.2.7+/1.3.2+

## 🚨 The Problem

Recent security updates to `runc` (versions 1.2.7+ and 1.3.2+) and `containerd` (1.7.28-2+) introduced a breaking incompatibility with AppArmor when running inside Proxmox LXC containers. This causes Docker and other container runtimes to fail with errors like:

```
OCI runtime create failed: unable to start container process:
error during container init: open sysctl net.ipv4.ip_unprivileged_port_start file:
reopen fd 8: permission denied
```

This affects:
- ✗ Proxmox community scripts (docker.sh, komodo.sh, dockge.sh, casaos.sh, etc.)
- ✗ Manual Docker/Podman installations in LXC
- ✗ Any container runtime using runc inside LXC containers

**Reference**: [opencontainers/runc#4968](https://github.com/opencontainers/runc/issues/4968)

## ⚠️ DO NOT Downgrade runc

While downgrading runc below 1.2.7/1.3.2 would "fix" the issue, it exposes your system to **actual privilege escalation vulnerabilities** that the security update patched. The workaround in this repository is the recommended approach.

## ✅ The Solution

This repository provides tools that automatically apply and manage the AppArmor workaround for Proxmox LXC containers:

1. **`pve-script-wrapper.sh`** - Universal wrapper for Proxmox community scripts
2. **`pve-docker-fix`** - Fix existing containers that are already broken
3. **`pve-docker-rollback`** - Remove the workaround when upstream fixes are available
4. **`pct-patched`** - Internal wrapper (used automatically by pve-script-wrapper.sh)

### How It Works

The scripts automatically detect your container's OS and apply the appropriate AppArmor workaround:

**For all containers:**
```conf
lxc.apparmor.profile: unconfined
```

**For Ubuntu containers only:**
```conf
lxc.mount.entry: /dev/null sys/module/apparmor/parameters/enabled none bind 0 0
```

The first line disables AppArmor confinement (required for all distributions). The second line masks the AppArmor module detection and is only needed for Ubuntu containers - Debian containers typically work without it ([runc#4968](https://github.com/opencontainers/runc/issues/4968)).

**OS Auto-Detection:** The scripts automatically detect whether your container is Ubuntu or Debian and apply only the necessary configuration lines.

## 📦 Installation

On your Proxmox VE host, run:

```bash
# Download all scripts
curl -fsSL https://raw.githubusercontent.com/jq6l43d1/proxmox-lxc-docker-fix/main/pve-script-wrapper.sh -o /usr/local/bin/pve-script-wrapper.sh
curl -fsSL https://raw.githubusercontent.com/jq6l43d1/proxmox-lxc-docker-fix/main/pct-patched -o /usr/local/bin/pct-patched
curl -fsSL https://raw.githubusercontent.com/jq6l43d1/proxmox-lxc-docker-fix/main/pve-docker-fix -o /usr/local/bin/pve-docker-fix
curl -fsSL https://raw.githubusercontent.com/jq6l43d1/proxmox-lxc-docker-fix/main/pve-docker-rollback -o /usr/local/bin/pve-docker-rollback

# Make them executable
chmod +x /usr/local/bin/pve-script-wrapper.sh /usr/local/bin/pct-patched /usr/local/bin/pve-docker-fix /usr/local/bin/pve-docker-rollback
```

Or clone the repository:

```bash
git clone https://github.com/jq6l43d1/proxmox-lxc-docker-fix.git
cd proxmox-lxc-docker-fix
chmod +x *.sh pct-patched pve-docker-fix pve-docker-rollback
cp pve-script-wrapper.sh pct-patched pve-docker-fix pve-docker-rollback /usr/local/bin/
```

## 🚀 Usage

### Running Community Scripts with Automatic Fix

Instead of:
```bash
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/komodo.sh)"
```

Use:
```bash
pve-script-wrapper.sh https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/komodo.sh
```

This works with **any** Proxmox community script that creates LXC containers:

```bash
# Docker
pve-script-wrapper.sh https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/docker.sh

# Dockge
pve-script-wrapper.sh https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/dockge.sh

# CasaOS
pve-script-wrapper.sh https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/casaos.sh

# Podman
pve-script-wrapper.sh https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/podman.sh

# And any other script that installs container runtimes
```

### Fixing Existing Containers

If you already have a broken container:

```bash
# Fix container 105
pve-docker-fix 105

# Fix without automatic restart
pve-docker-fix 105 --no-restart
```

The tool will:
1. Check if the fix is already applied
2. Stop the container (with confirmation)
3. Apply the AppArmor workaround
4. Restart the container

### Manual Fix

If you prefer to apply the fix manually:

```bash
# Stop the container
pct stop 105

# Edit the config file
nano /etc/pve/lxc/105.conf

# Add this line at the end (required for all containers):
lxc.apparmor.profile: unconfined

# For Ubuntu containers, also add this line:
lxc.mount.entry: /dev/null sys/module/apparmor/parameters/enabled none bind 0 0

# Start the container
pct start 105
```

**Note:** Debian containers typically only need the first line. Ubuntu containers need both lines. See [runc#4968](https://github.com/opencontainers/runc/issues/4968) for technical details.

### Rolling Back the Fix

When upstream fixes are available (Proxmox/LXC/AppArmor updates), you can remove the workaround:

```bash
# List all containers with the workaround
pve-docker-rollback --list

# Remove from specific container
pve-docker-rollback 105

# Preview changes without modifying
pve-docker-rollback 105 --dry-run

# Remove from all containers at once
pve-docker-rollback --all

# Remove without restart (changes apply on next start)
pve-docker-rollback 105 --no-restart

# Remove from all containers without confirmation
pve-docker-rollback --all --force
```

The rollback tool will:
1. Detect if the workaround is applied
2. Show which lines will be removed
3. Request confirmation (unless `--force`)
4. Remove the AppArmor configuration
5. Restart the container if needed

**When to rollback:**
- Wait for announcements that upstream fixes are available
- Monitor [runc#4968](https://github.com/opencontainers/runc/issues/4968) for updates
- Test on non-critical containers first
- Verify Docker/containers work after rollback before removing from production

## 🔧 How It Works Technically

### pve-script-wrapper.sh
- Creates a temporary directory with a symlink to `pct-patched`
- Modifies `PATH` to prioritize the wrapper
- Downloads and executes the community script
- The script transparently uses the patched `pct` command

### pct-patched
- Intercepts `pct create` commands
- Calls the real `/usr/sbin/pct` to create the container
- Detects container OS type (Ubuntu vs Debian)
- Immediately after creation, injects appropriate AppArmor configuration into `/etc/pve/lxc/$CTID.conf`
- Passes through all other `pct` commands unchanged

### pve-docker-fix
- Standalone tool for fixing existing containers
- Detects container OS type automatically
- Checks if fix is already applied (idempotent)
- Applies only necessary configuration lines based on OS
- Handles container stop/start with user confirmation
- Safe to run multiple times

### pve-docker-rollback
- Removes the AppArmor workaround when no longer needed
- Scans all containers to find those with workaround applied
- Safely removes comment blocks and configuration lines
- Supports single container, batch (--all), or list mode
- Dry-run mode to preview changes before applying
- Handles container restart with confirmation
- Idempotent and safe to run multiple times

## 🛡️ Security Considerations

### What This Changes
- Disables AppArmor confinement for the LXC container
- Removes one layer of defense-in-depth

### What's Still Protected
- Container is still **unprivileged** (most important security boundary)
- Kernel namespaces still enforce isolation
- cgroups resource limits still apply
- Standard Linux permissions still active

### Risk Assessment
- **Risk**: Slightly reduced isolation if container is compromised
- **Mitigation**: Containers remain unprivileged, which is the primary security control
- **Comparison**: Much safer than downgrading runc and exposing actual CVEs

### When NOT to Use This
- Production environments requiring maximum isolation
- Multi-tenant systems with untrusted containers
- Containers running untrusted code

### Alternatives
- Wait for upstream fixes (Proxmox/LXC/AppArmor/kernel)
- Use privileged containers (NOT recommended - worse security)
- Use VMs instead of containers (more overhead)

## 📋 Affected Systems

### Confirmed Affected
- Proxmox VE 8.x with recent updates
- Debian 12 (Bookworm) LXC containers
- Ubuntu LXC containers (all recent versions)
- runc versions 1.2.7+ and 1.3.2+
- containerd version 1.7.28-2+

### OS-Specific Notes
- **Debian containers**: Typically only need `lxc.apparmor.profile: unconfined`
- **Ubuntu containers**: Need both config lines (profile + mount entry)
- Scripts auto-detect OS and apply appropriate fix

### Community Scripts Known to Be Affected
- docker.sh
- komodo.sh
- dockge.sh
- casaos.sh
- podman.sh
- runtipi.sh
- omv.sh (OpenMediaVault)
- alpine-docker.sh
- podman-homeassistant.sh
- And 390+ other container-based scripts

## 🔗 References

- **Primary Issue**: [opencontainers/runc#4968](https://github.com/opencontainers/runc/issues/4968)
- **CVE**: CVE-2025-52881
- **Related CVEs**: CVE-2025-31133, CVE-2025-52565
- **Proxmox Forum Discussion**: [Community Scripts Issue #8890](https://github.com/community-scripts/ProxmoxVE/issues/8890)
- **Incus Fix**: [PR #2624](https://github.com/lxc/incus/pull/2624)

## 🐛 Troubleshooting

### Script doesn't work
```bash
# Verify scripts are executable
ls -l /usr/local/bin/pve-script-wrapper.sh /usr/local/bin/pct-patched

# Make them executable if needed
chmod +x /usr/local/bin/pve-script-wrapper.sh /usr/local/bin/pct-patched
```

### Docker still fails after applying fix
```bash
# Verify the fix was applied
grep -i apparmor /etc/pve/lxc/105.conf

# Check detected OS type
pct config 105 | grep ostype

# For Ubuntu containers, ensure both lines are present:
# - lxc.apparmor.profile: unconfined
# - lxc.mount.entry: /dev/null sys/module/apparmor/parameters/enabled...

# If not present, apply manually
pve-docker-fix 105

# Check container is restarted
pct status 105
```

### Container won't start after fix
```bash
# Check for syntax errors in config
cat /etc/pve/lxc/105.conf

# View detailed error messages
journalctl -xe
```

## 🤝 Contributing

Contributions welcome! Please:
1. Test your changes on a Proxmox VE system
2. Update documentation if adding features
3. Follow existing code style
4. Submit a PR with clear description

## 📝 License

GNU GENERAL PUBLIC LICENSE - See LICENSE file for details

## 🙏 Acknowledgments

- [opencontainers/runc](https://github.com/opencontainers/runc) team for the security fixes
- [community-scripts/ProxmoxVE](https://github.com/community-scripts/ProxmoxVE) maintainers
- All contributors to the issue discussions

## ⚡ Quick Reference

```bash
# Install
curl -fsSL https://raw.githubusercontent.com/jq6l43d1/proxmox-lxc-docker-fix/main/install.sh | bash

# Run community script with fix
pve-script-wrapper.sh <script-url>

# Fix existing container
pve-docker-fix <container-id>

# List containers with workaround
pve-docker-rollback --list

# Remove workaround (when upstream fixes available)
pve-docker-rollback <container-id>
pve-docker-rollback --all

# Get help
pve-script-wrapper.sh --help
pve-docker-fix --help
pve-docker-rollback --help
```

---

**Note**: This is a temporary workaround until upstream projects release permanent fixes. Monitor the referenced GitHub issues for updates.
File Snapshot

[4.0K] /data/pocs/245a2675401f16697c68919544f1b64927912e32 ├── [2.2K] install.sh ├── [ 34K] LICENSE ├── [2.0K] pct-patched ├── [4.3K] pve-docker-fix ├── [9.2K] pve-docker-rollback ├── [2.5K] pve-script-wrapper.sh └── [ 12K] README.md 1 directory, 7 files
Shenlong Bot has cached this for you
Remarks
    1. It is advised to access via the original source first.
    2. Local POC snapshots are reserved for subscribers — if the original source is unavailable, the local mirror is part of the paid plan.
    3. Mirroring, verifying, and maintaining this POC archive takes ongoing effort, so local snapshots are a paid feature. Your subscription keeps the archive online — thank you for the support. View subscription plans →