Alexandre Julliard : server: Create anonymous file mappings in the config directory if the server directory is mounted noexec .
Alexandre Julliard
julliard at winehq.org
Fri Jan 28 12:30:16 CST 2011
Module: wine
Branch: master
Commit: 8dbd06a1f8ab3f89e46be62e05a51f4b15f20b1c
URL: http://source.winehq.org/git/wine.git/?a=commit;h=8dbd06a1f8ab3f89e46be62e05a51f4b15f20b1c
Author: Alexandre Julliard <julliard at winehq.org>
Date: Fri Jan 28 17:23:45 2011 +0100
server: Create anonymous file mappings in the config directory if the server directory is mounted noexec.
---
server/mapping.c | 43 +++++++++++++++++++++++++++++++++++++++++--
1 files changed, 41 insertions(+), 2 deletions(-)
diff --git a/server/mapping.c b/server/mapping.c
index c8b8edf..5c77989 100644
--- a/server/mapping.c
+++ b/server/mapping.c
@@ -26,6 +26,9 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
+#ifdef HAVE_SYS_MMAN_H
+# include <sys/mman.h>
+#endif
#include <unistd.h>
#include "ntstatus.h"
@@ -161,13 +164,47 @@ static int grow_file( int unix_fd, file_pos_t new_size )
return 0;
}
+/* check if the current directory allows exec mappings */
+static int check_current_dir_for_exec(void)
+{
+ int fd;
+ char tmpfn[] = "anonmap.XXXXXX";
+ void *ret = MAP_FAILED;
+
+ fd = mkstemps( tmpfn, 0 );
+ if (fd == -1) return 0;
+ if (grow_file( fd, 1 ))
+ {
+ ret = mmap( NULL, get_page_size(), PROT_READ | PROT_EXEC, MAP_PRIVATE, fd, 0 );
+ if (ret != MAP_FAILED) munmap( ret, get_page_size() );
+ }
+ close( fd );
+ unlink( tmpfn );
+ return (ret != MAP_FAILED);
+}
+
/* create a temp file for anonymous mappings */
static int create_temp_file( file_pos_t size )
{
- char tmpfn[16];
+ static int temp_dir_fd = -1;
+ char tmpfn[] = "anonmap.XXXXXX";
int fd;
- sprintf( tmpfn, "anonmap.XXXXXX" ); /* create it in the server directory */
+ if (temp_dir_fd == -1)
+ {
+ temp_dir_fd = server_dir_fd;
+ if (!check_current_dir_for_exec())
+ {
+ /* the server dir is noexec, try the config dir instead */
+ fchdir( config_dir_fd );
+ if (check_current_dir_for_exec())
+ temp_dir_fd = config_dir_fd;
+ else /* neither works, fall back to server dir */
+ fchdir( server_dir_fd );
+ }
+ }
+ else if (temp_dir_fd != server_dir_fd) fchdir( temp_dir_fd );
+
fd = mkstemps( tmpfn, 0 );
if (fd != -1)
{
@@ -179,6 +216,8 @@ static int create_temp_file( file_pos_t size )
unlink( tmpfn );
}
else file_set_error();
+
+ if (temp_dir_fd != server_dir_fd) fchdir( server_dir_fd );
return fd;
}
More information about the wine-cvs
mailing list