Exhaustive audit (workflow: 19 finders + adversarial per-file verify; 85 raw -> 66 unique -> 39 confirmed) found 36 direct writes into the container-owned tree that bypass runFileOp/runFileWrite/runCfgOp (manager => EACCES in rootless) plus 3 $?-masking sites. Fixes by area: - apps: grafana + prometheus install hooks (sudo chmod -> runFileOp chmod); gluetun provider etag (tee -> runFileWrite). - webui generators: task-create (10 sites: mkdir/chown/tee/jq|tee/sed|tee -> runFileOp/runFileWrite); app-icons (mkdir/cp/mv); config icon cp; system metrics + update throttle stamps (runAsManager touch -> runFileOp touch); setup-lock rm; updater history seed + cp. - task health checker: 4 log writes (tee -a -> runFileWrite -a) + 3 find -delete (-> runFileOp find). - config reconcile: backup cp -> runCfgOp; live cp -> runFileWrite < tmp for container-owned configs (the container user can't read a manager 0600 tmp). - peer pull: tar extract into the container tree -> runFileOp tar. - masking: ip_find_available + folder_group(x2) — split 'local VAR=$(cmd)' so $? reaches the following [[ $? ]] check. 15 files, all pass bash -n; fixed idioms confirmed gone. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: librelad <librelad@digitalangels.vip>
47 lines
1.7 KiB
Bash
Executable File
47 lines
1.7 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# Find available IP in pool with randomization
|
|
ipFindAvailable()
|
|
{
|
|
# Extract subnet base from CFG_NETWORK_SUBNET and use hardcoded sensible defaults
|
|
local subnet_base=$(echo "$CFG_NETWORK_SUBNET" | cut -d'/' -f1 | cut -d'.' -f1-3)
|
|
local start_last=2 # Hardcoded sensible default: .2
|
|
local end_last=254 # Hardcoded sensible default: .254
|
|
|
|
local existing_ips; existing_ips=$(runInstallOp sqlite3 "$docker_dir/$db_file" "SELECT resource_value FROM network_resources WHERE resource_type = 'ip' AND status = 'active';" 2>/dev/null)
|
|
if [[ $? -ne 0 ]]; then
|
|
isError "Database query failed while checking existing IPs"
|
|
available_ip=""
|
|
fi
|
|
|
|
# Create an array to store available IPs
|
|
local available_ip_pool=()
|
|
|
|
# Randomization: Shuffle the IP range
|
|
local ip_range=($(seq $start_last $end_last | shuf))
|
|
|
|
for i in "${ip_range[@]}"; do
|
|
# Skip reserved IPs (1=gateway, 254=broadcast)
|
|
if [[ $i -eq 1 || $i -eq 254 ]]; then
|
|
continue
|
|
fi
|
|
|
|
local test_ip="${subnet_base}.${i}"
|
|
|
|
# Check if IP is already allocated
|
|
if [[ "$existing_ips" != *"$test_ip"* ]]; then
|
|
available_ip_pool+=("$test_ip")
|
|
fi
|
|
done
|
|
|
|
# Check if we have any available IPs
|
|
if [[ ${#available_ip_pool[@]} -eq 0 ]]; then
|
|
isError "No available IP addresses in subnet $CFG_NETWORK_SUBNET and all expansion ranges exhausted"
|
|
available_ip=""
|
|
fi
|
|
|
|
# Randomly select an IP from the available pool
|
|
local random_index=$((RANDOM % ${#available_ip_pool[@]}))
|
|
available_ip="${available_ip_pool[$random_index]}"
|
|
}
|