Вопросы о setuid

У меня проблема с запуском следующей программы на C:

#include<unistd.h>

void main()
{
    if (access("/root/main.c",R_OK)==0)
    {
        printf("/root/main.c can be read\n");
    }
    else
    {
        printf("can't be read\n");
    }
}

Когда я запускаю исполняемый файл как root, я могу получить результат:

/root/main.c can be read

Но когда я устанавливаю разрешения для исполняемого файла на 4755 и запускаю его как обычный пользователь, я получаю только вывод:

can't be read

Есть ли в моем протоколе ошибка?


person lwp007    schedule 12.03.2018    source источник
comment
кто является владельцем и группой файла   -  person Juan    schedule 12.03.2018
comment
Из любопытства, какие первые 4? Он не соответствует en.wikipedia.org/wiki/File_system_permissions   -  person Tom de Geus    schedule 12.03.2018
comment
@TomdeGeus en.wikipedia.org/wiki/Setuid#setuid_and_setgid_on_executables   -  person melpomene    schedule 12.03.2018


Ответы (1)


access игнорирует биты setuid / setgid. Это сделано намеренно.

Цитата из man 2 access в Linux:

Проверка выполняется с использованием реальных UID и GID вызывающего процесса, а не эффективных идентификаторов, как это делается при фактической попытке выполнения операции (например, open(2)) с файлом. Точно так же для пользователя root проверка использует набор разрешенных возможностей, а не набор эффективных возможностей; а для пользователей без полномочий root проверка использует пустой набор возможностей.

Это позволяет программам с набором идентификаторов пользователей и программам с возможностями легко определять полномочия вызывающего пользователя. Другими словами, access() не отвечает на вопрос «Могу ли я прочитать / записать / выполнить этот файл?» вопрос. Он отвечает на несколько иной вопрос: «(при условии, что я - двоичный файл setuid) может вызвавший меня пользователь читать / писать / выполнять этот файл?», Что дает возможность программам set-user-ID чтобы злоумышленники не заставляли их читать файлы, которые пользователи не должны иметь возможность читать.

Если вы хотите знать, действительно ли ваш процесс может открыть файл для чтения, просто open() его и обработайте ошибку, если таковая имеется. (Это также позволяет избежать состояния гонки.)

person melpomene    schedule 12.03.2018
comment
Большое спасибо, это мне очень помогает. - person lwp007; 27.03.2018