Tôi quản lý một hộp Gentoo Hardened sử dụng các khả năng của tệp để loại bỏ hầu hết nhu cầu về các nhị phân gốc setuid (ví dụ: /bin/ping
có CAP_NET_RAW, v.v.).
Nguyên vẹn, nhị phân duy nhất tôi còn lại là cái này:
abraxas ~ # find / -xdev -type f -perm -u=s
/usr/lib64/misc/glibc/pt_chown
abraxas ~ #
Nếu tôi loại bỏ bit setuid hoặc lặp lại hệ thống tập tin gốc của mình nosuid
, sshd và GNU Screen ngừng hoạt động, bởi vì chúng gọi grantpt(3)
pesudotermutions chính của chúng và glibc dường như thực thi chương trình này để điều khiển và kiểm tra giả hình nô lệ bên dưới /dev/pts/
và GNU Screen quan tâm đến chức năng này thất bại
Vấn đề là, trang quản trị đã grantpt(3)
tuyên bố rõ ràng rằng trong Linux, với devpts
hệ thống tập tin được gắn kết, không yêu cầu nhị phân trợ giúp như vậy; hạt nhân sẽ tự động đặt UID & GID của nô lệ thành UID & GID thực của quá trình đã mở /dev/ptmx
(bằng cách gọi getpt(3)
).
Tôi đã viết một chương trình ví dụ nhỏ để chứng minh điều này:
#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;
}
Quan sát nó trong hành động với bit setuid trên chương trình đã nói ở trên đã bị xóa:
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
Tôi chỉ có một vài ý tưởng về cách giải quyết vấn đề này:
1) Thay thế chương trình bằng bộ xương chỉ trả về 0.
2) Patch Grantpt () trong libc của tôi không làm gì cả.
Tôi có thể tự động hóa cả hai thứ này, nhưng có ai có đề xuất cho cái này hơn cái kia không, hoặc đề xuất về cách khác để giải quyết vấn đề này?
Một khi điều này được giải quyết, cuối cùng tôi có thể mount -o remount,nosuid /
.
pty
(như họ nên) mà cho chương trình?