Описание
Плохой порядок понижающихся привилегий проверяет порядок отбрасываний привилегии. Если вы пропускаете более высокие поднятые привилегии прежде, чем пропустить ниже поднятые привилегии, Polyspace повышает дефект. Например, отбрасывание подняло первичные привилегии группы прежде, чем понизиться, поднял вспомогательные привилегии группы.
Риск
Если вы пропускаете привилегии в неправильном порядке, можно потенциально пропустить более высокие привилегии, что необходимо пропустить более низкие привилегии. Неправильный порядок может означать, привилегии не пропущены, ставя под угрозу безопасность вашей программы.
Фиксация
Уважайте этот порядок отбрасывания поднятых привилегий:
Пропустите (поднятые) вспомогательные привилегии группы, затем пропустите (поднятые) первичные привилегии группы.
Пропустите (поднятые) первичные привилегии группы, затем пропустите (поднятые) полномочия пользователя.
Пример - пропускающий полномочия пользователя сначала
#define _BSD_SOURCE
#include <sys/types.h>
#include <unistd.h>
#include <grp.h>
#include <stdlib.h>
#define fatal_error() abort()
static void sanitize_privilege_drop_check(uid_t olduid, gid_t oldgid)
{
if (seteuid(olduid) != -1)
{
/* Privileges can be restored, handle error */
fatal_error();
}
if (setegid(oldgid) != -1)
{
/* Privileges can be restored, handle error */
fatal_error();
}
}
void badprivilegedroporder(void) {
uid_t
newuid = getuid(),
olduid = geteuid();
gid_t
newgid = getgid(),
oldgid = getegid();
if (setuid(newuid) == -1) {
/* handle error condition */
fatal_error();
}
if (setgid(newgid) == -1) {
/* handle error condition */
fatal_error();
}
if (olduid == 0) {
/* drop ancillary groups IDs only possible for root */
if (setgroups(1, &newgid) == -1) {
/* handle error condition */
fatal_error();
}
}
sanitize_privilege_drop_check(olduid, oldgid);
}
В этом примере существует два отбрасывания привилегии, сделанные в неправильном порядке. setgid
пытается пропустить привилегии группы. Однако setgid
требует полномочий пользователя, которые были пропущены ранее с помощью setuid
, чтобы выполнить эту функцию. После понижающихся привилегий группы эта функция пытается пропустить вспомогательные привилегии групп при помощи setgroups
. Эта задача требует более высоких первичных привилегий группы, которые были пропущены с setgid
. В конце этой функции возможно возвратить привилегии группы, потому что порядок понижающихся привилегий был неправильным.
Исправление — противоположный порядок отбрасывания привилегии
Одно возможное исправление должно пропустить самые низкие привилегии уровня сначала. В этом исправлении вспомогательные привилегии группы пропущены, затем пропущены первичные привилегии группы, и наконец полномочия пользователя пропущены.
#define _BSD_SOURCE
#include <sys/types.h>
#include <unistd.h>
#include <grp.h>
#include <stdlib.h>
#define fatal_error() abort()
static void sanitize_privilege_drop_check(uid_t olduid, gid_t oldgid)
{
if (seteuid(olduid) != -1)
{
/* Privileges can be restored, handle error */
fatal_error();
}
if (setegid(oldgid) != -1)
{
/* Privileges can be restored, handle error */
fatal_error();
}
}
void badprivilegedroporder(void) {
uid_t
newuid = getuid(),
olduid = geteuid();
gid_t
newgid = getgid(),
oldgid = getegid();
if (olduid == 0) {
/* drop ancillary groups IDs only possible for root */
if (setgroups(1, &newgid) == -1) {
/* handle error condition */
fatal_error();
}
}
if (setgid(getgid()) == -1) {
/* handle error condition */
fatal_error();
}
if (setuid(getuid()) == -1) {
/* handle error condition */
fatal_error();
}
sanitize_privilege_drop_check(olduid, oldgid);
}