春江暮客

春江暮客的个人学习分享网站

Codex bwrap Loopback Error: An AppArmor Troubleshooting Case on Ubuntu 24.04

2026-10-09 Technology
Codex bwrap Loopback Error: An AppArmor Troubleshooting Case on Ubuntu 24.04

This investigation started with one error:

bwrap: loopback: Failed RTM_NEWADDR: Operation not permitted

Codex CLI 0.162.0 was running on Ubuntu 24.04.5 LTS. Even pwd could not execute through its sandbox. A comparison pointed to AppArmor: temporarily relaxing the unprivileged user namespace restriction let the command run; restoring it brought the sandbox failure back. Loading a dedicated configuration for the system bwrap eventually produced a successful execution record.

This article draws on that ChatGPT troubleshooting conversation and official documentation checked for publication. The original record establishes functional recovery, without validating a complete security policy. The observed workaround and the documented repair path are described separately. Usernames and session identifiers are omitted; /work/project replaces the original working directory in output examples.

Locate the failing operation

bwrap is the bubblewrap command. Its network setup source sends a Netlink RTM_NEWADDR request to add 127.0.0.1/8 to lo, and emits this error if that operation fails.

Start by investigating permission to perform that sandbox setup step. The message alone does not identify AppArmor, an outer container policy, or another restriction as the cause. It does not imply that the host network interface needs reconfiguration.

Collect the environment and correlate denial logs

Run these checks in the Linux environment where the failure occurs:

cat /etc/os-release
codex --version
systemd-detect-virt
id
sysctl kernel.unprivileged_userns_clone user.max_user_namespaces
sysctl kernel.apparmor_restrict_unprivileged_userns
grep -E 'CapEff|Seccomp|NoNewPrivs' /proc/self/status
command -v bwrap

The conversation recorded these results:

Check Observed value What it establishes
OS Ubuntu 24.04.5 LTS Distribution-specific AppArmor policy matters
Codex 0.162.0, standalone installation The case concerns this version
Virtualization detection none The detector identified no virtualization
kernel.unprivileged_userns_clone 1 This namespace switch was enabled
user.max_user_namespaces 4126513 The quota was not zero
AppArmor userns restriction 1 Enabled; logs are needed to connect it to the failure
Checking process CapEff=0, NoNewPrivs=0, Seccomp=0 A snapshot of that process, not future children

Zero effective capabilities in an ordinary user process are insufficient to explain this failure. Ubuntu 24.04 can allow namespace creation while denying later use of capabilities inside it. An enabled userns switch therefore does not establish permission to configure the loopback interface. Ubuntu release notes

Reproduce the error and immediately inspect the matching time window:

sudo journalctl -k --since "5 minutes ago" \
  | grep -Ei 'apparmor|DENIED|userns|bwrap'

These were the important log fields discussed in the conversation:

apparmor="DENIED" operation="capable" profile="unprivileged_userns" capability=12 capname="net_admin"

The conversation also mentioned a setpcap denial. The network-management denial fits the loopback failure, but correlate timestamps, PIDs, and process names before attributing a log entry to Codex. The sysctl value alone is insufficient evidence.

Make the test reach the shell command

One diagnostic run stopped with a different error:

Not inside a trusted directory and --skip-git-repo-check was not specified.

That run stopped at the repository check and did not test successful sandbox execution. In a test directory you control, use:

codex exec --skip-git-repo-check 'pwd'

This flag addresses the repository check; it does not grant AppArmor permissions. In this case, temporarily relaxing the restriction produced a real command execution record. After restoration, the same test failed again. Together with the denial logs, that comparison implicated AppArmor.

There was another trap: after a failed tool execution, Codex answered with the working directory from its environment context. A path in the final response is insufficient proof. Check for the shell command, its succeeded record, and its actual output.

Check the distribution bwrap profile first

Initially, bwrap was absent from PATH, while Codex reported a bundled helper. Installing system bubblewrap still left a sandbox failure. Having the executable and having the required policy are separate checks.

The official OpenAI sandbox documentation describes PATH selection and an extra Ubuntu 24.04 AppArmor profile. The following is that documented repair path; it was not the configuration tested in the original conversation.

Install the packages and inspect the executable:

sudo apt update
sudo apt install bubblewrap apparmor-profiles apparmor-utils
command -v bwrap
readlink -f "$(command -v bwrap)"
bwrap --version

Check existing policy and the additional profile file:

sudo aa-status
sudo grep -R -n -E 'bwrap|bubblewrap' /etc/apparmor.d
ls -l /usr/share/apparmor/extra-profiles/bwrap-userns-restrict

Package versions and local changes matter. Read and back up any existing destination file. Avoid overwriting custom policy or installing competing profiles for the same executable. If the source file is absent, check the package version and repository first.

When the source exists and no conflicting policy is present, copy and load it:

sudo install -m 0644 \
  /usr/share/apparmor/extra-profiles/bwrap-userns-restrict \
  /etc/apparmor.d/bwrap-userns-restrict
sudo apparmor_parser -r /etc/apparmor.d/bwrap-userns-restrict

Verify policy state and repeat the test:

sysctl kernel.apparmor_restrict_unprivileged_userns
sudo aa-status | grep -i bwrap
codex exec --skip-git-repo-check 'pwd'

