Estoy tratando de que dos procesos se comuniquen a través de la memoria compartida. Noté que si los ejecuto con diferentes usuarios, el segundo falla en shm_open() con permiso denegado, incluso si son del mismo grupo. Pero si agrego el bit de ejecución al modo, el segundo proceso no falla en la llamada a shm_open().
Me gustaría entender este comportamiento, ¿qué hace exactamente el bit de ejecución en el caso de shm_open() ? En particular, ¿puede un proceso ejecutar shellcode en /dev/shm si el bit de ejecución se establece durante la llamada a shm_open() ?
Las páginas de manual son los mejores documentos que encontré sobre esto. De lo que dice en O_CREAT:
Cree el objeto de memoria compartida si no existe. La propiedad del objeto por parte del usuario y del grupo se toma de los ID efectivos correspondientes del proceso de llamada, y los bits de permiso del objeto se establecen de acuerdo con los 9 bits de modo de orden inferior, excepto aquellos bits establecidos en la máscara de creación del modo de archivo de proceso. (ver umask(2)) están borrados para el nuevo objeto
Según tengo entendido, obtiene sus bits de permiso del modo (mi umask está configurado en 0002, pero cambiar a 0 no parece producir un resultado diferente). Mantengo O_CREAT en ambos programas porque el manual dice "Crear el objeto de memoria compartida si no existe", así que quería reutilizar el mismo código para ambos.
MWE:
#include <sys/mman.h> #include <sys/stat.h> #include <fcntl.h> #include <stdio.h> #include <string.h> #include <errno.h> #include <stdlib.h> int main() { const char* name = "com/page"; int flags = O_CREAT | O_RDWR; int mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP; int fd = shm_open(name, flags, mode); if (fd < 1) { printf("shm_open() failed: %s", strerror(errno)); exit(EXIT_FAILURE); } /* ... */ shm_unlink(name); return EXIT_SUCCESS; }Tal como está, el fragmento anterior devuelve -1 con errno establecido en permiso denegado si los programas se ejecutan con diferentes usuarios, pero ambos en el mismo grupo.
Si reemplazo la línea 12 de arriba con:
int mode = S_IRWXU | S_RWXGLuego, la llamada a shm_open() devuelve 0.
Esto parece estar relacionado con cuando a un directorio le falta el bit de ejecución, y no podemos acceder a él. Traté de usar una ruta en lugar de un nombre de archivo (con la estructura de carpetas en /dev/shm creada de antemano) pero luego shm_open() falla con un argumento no válido.