Когда полезен umask()?

umask(0);

fd = open("/dev/null", O_RDWR);

Вот man 2 umask:

umask() sets the calling process’s file mode creation mask (umask) to mask & 0777.

Но для меня это не имеет смысла, так как при вызове open мы также предоставляем параметр режима.

Так в чем смысл umask?


person cpuer    schedule 01.06.2011    source источник
comment
Возможный дубликат Зачем вам использовать umask?   -  person Ky Leggiero    schedule 02.02.2019


Ответы (4)


Маска umask применяется ко всем режимам, используемым в операциях с файловой системой. Из руководства open(2):

Права доступа к созданному файлу: (mode & ~umask)

Таким образом, одним вызовом umask вы можете влиять на режим всех создаваемых файлов.

Обычно это используется, когда программа хочет, чтобы пользователь разрешил отменить права доступа по умолчанию для файлов/каталогов, которые она создает. Параноидальный пользователь (или root) может установить umask на 0077, что означает, что даже если вы укажете 0777 в open(2), только текущий пользователь будет иметь доступ.

person Aaron Digulla    schedule 01.06.2011
comment
что, если umask равен 777, тогда никто не сможет его изменить? - person cpuer; 01.06.2011
comment
вроде open тоже можно вызывать без параметра mode, int open(const char *pathname, int flags);, какое будет разрешение создаваемых файлов в таком случае? - person cpuer; 01.06.2011
comment
Да. Не имеет большого смысла, но ничто не мешает вам создавать файлы, к которым вы не можете получить доступ самостоятельно. На самом деле, я использую это, чтобы остановить программы для создания/изменения нежелательных файлов и папок с помощью chmod 0 .configdir - person Aaron Digulla; 01.06.2011
comment
повторно открыть без режима: это зависит от вашего вкуса Unix. В моем Linux вы должны указать режим при использовании O_CREAT. Некоторые системы Unix строят режим из режима каталога, содержащего новый файл. Подробности читайте в документации. - person Aaron Digulla; 01.06.2011
comment
Итак, umask(0); ничего не делает, кроме сброса umask до значения по умолчанию? - person Fábio Roberto Teodoro; 25.09.2019
comment
@FábioRobertoTeodoro Да, вы можете посмотреть на это так. На мой взгляд, это отключает эффект umask(). - person Aaron Digulla; 27.09.2019

Я знаю, что это и старый вопрос, но вот мои два цента:

Разрешения объекта общей памяти

Я пытался создать объект общей памяти с помощью:

int shm_open(const char *name, int oflag, mode_t mode); 

В результирующей общей памяти не было разрешения, установленного в аргументе режима, поэтому я прочитал справочную страницу shm_open, которая привела меня к функции открытия справочная страница и там написано:

mode указывает разрешения для использования в случае создания нового файла. Этот аргумент должен быть указан, если в флагах указано O_CREAT; если O_CREAT не указан, то режим игнорируется. Действующие разрешения модифицируются umask процесса обычным способом: Разрешения созданного файла: (mode & ~umask). Обратите внимание, что этот режим применяется только к будущим обращениям к вновь созданному файлу.

Поэтому я попытался изменить umask с помощью:

mode_t umask(mode_t mask); 

но это тоже не сработало, поэтому, погуглив еще раз, я нашел этот Setting Разрешение документ на gnu.org

Который рекомендует:

Когда вашей программе необходимо создать файл и обойти umask для его прав доступа, самый простой способ сделать это — использовать fchmod после открытия файла, а не изменять umask. На самом деле смена умаска обычно производится только оболочками. Они используют функцию umask.

а с fchmod моя функция работала как я и хотел :) вот она:

