ПроблемаНеправильный порядок удаления привилегий проверяет порядок понижений привилегий. Если вы сбрасываете более высокие повышенные привилегии, прежде чем сбрасывать более низкие повышенные привилегии, 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);
}