J'administre une boîte Gentoo Hardened qui utilise les capacités des fichiers pour éliminer la plupart des binaires setuid-root (par exemple /bin/ping
a CAP_NET_RAW, etc.).
En fait, le seul binaire qu'il me reste est celui-ci:
abraxas ~ # find / -xdev -type f -perm -u=s
/usr/lib64/misc/glibc/pt_chown
abraxas ~ #
Si je supprime le bit setuid ou remonte mon système de fichiers racine nosuid
, sshd et GNU Screen cessent de fonctionner, car ils appellent grantpt(3)
leurs maîtres pesudoterminals et glibc exécute apparemment ce programme pour afficher et chmod le pseudoterminal esclave sous /dev/pts/
, et GNU Screen se soucie quand cette fonction échoue.
Le problème est que la page de manuel de grantpt(3)
explicitement indique que sous Linux, avec le devpts
système de fichiers monté, aucun binaire d'assistance n'est requis; le noyau définira automatiquement l'UID et le GID de l'esclave sur le véritable UID et GID du processus qui s'est ouvert /dev/ptmx
(en appelant getpt(3)
).
J'ai écrit un petit exemple de programme pour le démontrer:
#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;
}
Observez-le en action avec le bit setuid sur le programme susmentionné supprimé:
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
Je n'ai que quelques idées sur la façon de contourner ce problème:
1) Remplacez le programme par un squelette qui renvoie simplement 0.
2) Patch grantpt () dans ma libc pour ne rien faire.
Je peux automatiser les deux, mais quelqu'un a-t-il une recommandation à faire l'un par rapport à l'autre, ou des recommandations sur la manière de résoudre ce problème?
Une fois que cela est résolu, je peux enfin mount -o remount,nosuid /
.
pty
(comme ils le devraient) mais le programme?