If it fails, inspect fresh logs, especially whether the process still lands under profile="unprivileged_userns". Confirm which executable actually runs. Finding a bwrap on PATH identifies a candidate; it does not independently prove that a particular execution matched the intended profile.

What restored the original case

The final part of the conversation identified /usr/bin/bwrap. With no dedicated bwrap profile visible in the reported checks, the following permissive test configuration was created and loaded:

abi <abi/4.0>,

include <tunables/global>

profile bwrap /usr/bin/bwrap flags=(unconfined) {
    userns,

    capability net_admin,
    capability setpcap,
}

Its file was /etc/apparmor.d/usr.bin.bwrap. The subsequent pwd test produced this execution record, with the directory replaced by an example value:

sandbox: read-only

/usr/bin/zsh -lc pwd
succeeded in 0ms:
/work/project

That establishes functional recovery in this case. The unconfined flag makes this a permissive profile; the two capability entries do not turn it into a minimal allowlist. Its attachment targets /usr/bin/bwrap, beyond a single Codex invocation. Ubuntu describes this profile mode in its release notes.

The procedure included restoring the global restriction to 1. However, the final successful run was not followed by fresh sysctl and profile-status output. The record supports successful execution, without proving a complete security review or that every subsequent workload will succeed.

If this custom configuration is already installed, back it up, unload the test profile, and move its policy file out of /etc/apparmor.d before replacing it with the distribution profile. Inspect attachment paths instead of loading both and hoping they work together.

Preserve the original value during temporary diagnostics

The conversation used kernel.apparmor_restrict_unprivileged_userns=0 for comparison. This affects the whole host and belongs only in an administrator-controlled environment where a brief change is acceptable. Try the distribution policy first. If a comparison is still needed, preserve the original value and restore it on exit.

This Bash script restores the value it read, rather than assuming the previous setting was 1:

#!/usr/bin/env bash
set -euo pipefail

sudo -v
original_userns=$(sysctl -n kernel.apparmor_restrict_unprivileged_userns)

restore_userns() {
  sudo sysctl -w "kernel.apparmor_restrict_unprivileged_userns=${original_userns}"
}
trap restore_userns EXIT
trap 'exit 130' INT
trap 'exit 143' TERM

sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0
codex exec --skip-git-repo-check 'pwd'

An exit trap cannot handle power loss or SIGKILL, and restoration can itself fail. Check sysctl kernel.apparmor_restrict_unprivileged_userns afterward and restore the recorded value if necessary. Do not persist the diagnostic value of 0 in a sysctl configuration file.

Verify the same operation before testing more

Keep the user, directory, and sandbox mode consistent for the first retest. Confirm actual tool execution, the intended loaded profile, the expected global restriction value, and the absence of related denials in that time window. Then test the reads, writes, or network operations required by the real project. A successful pwd covers only a minimal execution path.

Docker and LXC require separate investigation of the outer container policy. This case’s systemd-detect-virt result cannot be generalized to containers, and Seccomp=0 in the checking process does not establish the policy of every later child.

The two misleading checkpoints in this case were a run stopped by repository validation and a directory supplied from model context after execution failed. Correlating the original error, matching denial logs, and real tool output identifies which step the repair actually changed.

标签

1024 ablang adsense agents.md ai ai-agent ai-agents ai-seo algorithm amp antibodies apparmor argparse automation background backup bash batch-processing binarycif bioinformatics biopython blockchain boltz bootstrapping boxes bubblewrap c-index cca cdn checkpoint cli cloudflare codex cofoldarena copy cpu monitoring cron csv cuda curl data-leakage data-processing data-quality data-validation datascience datavisualization datetime debugging decimal deployment desktop-app devtools disk-space disown dns docker dovecot download economics electron encoding esm esm2 esm3 esmc esmfold2 fable faceswap fasta fastmcp faulthandler ffmpeg file-descriptors file-io flashppi flask folium frontend game generator git github-actions google google-research grep gzip harness hls html http hugo imports indexnow javascript jev json jsonl just k-means kaggle langfuse leecode linux list litellm llm llms.txt logging logs lollipop lsof m3u8 machine-learning macos manacher matplotlib mcp mirror mmcif model-evaluation monitoring mp3 mp4 mpnn multiomics mutation mysql nanobert nanobodies networkx nginx normalize numpy ollama omegatherm pandas password pathlib pdb pep-723 phaser pillow pip postfix preprocessing print probability protein-alignment protein-design protein-embeddings protein-interactions protein-language-models protein-stability protein-structure proxy pydantic pyecharts pyqt python python3 r raincloud reproducibility requests reservoir-sampling rfoptimization rg ripgrep rosettafold3 roundcube rrsi rsi rsync s-tui sampling scale scikit-learn scrapy screen seaborn security seo sequence-identity sha256 shell signals sklearn socket solana somaticsignatures spl sqlite ssh standardize static-site subprocess symlink sysadmin system-one tarfile tcp tensorflow tkinter tls toml trade tron tronpy troubleshooting turtle typesafe-ai ubuntu unicode usdt utf-8 uv vhhbert vite wallet webp wordcloud wordpress workflow yaml zipfile zoneinfo 迅雷解析

友情链接

其它