CERT C: Rule POS36-C

Наблюдайте правильный порядок аннулирования при отказе от привилегий

Описание

Управляйте определением

Наблюдайте правильный порядок аннулирования при отказе от привилегий. [1]

Реализация Polyspace

Это средство проверки проверяет на Плохой порядок понижающихся привилегий.

Примеры

развернуть все

Проблема

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

Проверяйте информацию

Группа: правило 50. POSIX (POS)

Введенный в R2019a


[1]  Это программное обеспечение было создано MathWorks, включающим фрагменты: “Веб-сайт SEI CERT-C”, © 2017 Carnegie Mellon University, веб-сайт SEI CERT-C © 2017 Carnegie Mellon University”, CERT SEI C Кодирование Стандарта – Правил для Разработки безопасных, Надежных и Защищенных систем – 2 016 Выпусков”, © 2016 Carnegie Mellon University, and “CERT SEI Стандарт Кодирования C++ – Правил для Разработки безопасных, Надежных и Защищенных систем на C++ – 2 016 Выпусков” © 2016 Carnegie Mellon University, со специальным разрешением от его Института программной инженерии.

ЛЮБОЙ МАТЕРИАЛ УНИВЕРСИТЕТА КАРНЕГИ-МЕЛЛОН И/ИЛИ ЕГО ИНСТИТУТА ПРОГРАММНОЙ ИНЖЕНЕРИИ СОДЕРЖАЛ, ЗДЕСЬ ПРЕДОСТАВЛЯЕТСЯ НА ОСНОВЕ "ASIS". УНИВЕРСИТЕТ КАРНЕГИ-МЕЛЛОН НЕ ДАЕТ ГАРАНТИЙ НИКАКОГО ВИДА, ИЛИ ВЫРАЗИЛ ИЛИ ПОДРАЗУМЕВАЛ, ОТНОСИТЕЛЬНО ЛЮБОГО ВОПРОСА ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИЛ, ГАРАНТИЯ ПРИГОДНОСТИ ДЛЯ ЦЕЛИ ИЛИ ВЫСОКОГО СПРОСА, ИСКЛЮЧИТЕЛЬНОСТИ, ИЛИ ЗАКАНЧИВАЕТСЯ ПОЛУЧЕННЫЙ ИЗ ИСПОЛЬЗОВАНИЯ МАТЕРИАЛА. УНИВЕРСИТЕТ КАРНЕГИ-МЕЛЛОН НЕ ДАЕТ ГАРАНТИИ НИКАКОГО ВИДА ОТНОСИТЕЛЬНО СВОБОДЫ ОТ ПАТЕНТА, ТОВАРНОГО ЗНАКА ИЛИ НАРУШЕНИЯ АВТОРСКОГО ПРАВА.

Это программное обеспечение и сопоставленная документация не были рассмотрены, ни являются подтвержденным Университетом Карнеги-Меллон или его Институтом программной инженерии.