Я написал простую программу следующим образом:
int main(int argc, char* argv[]) {
setuid(0);
setgid(0);
printf("Current uid and euid are %d, %d\n", getuid(), geteuid());
while(1);
}
Я скомпилировал это как root и установил бит setuid, используя sudo chmod +s test
.
Когда эта программа запускается от имени непривилегированного пользователя из bash, программа печатает -
Текущие uid и euid равны 0, 0
а потом застревает в бесконечном цикле.
Однако я все еще могу убить этот процесс, нажав Crl+C. Если я правильно понимаю, bash (работающий от имени непривилегированного пользователя) не должен иметь возможности отправлять SIGINT корневому процессу.
Я также пробовал то же самое с kill <pid of test>
, и это не удалось, как исключение.
Как bash может убить процесс? Существуют ли особые отношения между родительским процессом и дочерним процессом?
Я также пробовал эту другую программу-оболочку -
int main(int argc, char* argv[]) {
pid_t p = fork();
if (p == 0) {
char * args[] = {"./test", NULL};
execv("./test", args);
} else {
sleep(4);
int ret = kill(p, 9);
printf("Kill returned = %d\n", ret);
return 0;
}
}
И запустил его как непривилегированный пользователь (где test
имеет бит setuid, установленный пользователем root). В этом случае родитель не может убить ребенка. вызов kill
возвращает -1, а процесс test
становится осиротевшим.
Что здесь происходит? Что делает bash особенным, что он может убить порожденные им дочерние процессы?