Mtro. Carlos Alberto Román Zamitiz · 27 ago 2026 · Tema 1 — Permisos UGO y chmod decimal, bit SetUID (chmod 4xxx), /etc/passwd, ID real vs. efectivo, Tarea 2, y fork() (retorno pid_t, PID del hijo al padre / 0 al hijo, deadlock).
Regla mnemotécnica: "ugo" (como "Hugo" sin H) → Usuario (dueño), Grupo, Otros. chmod = change mode.
r w x
4 2 1 rwx = 4+2+1 = 7 rw- = 6 r-x = 5
chmod 777 archivo — todos los permisos para u, g y o.chmod 644 archivo — archivo editable no ejecutable: dueño rw (6), grupo y otros r (4).chmod 755 archivo — ejecutable típico: dueño rwx (7), grupo y otros r-x (5).Al ejecutar un binario, el proceso normalmente pertenece a quien lo ejecuta. Con el bit SetUID activo, quien lo ejecuta toma temporalmente los privilegios del dueño del archivo mientras dura la ejecución.
Se activa con un cuarto dígito a la izquierda en chmod, que indica sobre qué bloque:
4 = SetUID (bloque de usuario) ← el más usado
2 = SetGID (bloque de grupo)
1 = sticky (bloque de otros)
ej. chmod 4511 archivo
⚠️ Riesgo de seguridad: si root pone SetUID a un ejecutable, cualquier usuario sin privilegios se vuelve root durante esa ejecución. Manejar con extrema precaución.
/etc/passwd. Se obtiene con getuid() (igual que getpid() / getppid()).geteuid() (la "e" = effective).cat /etc/passwd — campos separados por :
username : x : UID : GID : nombre_real : /home/... : shell
| | | | | | |
el 1º contraseña id id de GECOS (si no dir. tipo de
es root oculta usuario grupo se puso, =user) home shell
Usuarios de sistema con shell nologin: no pueden iniciar sesión interactiva (seguridad). [inaudible: la ruta se oye como "etc/al passworden"]
Metodología: dos terminales (una como root, otra como usuario sin privilegios). Las instrucciones de pantalla dividida en Codespaces están en la carpeta del Tema 3 del repo, aunque se usan desde el Tema 1. whoami muestra el usuario activo.
fdisk = comando solo-root para manipular la tabla de particiones (man fdisk). Sirve cualquier comando que pida privilegios. Pasos:
# 1) como usuario NO root:
fdisk -l # -> "permiso denegado"
# (en Fedora puede solo regresar el prompt vacío)
# 2) como root, ver permisos actuales:
ls -l /sbin/fdisk # -> 755 (rwxr-xr-x)
# 3) como root, activar SetUID:
chmod 4511 /sbin/fdisk # -> r-s--x--x (la 's' en vez de 'x' = SetUID activo;
# el nombre se ve en rojo si hay color)
# 4) como usuario NO root otra vez:
fdisk -l # -> AHORA SÍ funciona: lista las particiones
# 5) OBLIGATORIO: revertir de inmediato
chmod 755 /sbin/fdisk # (o los permisos que tuviera antes)
[inaudible: la ruta se dicta rápido como "diagonal se bin diagonal fis" → /sbin/fdisk]
Actividad 2: programa en C (programa02_ids.c en el repo) que imprime getuid() y geteuid(). Compilar gcc programa02_ids.c -o programa02_ids. Ejecutado normal → ID real == ID efectivo. Aplicando chmod 4511 al binario y ejecutándolo con otro usuario → salen distintos.
⚠️ Para sacar 10: las capturas deben mostrar ID real ≠ ID efectivo.
⚠️ No entregar la Tarea 2 todavía — el profesor no pudo hacer la demo en el laboratorio; reactivará la fecha de entrega después. (Recomienda clonar el repo localmente con git en vez de usar Codespaces.)
fork(), padre e hijo corren en paralelo y asíncronos (ráfagas de CPU alternadas).Retorno (tipo pid_t, encapsula un entero; se imprime con %d / %i):
al PADRE -> el PID del hijo (entero != 0)
al HIJO -> 0
La variable donde guardas el retorno se duplica: en el padre vale el PID del hijo, en el hijo vale 0. Se separa el código con:
if (id_hijo != 0) {
// código exclusivo del padre
} else {
// código exclusivo del hijo
}
Sin if, todo lo que va después de fork() se ejecuta en ambos → sale duplicado. En programa05_fork_v1.c: la línea de antes del fork() se imprime una vez; las dos de después, dos veces cada una.
Nota semántica del profesor: antes del fork() lo llama "proceso main / principal"; "padre" solo cuando ya hay hijo.
Si el padre espera a que termine el hijo para continuar y a la vez el hijo espera a que termine el padre → bloqueo indefinido. Única salida: Ctrl + C.
Valores de esa corrida (programa05_fork_v2.c):
| Dato | Valor |
|---|---|
| PID del padre | 30405 |
| PID del hijo | 30406 (el entero inmediato siguiente) |
id_hijo en el padre | 30406 |
id_hijo en el hijo | 0 |
getpid() en el hijo | 30406 |
getppid() en el padre | PID de la shell (bash) que lanzó el programa |
getppid() en el hijo | 30405 (su creador es el padre) |
El if puede ser != 0 (padre primero) o == 0 (hijo primero), a gusto del programador.
Tarea moral (sin entrega): leer con calma el PDF 2 del Tema 1 (procesos).
Teoría general de procesos, ejemplos en C y los programas del profesor están en el Tema 1.