#define _BSD_SOURCE
#include <sys/types.h>
#include <unistd.h>
#include <grp.h>
#include <stdlib.h>
#define fatal_error() abort()
extern int need_more_privileges;
void missingprivilegedropcheck()
{
/* Code intended to run with elevated privileges */
/* Temporarily drop elevated privileges */
if (seteuid(getuid()) != 0) {
/* Handle error */
fatal_error();
}
/* Code intended to run with lower privileges */
if (need_more_privileges) {
/* Restore elevated privileges */
if (seteuid(0) != 0) {
/* Handle error */
fatal_error();
}
/* Code intended to run with elevated privileges */
}
/* ... */
/* Permanently drop elevated privileges */
if (setuid(getuid()) != 0) {
/* Handle error */
fatal_error();
}
/* Code intended to run with lower privileges */
}
В этом примере привилегии подняты и пропущены, чтобы запустить код с намеченным уровнем полномочий. Когда привилегии пропущены, уровень полномочий прежде, чем выйти из тела функции не проверяется. Злонамеренный атакующий может возвратить их поднятые привилегии.
Исправление — проверяет отбрасывание привилегии
Одно возможное исправление должно использовать setuid
, чтобы проверить, что привилегии были пропущены.
#define _BSD_SOURCE
#include <sys/types.h>
#include <unistd.h>
#include <grp.h>
#include <stdlib.h>
#define fatal_error() abort()
extern int need_more_privileges;
void missingprivilegedropcheck()
{
/* Store the privileged ID for later verification */
uid_t privid = geteuid();
/* Code intended to run with elevated privileges */
/* Temporarily drop elevated privileges */
if (seteuid(getuid()) != 0) {
/* Handle error */
fatal_error();
}
/* Code intended to run with lower privileges */
if (need_more_privileges) {
/* Restore elevated Privileges */
if (seteuid(privid) != 0) {
/* Handle error */
fatal_error();
}
/* Code intended to run with elevated privileges */
}
/* ... */
/* Restore privileges if needed */
if (geteuid() != privid) {
if (seteuid(privid) != 0) {
/* Handle error */
fatal_error();
}
}
/* Permanently drop privileges */
if (setuid(getuid()) != 0) {
/* Handle error */
fatal_error();
}
if (setuid(0) != -1) {
/* Privileges can be restored, handle error */
fatal_error();
}
/* Code intended to run with lower privileges; */
}