Описание
Отбрасывание привилегии, не проверенное, обнаруживает вызовы функций, которые оставляют привилегии. Если вы не проверяете, что привилегии были пропущены перед концом вашей функции повышен дефект.
Риск
Если отказ привилегии перестал работать, атакующий может возвратить поднятые привилегии и иметь больше доступа к вашей программе, чем предназначенный. Эта дыра в системе безопасности может вызвать неожиданное поведение в вашем коде если левый открытый.
Фиксация
Перед концом осциллографа проверьте, что привилегии, которые вы пропустили, были на самом деле пропущены.
Пример - привилегии отбрасывания в функции
#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; */
}