ПроблемаНеправильный порядок отбрасывания привилегий проверяет порядок отбрасывания привилегий. Если удалить более высокие привилегии, прежде чем удалить более низкие, Полиспейс вызывает дефект. Например, удаление повышенных привилегий основной группы перед удалением повышенных привилегий вспомогательной группы.
РискЕсли удалить привилегии в неправильном порядке, потенциально можно удалить более высокие привилегии, которые необходимо удалить. Неправильный порядок может означать, что привилегии не удаляются, что подрывает безопасность программы.
ЗафиксироватьСоблюдайте этот порядок удаления повышенных привилегий:
Удаление (повышенных) привилегий вспомогательной группы, затем удаление (повышенных) привилегий основной группы.
Удаление (повышенных) привилегий основной группы, затем удаление (повышенных) привилегий пользователя.
Пример - Удаление прав пользователя первым#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);
}