Gestisco una scatola indurita di Gentoo che utilizza le capacità dei file per eliminare la maggior parte della necessità di file binari setuid-root (ad es. /bin/ping
Ha CAP_NET_RAW, ecc.).
Infatti, l'unico binario che mi rimane è questo:
abraxas ~ # find / -xdev -type f -perm -u=s
/usr/lib64/misc/glibc/pt_chown
abraxas ~ #
Se rimuovo il bit setuid, o rimonto il mio filesystem di root nosuid
, sshd e GNU Screen smettono di funzionare, perché chiamano i grantpt(3)
loro principali pesudoterminals e glibc apparentemente esegue questo programma per chown e chmod lo pseudoterminal slave sotto /dev/pts/
, e GNU Screen si preoccupa quando questa funzione non riesce.
Il problema è che la manpage per grantpt(3)
esplicitamente afferma che sotto Linux, con il devpts
filesystem montato, non è richiesto tale binario di supporto; il kernel imposterà automaticamente l'UID e GID dello slave sull'UID e GID reali del processo aperto /dev/ptmx
(chiamando getpt(3)
).
Ho scritto un piccolo programma di esempio per dimostrarlo:
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
int main(void)
{
int master;
char slave[16];
struct stat slavestat;
if ((master = getpt()) < 0) {
fprintf(stderr, "getpt: %m\n");
return 1;
}
printf("Opened a UNIX98 master terminal, fd = %d\n", master);
/* I am not going to call grantpt() because I am trying to
* demonstrate that it is not necessary with devpts mounted,
* the owners and mode will be set automatically by the kernel.
*/
if (unlockpt(master) < 0) {
fprintf(stderr, "unlockpt: %m\n");
return 2;
}
memset(slave, 0, sizeof(slave));
if (ptsname_r(master, slave, sizeof(slave)) < 0) {
fprintf(stderr, "ptsname: %m\n");
return 2;
}
printf("Device name of slave pseudoterminal: %s\n", slave);
if (stat(slave, &slavestat) < 0) {
fprintf(stderr, "stat: %m\n");
return 3;
}
printf("Information for device %s:\n", slave);
printf(" Owner UID: %d\n", slavestat.st_uid);
printf(" Owner GID: %d\n", slavestat.st_gid);
printf(" Octal mode: %04o\n", slavestat.st_mode & 00007777);
return 0;
}
Osservalo in azione con il bit setuid sul programma di cui sopra rimosso:
aaron@abraxas ~ $ id
uid=1000(aaron) gid=100(users) groups=100(users)
aaron@abraxas ~ $ ./ptytest
Opened a UNIX98 master terminal, fd = 3
Device name of slave pseudoterminal: /dev/pts/17
Information for device /dev/pts/17:
Owner UID: 1000
Owner GID: 100
Octal mode: 0620
Ho solo alcune idee su come aggirare questo problema:
1) Sostituisci il programma con uno scheletro che restituisce semplicemente 0.
2) Patch grantpt () nella mia libc per non fare nulla.
Posso automatizzare entrambi, ma qualcuno ha una raccomandazione l'una sull'altra o raccomandazioni su come altro risolverlo?
Una volta risolto, finalmente posso mount -o remount,nosuid /
.
pty
(come dovrebbero), ma per il programma?