gioser

sergio/takana

> Una distribución Linux construida con un laboratorio funcional y hermético en el > sótano, y una terminal mutable, clásica y anárquica en el piso de arriba — diseñada > desde el suelo para que una IA programadora entienda, modifique y co…

TOML 815Rust 56Shell 37Markdown 291229 Definitions

⎇ 534014c3ec69daea789a1d0523e1d00a69c6ed65 scripts/probar-fusion-privilegio.sh Shell · 59 lines · 3.4 KB History raw

fix(prueba): el test de la fusion moria en silencio y pasaba por verde ff40c91ba · sergio ·

1#!/bin/sh
2# Prueba del bloque REAL de liberación de symlinks: se extrae del propio instalador-variantes.sh
3# (no una copia) y se corre contra un árbol de juguete. Lo que se mide es si `bin/su` de shadow
4# llega entero al árbol compuesto en vez de quedar tapado por el symlink a busybox del piso.
5set -eu
6cd "$(cd "$(dirname "$0")/.." && pwd)"
7W=/tmp/probar-fusion.$$
8trap 'rm -rf "$W"' EXIT
9C="$W/C"; H="$W/H"
10mkdir -p "$C/bin" "$C/usr/bin" "$H/bin" "$H/usr/bin"
11
12# El piso: busybox y sus symlinks (lo que trae product-rootfs).
13printf 'soy busybox\n' > "$C/bin/busybox"; chmod 755 "$C/bin/busybox"
14ln -s busybox "$C/bin/su"
15ln -s ../../bin/busybox "$C/usr/bin/passwd"
16ln -s busybox "$C/bin/ls"          # un applet SIN [[setuid]]: NO debe tocarse
17# El perfil: los binarios de verdad, ya con su bit (como los deja `setuid --apply`).
18printf 'soy el su de shadow\n' > "$H/bin/su"; chmod 4755 "$H/bin/su"
19printf 'soy el passwd de shadow\n' > "$H/usr/bin/passwd"; chmod 4755 "$H/usr/bin/passwd"
20printf 'soy el ls de uutils\n' > "$H/bin/ls"; chmod 755 "$H/bin/ls"
21
22p=base
23# ⚠ Sin el binario del verbo no hay nada que medir: el bloque pregunta las rutas declaradas con
24# `takana setuid --json`. Se SALTA diciéndolo (exit 2), que no es lo mismo que pasar.
25[ -x ./target/release/takana ] || {
26	echo "  ⊘ SALTADO: falta ./target/release/takana — el bloque no puede preguntar las declaraciones"
27	exit 2
28}
29# ── el bloque REAL, extraído del script que va a correr ────────────────────────────────────────
30sed -n '/^        _recetas_p=""/,/^        \[ "\$_liberados" -gt 0 \]/p' scripts/instalador-variantes.sh > "$W/bloque.sh"
31[ -s "$W/bloque.sh" ] || { echo "✗ no pude extraer el bloque del armador"; exit 1; }
32echo "   (bloque extraído: $(wc -l < "$W/bloque.sh") líneas)"
33# `set +e` alrededor del bloque: su última línea es un `[ ... ] && echo`, que devuelve 1 cuando no
34# libera nada, y con `set -e` eso mataba el test antes de comprobar una sola cosa. Un test que muere
35# en silencio pasa por verde.
36set +e
37. "$W/bloque.sh"
38set -e
39# ── y la copia que viene después, igual que en el armador ──────────────────────────────────────
40( cd "$H" && find . -type d -exec mkdir -p "$C/{}" \; ) 2>/dev/null || true
41( cd "$H" && find . ! -type d -exec cp -a -l -n {} "$C/{}" \; ) 2>/dev/null || true
42
43echo "══ cómo quedó el árbol compuesto ══"
44fallo=0
45for b in bin/su usr/bin/passwd; do
46	if [ -L "$C/$b" ]; then echo "  ✗ $b sigue siendo un symlink a $(readlink "$C/$b")"; fallo=1
47	elif [ "$(stat -c%a "$C/$b")" = 4755 ] && grep -q shadow "$C/$b"; then
48		echo "  ✓ $b es el binario de shadow, 4755"
49	else echo "  ✗ $b quedó raro: $(stat -c%A "$C/$b")"; fallo=1; fi
50done
51# El brazo de control: un applet sin declaración NO se toca. Si se tocara, este arreglo habría
52# dejado de estar acotado y estaría reemplazando los 331 symlinks sin medición.
53if [ -L "$C/bin/ls" ] && [ "$(readlink "$C/bin/ls")" = busybox ]; then
54	echo "  ✓ bin/ls (sin [[setuid]]) sigue siendo el applet: el arreglo está acotado"
55else
56	echo "  ✗ bin/ls se tocó, y no tiene declaración de privilegio"; fallo=1
57fi
58[ -f "$C/bin/busybox" ] || { echo "  ✗ se perdió el busybox del piso"; fallo=1; }
59[ "$fallo" = 0 ] && echo "✓✓ la fusión deja pasar el binario privilegiado y no toca lo demás" || exit 1