int open_signals_shmem(struct signal_shmem **shmem, int size)
{
    int fd, ret;
    void *ptr;

    *shmem = NULL;
    ret = 1;

    fd = shm_open(SIGNALS_SHMEM_NAME, O_RDWR | O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO);
    if (fd == -1)
    {
        printf("error: signals shmem could not be allocated (%s, errno=%d)\n", SIGNALS_SHMEM_NAME, errno);
    }
    else
    {
        // Change permissions of shared memory, so every body can access it
        fchmod(fd, S_IRWXU | S_IRWXG | S_IRWXO);

        if (ftruncate(fd, size) == -1)
        {
            printf("error: signals shmem could not be truncated (%s, errno=%d)\n", SIGNALS_SHMEM_NAME, errno);
        }
        else
        {
            ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
            if (ptr == MAP_FAILED)
            {
                printf("error: signals shmem could not be mapped (%s, errno=%d)\n", SIGNALS_SHMEM_NAME, errno);
            }
            else
            {
                *shmem = ptr;
                ret = 0;
            }
        }
    }
    return ret;
}
person q325mg    schedule 20.02.2015
comment
Вы можете вызывать fchmod только при создании общей памяти (попробуйте открыть с помощью RDWR, затем проверьте errno на наличие ENOENT, затем выполните O_RDWR|O_CREAT и fchmod), так как вы не можете fchmod совместно используемой памяти другого пользователя даже с разрешениями 777. В противном случае, если вы попытаетесь открыть объект общей памяти, созданный другим пользователем, вы получите ошибку прав доступа. - person Marc Etcheverry; 16.10.2017

Цитируя эту статью:

Маска umask предназначена для того, чтобы пользователи могли влиять на права доступа к вновь создаваемым файлам и каталогам. Демоны не должны зависеть от этой настройки, потому что то, что подходит пользователю, не обязательно подходит для демона.

В некоторых случаях для umask может быть удобнее установить ненулевое значение. Это в равной степени приемлемо: важным моментом является то, что демон взял на себя управление значением, а не просто принял то, что ему было дано.

person Blagovest Buyukliev    schedule 01.06.2011
comment
@Благовест Буюклиев, я так и не вижу назначения umask, разве это уже не доступно в параметре open? - person cpuer; 01.06.2011
comment
Второй аргумент open указывает режим открытия файла, т. е. какие операции будут доступны для возвращаемого дескриптора. umask, с другой стороны, указывает разрешения файловой системы, которые будут установлены для каждого вновь созданного файла. - person Blagovest Buyukliev; 01.06.2011
comment
@Благовест Буюклиев, а это тоже не доступно? int creat(const char *pathname, mode_t mode); - person cpuer; 01.06.2011
comment
creat — это старый, устаревший способ создания нового пустого файла. Это то же самое, что и open с флагом O_CREAT. - person Blagovest Buyukliev; 01.06.2011
comment
@Blagovest Buyukliev, я имею в виду, что либо creat, либо open имеют свой параметр для mode, а flag, umask все еще кажутся мне бесполезными. - person cpuer; 01.06.2011
comment
Да, open можно использовать с параметром mode, но umask устанавливает параметр по умолчанию, чтобы вам не приходилось передавать его каждый раз. - person Blagovest Buyukliev; 01.06.2011
comment
@Blagovest Buyukliev, согласно ответу @Aaron Digulla, umask не предоставляет значение по умолчанию, но окончательный режим представляет собой комбинацию mode & ~umask. - person cpuer; 01.06.2011

Большинство разработчиков Mac (и, соответственно, большинство тестировщиков программного обеспечения) с самого детства помещают это в свой .cshrc.

umask 002

Однако большинство конечных пользователей не знают о umask, поэтому, если они создадут нового пользователя на машине и запустят ваше приложение, вы, вероятно, создадите кучу файлов журнала и еще много чего без групповых разрешений на чтение/запись. Затем они снова меняют пользователей, и вдруг ваше приложение не работает. По этой причине мы добавляем это во все наши приложения. Наше практическое правило, когда речь заходит о безопасности, гласит: «Мы хотим, чтобы пользователи могли использовать наше программное обеспечение».

#import <sys/types.h>
#import <sys/stat.h>
int main(int argc, char *argv[])
{
    // set permissions for newly created files to ug+rwX,o+rX
    umask(0002); 
person Keith Knauber    schedule 03.02.2017