2010-03-07 9 views
19

Estoy tratando de crear un archivo de solo escritura en C en Linux (Ubuntu). Este es mi código:Crear un archivo en Linux utilizando C

int fd2 = open ("/tmp/test.svg", O_RDWR|O_CREAT); 

if (fd2 != -1) { 
    //.... 
} 

Pero ¿por qué los archivos que he creado tienen modo de 'xr'? ¿Cómo puedo crearlo para que pueda abrirlo yo mismo en el símbolo del sistema?

------xr-- 1 michael michael 55788 2010-03-06 21:57 test.txt* 
------xr-- 1 michael michael 9703 2010-03-06 22:41 test.svg* 
+2

Ejemplo impresionante de código inseguro. –

+2

@Michael Foukarakis: temporalmente, hay problemas más grandes con los que lidiar, pero tienes razón. Se debe agregar O_EXCL (para evitar el seguimiento de enlaces simbólicos maliciosos y evitar el archivo de otras personas cuando ejecutan el mismo programa en la misma máquina); el nombre fijo será problemático en el código de producción, por lo que debería estar usando '' mkstemp() ''o un pariente para crear el nombre del archivo. Y la lista continúa, sin duda. –

Respuesta

31

Usted necesita la forma de tres argumentos de open() cuando se especifica O_CREAT. Cuando se omite el tercer argumento, open() usa cualquier valor que esté en la pila donde se esperaba el tercer argumento; esto rara vez es un conjunto coherente de permisos (en su ejemplo, parece que el decimal 12 = octal 014 estaba en la pila).

El tercer argumento son los permisos del archivo, que se modificarán con el valor umask().

int fd2 = open("/tmp/test.svg", O_RDWR | O_CREAT, S_IRUSR | S_IRGRP | S_IROTH); 

Tenga en cuenta que se puede crear un archivo sin permisos de escritura (a cualquier otra persona, o cualquier otro proceso) sin dejar de ser capaz de escribir en él desde el proceso actual. Rara vez es necesario utilizar bits de ejecución en archivos creados a partir de un programa, a menos que esté escribiendo un compilador (¡y los archivos '.svg' no son normalmente ejecutables!).

Las banderas S_xxxx provienen de <sys/stat.h> y <fcntl.h> - puede utilizar cualquiera de cabecera para obtener la información (pero sí open() se declara en <fcntl.h>).

Tenga en cuenta que el nombre del archivo fijo y la ausencia de opciones de protección como O_EXCL hacen que incluso la llamada revisada open() sea un tanto insegura.

+1

Si tiene versiones recientes de los encabezados glibc y gcc, gcc puede advertirle acerca de dejar fuera ese tercer argumento para 'abrir'. – caf

+0

@Jonathan: ¿hay algo mal en lo que he publicado? Ha mencionado sobre seguir enlaces simbólicos dañados maliciosos y un problema con el nombre fijo en el código de producción. ¿Qué/por qué son estos problemas? –

+1

@nvl: supongamos que dos usuarios, bill y joe, ejecutan su programa al mismo tiempo. Ambos crean un archivo /tmp/test.svg... ¿con qué datos se usa? Digamos que el Sr. Malicious trabaja en su máquina y logra hacer: 'ln -s/etc/passwd/tmp/test.svg'. Ahora sucederá una de dos cosas cuando se ejecuta el programa: (1) aparece un error abierto porque no puede escribir en/etc/passwd (no es root), o (2) obtiene una copia de su imagen SVG en/etc/passwd porque es root. Ninguno de los dos se considera normalmente deseable. Y el Sr. Malicious también puede hacer: 'ln -us /usr/lib/security/libmalpam.so/tmp/test.svg' ... –

1

Dale permisos de acceso como tercer parámetro:

int fd2 = open("/tmp/test.svg", O_RDWR|O_CREAT, 0777); // Originally 777 (see comments) 

if (fd2 != -1) { 
    // use file descriptor 
    close(fd2); 
} 

De esta manera, toda lectura, escritura y ejecución se darán permisos para el usuario, grupo y otros. Modifique el 3er parámetro según su uso.

+1

777 no es lo mismo que S_IRWXU | S_IRWXG | S_IRWXO. 0x777 pasa a ser lo mismo, pero es una mala práctica de codificación. – prewett

+3

Tenga en cuenta que ni 777 (decimal) ni 0x777 (hex) es lo mismo que el normal 0777 (octal) o 'S_IRWXU | S_IRWXG | S_IRWXO' que proporciona a usuarios, grupos y otros acceso de lectura, escritura y ejecución en un archivo. Entonces, el comentario anterior de que "0x777 pasa a ser lo mismo" es erróneo. Corresponde a: r-xrwSrwt (conjunto de bits SGID, conjunto de bits SVTX, más 0567 permisos, y no tengo la paciencia para escribir eso de forma simbólica, requiere 7 términos o juntos). –

Cuestiones relacionadas