Я адмініструю поле Gentoo Hardened, яке використовує можливості файлів, щоб усунути більшість потреб у встановлених кореневих бінарних файлах (наприклад, /bin/ping
має CAP_NET_RAW тощо).
Infact, єдиний бінарний, який у мене залишився, це:
abraxas ~ # find / -xdev -type f -perm -u=s
/usr/lib64/misc/glibc/pt_chown
abraxas ~ #
Якщо я видаляю біт setuid або перезавантажую свою кореневу файлову систему nosuid
, sshd та GNU Screen перестають працювати, оскільки вони закликають grantpt(3)
їх головних песудотерміналів, а glibc, мабуть, виконує цю програму, щоб подавити та chmod під псевдотерміналом підлеглого /dev/pts/
, і GNU Screen піклується про те, коли ця функція не вдається.
Проблема полягає в тому, що на сторінці сторінки grantpt(3)
чітко зазначено, що в Linux із встановленою devpts
файловою системою таких бінарних помічників не потрібно; ядро автоматично встановить UID & GID підлеглого на справжній UID & GID процесу, який відкрився /dev/ptmx
(за допомогою виклику getpt(3)
).
Я написав невеликий приклад програми, щоб продемонструвати це:
#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;
}
Слідкуйте за цим дією із встановленим бітом у вищезгаданій програмі:
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
У мене є лише кілька ідей, як вирішити цю проблему:
1) Замініть програму скелетом, який просто повертає 0.
2) Патч grantpt () в моєму libc нічого не робити.
Я можу автоматизувати і те, і інше, але хтось має рекомендації один за іншим або рекомендації, як ще вирішити це?
Як тільки це вирішиться, я можу нарешті mount -o remount,nosuid /
.
pty
(як слід), а на програму?