Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
1e78c993
Commit
1e78c993
authored
Nov 22, 2013
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
kernel32: Validate the architecture of newly created processes on the server side.
parent
f2c54dba
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
96 additions
and
29 deletions
+96
-29
process.c
dlls/kernel32/process.c
+54
-10
server.c
dlls/ntdll/server.c
+6
-6
server_protocol.h
include/wine/server_protocol.h
+3
-1
process.c
server/process.c
+5
-0
protocol.def
server/protocol.def
+1
-0
request.h
server/request.h
+3
-2
thread.c
server/thread.c
+17
-10
thread.h
server/thread.h
+1
-0
trace.c
server/trace.c
+6
-0
No files found.
dlls/kernel32/process.c
View file @
1e78c993
...
...
@@ -1809,6 +1809,25 @@ static BOOL terminate_main_thread(void)
#endif
/***********************************************************************
* get_process_cpu
*/
static
int
get_process_cpu
(
const
WCHAR
*
filename
,
const
struct
binary_info
*
binary_info
)
{
switch
(
binary_info
->
arch
)
{
case
IMAGE_FILE_MACHINE_I386
:
return
CPU_x86
;
case
IMAGE_FILE_MACHINE_AMD64
:
return
CPU_x86_64
;
case
IMAGE_FILE_MACHINE_POWERPC
:
return
CPU_POWERPC
;
case
IMAGE_FILE_MACHINE_ARM
:
case
IMAGE_FILE_MACHINE_THUMB
:
case
IMAGE_FILE_MACHINE_ARMNT
:
return
CPU_ARM
;
case
IMAGE_FILE_MACHINE_ARM64
:
return
CPU_ARM64
;
}
ERR
(
"%s uses unsupported architecture (%04x)
\n
"
,
debugstr_w
(
filename
),
binary_info
->
arch
);
return
-
1
;
}
/***********************************************************************
* exec_loader
*/
static
pid_t
exec_loader
(
LPCWSTR
cmd_line
,
unsigned
int
flags
,
int
socketfd
,
...
...
@@ -1909,7 +1928,9 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW
LPPROCESS_INFORMATION
info
,
LPCSTR
unixdir
,
const
struct
binary_info
*
binary_info
,
int
exec_only
)
{
BOOL
ret
,
success
=
FALSE
;
static
const
char
*
cpu_names
[]
=
{
"x86"
,
"x86_64"
,
"PowerPC"
,
"ARM"
,
"ARM64"
};
NTSTATUS
status
;
BOOL
success
=
FALSE
;
HANDLE
process_info
;
WCHAR
*
env_end
;
char
*
winedebug
=
NULL
;
...
...
@@ -1917,11 +1938,10 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW
DWORD
startup_info_size
;
int
socketfd
[
2
],
stdin_fd
=
-
1
,
stdout_fd
=
-
1
;
pid_t
pid
;
int
err
;
int
err
,
cpu
;
if
(
!
is_win64
&&
!
is_wow64
&&
(
binary_info
->
flags
&
BINARY_FLAG_64BIT
)
)
if
(
(
cpu
=
get_process_cpu
(
filename
,
binary_info
))
==
-
1
)
{
ERR
(
"starting 64-bit process %s not supported in 32-bit wineprefix
\n
"
,
debugstr_w
(
filename
)
);
SetLastError
(
ERROR_BAD_EXE_FORMAT
);
return
FALSE
;
}
...
...
@@ -1950,14 +1970,26 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW
req
->
create_flags
=
flags
;
req
->
socket_fd
=
socketfd
[
1
];
req
->
exe_file
=
wine_server_obj_handle
(
hFile
);
ret
=
!
wine_server_call_err
(
req
);
req
->
cpu
=
cpu
;
status
=
wine_server_call
(
req
);
}
SERVER_END_REQ
;
if
(
ret
)
exec_loader
(
cmd_line
,
flags
,
socketfd
[
0
],
stdin_fd
,
stdout_fd
,
unixdir
,
winedebug
,
binary_info
,
TRUE
);
switch
(
status
)
{
case
STATUS_INVALID_IMAGE_WIN_64
:
ERR
(
"64-bit application %s not supported in 32-bit prefix
\n
"
,
debugstr_w
(
filename
)
);
break
;
case
STATUS_INVALID_IMAGE_FORMAT
:
ERR
(
"%s not supported on this installation (%s binary)
\n
"
,
debugstr_w
(
filename
),
cpu_names
[
cpu
]
);
break
;
case
STATUS_SUCCESS
:
exec_loader
(
cmd_line
,
flags
,
socketfd
[
0
],
stdin_fd
,
stdout_fd
,
unixdir
,
winedebug
,
binary_info
,
TRUE
);
}
close
(
socketfd
[
0
]
);
SetLastError
(
RtlNtStatusToDosError
(
status
));
return
FALSE
;
}
...
...
@@ -2001,11 +2033,12 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW
req
->
process_attr
=
(
psa
&&
(
psa
->
nLength
>=
sizeof
(
*
psa
))
&&
psa
->
bInheritHandle
)
?
OBJ_INHERIT
:
0
;
req
->
thread_access
=
THREAD_ALL_ACCESS
;
req
->
thread_attr
=
(
tsa
&&
(
tsa
->
nLength
>=
sizeof
(
*
tsa
))
&&
tsa
->
bInheritHandle
)
?
OBJ_INHERIT
:
0
;
req
->
cpu
=
cpu
;
req
->
info_size
=
startup_info_size
;
wine_server_add_data
(
req
,
startup_info
,
startup_info_size
);
wine_server_add_data
(
req
,
env
,
(
env_end
-
env
)
*
sizeof
(
WCHAR
)
);
if
(
(
ret
=
!
wine_server_call_err
(
req
)))
if
(
!
(
status
=
wine_server_call
(
req
)))
{
info
->
dwProcessId
=
(
DWORD
)
reply
->
pid
;
info
->
dwThreadId
=
(
DWORD
)
reply
->
tid
;
...
...
@@ -2017,11 +2050,22 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW
SERVER_END_REQ
;
RtlReleasePebLock
();
if
(
!
ret
)
if
(
status
)
{
switch
(
status
)
{
case
STATUS_INVALID_IMAGE_WIN_64
:
ERR
(
"64-bit application %s not supported in 32-bit prefix
\n
"
,
debugstr_w
(
filename
)
);
break
;
case
STATUS_INVALID_IMAGE_FORMAT
:
ERR
(
"%s not supported on this installation (%s binary)
\n
"
,
debugstr_w
(
filename
),
cpu_names
[
cpu
]
);
break
;
}
close
(
socketfd
[
0
]
);
HeapFree
(
GetProcessHeap
(),
0
,
startup_info
);
HeapFree
(
GetProcessHeap
(),
0
,
winedebug
);
SetLastError
(
RtlNtStatusToDosError
(
status
));
return
FALSE
;
}
...
...
dlls/ntdll/server.c
View file @
1e78c993
...
...
@@ -1428,6 +1428,7 @@ NTSTATUS server_init_process_done(void)
*/
size_t
server_init_thread
(
void
*
entry_point
)
{
static
const
char
*
cpu_names
[]
=
{
"x86"
,
"x86_64"
,
"PowerPC"
,
"ARM"
,
"ARM64"
};
static
const
BOOL
is_win64
=
(
sizeof
(
void
*
)
>
sizeof
(
int
));
const
char
*
arch
=
getenv
(
"WINEARCH"
);
int
ret
;
...
...
@@ -1485,15 +1486,14 @@ size_t server_init_thread( void *entry_point )
wine_get_config_dir
()
);
}
return
info_size
;
case
STATUS_
NOT_REGISTRY_FILE
:
case
STATUS_
INVALID_IMAGE_WIN_64
:
fatal_error
(
"'%s' is a 32-bit installation, it cannot support 64-bit applications.
\n
"
,
wine_get_config_dir
()
);
case
STATUS_NOT_SUPPORTED
:
if
(
is_win64
)
fatal_error
(
"wineserver is 32-bit, it cannot support 64-bit applications.
\n
"
);
else
fatal_error
(
"'%s' is a 64-bit installation, it cannot be used with a 32-bit wineserver.
\n
"
,
wine_get_config_dir
()
);
fatal_error
(
"'%s' is a 64-bit installation, it cannot be used with a 32-bit wineserver.
\n
"
,
wine_get_config_dir
()
);
case
STATUS_INVALID_IMAGE_FORMAT
:
fatal_error
(
"wineserver doesn't support the %s architecture
\n
"
,
cpu_names
[
client_cpu
]
);
default:
server_protocol_error
(
"init_thread failed with status %x
\n
"
,
ret
);
}
...
...
include/wine/server_protocol.h
View file @
1e78c993
...
...
@@ -667,9 +667,11 @@ struct new_process_request
unsigned
int
process_attr
;
unsigned
int
thread_access
;
unsigned
int
thread_attr
;
cpu_type_t
cpu
;
data_size_t
info_size
;
/* VARARG(info,startup_info,info_size); */
/* VARARG(env,unicode_str); */
char
__pad_52
[
4
];
};
struct
new_process_reply
{
...
...
@@ -5846,6 +5848,6 @@ union generic_reply
struct
set_suspend_context_reply
set_suspend_context_reply
;
};
#define SERVER_PROTOCOL_VERSION 45
2
#define SERVER_PROTOCOL_VERSION 45
3
#endif
/* __WINE_WINE_SERVER_PROTOCOL_H */
server/process.c
View file @
1e78c993
...
...
@@ -898,6 +898,11 @@ DECL_HANDLER(new_process)
close
(
socket_fd
);
return
;
}
if
(
!
is_cpu_supported
(
req
->
cpu
))
{
close
(
socket_fd
);
return
;
}
if
(
!
req
->
info_size
)
/* create an orphaned process */
{
...
...
server/protocol.def
View file @
1e78c993
...
...
@@ -681,6 +681,7 @@ struct rawinput_device
unsigned int process_attr; /* attributes for process object */
unsigned int thread_access; /* access rights for thread object */
unsigned int thread_attr; /* attributes for thread object */
cpu_type_t cpu; /* CPU that the new process will use */
data_size_t info_size; /* size of startup info */
VARARG(info,startup_info,info_size); /* startup information */
VARARG(env,unicode_str); /* environment for new process */
...
...
server/request.h
View file @
1e78c993
...
...
@@ -659,8 +659,9 @@ C_ASSERT( FIELD_OFFSET(struct new_process_request, process_access) == 28 );
C_ASSERT
(
FIELD_OFFSET
(
struct
new_process_request
,
process_attr
)
==
32
);
C_ASSERT
(
FIELD_OFFSET
(
struct
new_process_request
,
thread_access
)
==
36
);
C_ASSERT
(
FIELD_OFFSET
(
struct
new_process_request
,
thread_attr
)
==
40
);
C_ASSERT
(
FIELD_OFFSET
(
struct
new_process_request
,
info_size
)
==
44
);
C_ASSERT
(
sizeof
(
struct
new_process_request
)
==
48
);
C_ASSERT
(
FIELD_OFFSET
(
struct
new_process_request
,
cpu
)
==
44
);
C_ASSERT
(
FIELD_OFFSET
(
struct
new_process_request
,
info_size
)
==
48
);
C_ASSERT
(
sizeof
(
struct
new_process_request
)
==
56
);
C_ASSERT
(
FIELD_OFFSET
(
struct
new_process_reply
,
info
)
==
8
);
C_ASSERT
(
FIELD_OFFSET
(
struct
new_process_reply
,
pid
)
==
12
);
C_ASSERT
(
FIELD_OFFSET
(
struct
new_process_reply
,
phandle
)
==
16
);
...
...
server/thread.c
View file @
1e78c993
...
...
@@ -1189,6 +1189,21 @@ struct token *thread_get_impersonation_token( struct thread *thread )
return
thread
->
process
->
token
;
}
/* check if a cpu type can be supported on this server */
int
is_cpu_supported
(
enum
cpu_type
cpu
)
{
unsigned
int
prefix_cpu_mask
=
get_prefix_cpu_mask
();
if
(
CPU_FLAG
(
cpu
)
&&
(
supported_cpus
&
prefix_cpu_mask
&
CPU_FLAG
(
cpu
)))
return
1
;
if
(
!
(
supported_cpus
&
prefix_cpu_mask
))
set_error
(
STATUS_NOT_SUPPORTED
);
else
if
(
supported_cpus
&
CPU_FLAG
(
cpu
))
set_error
(
STATUS_INVALID_IMAGE_WIN_64
);
/* server supports it but not the prefix */
else
set_error
(
STATUS_INVALID_IMAGE_FORMAT
);
return
0
;
}
/* create a new thread */
DECL_HANDLER
(
new_thread
)
{
...
...
@@ -1218,7 +1233,6 @@ DECL_HANDLER(new_thread)
/* initialize a new thread */
DECL_HANDLER
(
init_thread
)
{
unsigned
int
prefix_cpu_mask
=
get_prefix_cpu_mask
();
struct
process
*
process
=
current
->
process
;
int
wait_fd
,
reply_fd
;
...
...
@@ -1257,14 +1271,7 @@ DECL_HANDLER(init_thread)
if
(
!
process
->
peb
)
/* first thread, initialize the process too */
{
if
(
!
CPU_FLAG
(
req
->
cpu
)
||
!
(
supported_cpus
&
prefix_cpu_mask
&
CPU_FLAG
(
req
->
cpu
)))
{
if
(
!
(
supported_cpus
&
CPU_64BIT_MASK
))
set_error
(
STATUS_NOT_SUPPORTED
);
else
set_error
(
STATUS_NOT_REGISTRY_FILE
);
/* server supports it but not the prefix */
return
;
}
if
(
!
is_cpu_supported
(
req
->
cpu
))
return
;
process
->
unix_pid
=
current
->
unix_pid
;
process
->
peb
=
req
->
entry
;
process
->
cpu
=
req
->
cpu
;
...
...
@@ -1293,7 +1300,7 @@ DECL_HANDLER(init_thread)
reply
->
tid
=
get_thread_id
(
current
);
reply
->
version
=
SERVER_PROTOCOL_VERSION
;
reply
->
server_start
=
server_start_time
;
reply
->
all_cpus
=
supported_cpus
&
prefix_cpu_mask
;
reply
->
all_cpus
=
supported_cpus
&
get_prefix_cpu_mask
()
;
return
;
error
:
...
...
server/thread.h
View file @
1e78c993
...
...
@@ -125,6 +125,7 @@ extern int thread_get_inflight_fd( struct thread *thread, int client );
extern
struct
thread_snapshot
*
thread_snap
(
int
*
count
);
extern
struct
token
*
thread_get_impersonation_token
(
struct
thread
*
thread
);
extern
int
set_thread_affinity
(
struct
thread
*
thread
,
affinity_t
affinity
);
extern
int
is_cpu_supported
(
enum
cpu_type
cpu
);
/* ptrace functions */
...
...
server/trace.c
View file @
1e78c993
...
...
@@ -1106,6 +1106,7 @@ static void dump_new_process_request( const struct new_process_request *req )
fprintf
(
stderr
,
", process_attr=%08x"
,
req
->
process_attr
);
fprintf
(
stderr
,
", thread_access=%08x"
,
req
->
thread_access
);
fprintf
(
stderr
,
", thread_attr=%08x"
,
req
->
thread_attr
);
dump_cpu_type
(
", cpu="
,
&
req
->
cpu
);
fprintf
(
stderr
,
", info_size=%u"
,
req
->
info_size
);
dump_varargs_startup_info
(
", info="
,
min
(
cur_size
,
req
->
info_size
)
);
dump_varargs_unicode_str
(
", env="
,
cur_size
);
...
...
@@ -4909,6 +4910,11 @@ static const struct
{
"INVALID_DEVICE_REQUEST"
,
STATUS_INVALID_DEVICE_REQUEST
},
{
"INVALID_FILE_FOR_SECTION"
,
STATUS_INVALID_FILE_FOR_SECTION
},
{
"INVALID_HANDLE"
,
STATUS_INVALID_HANDLE
},
{
"INVALID_IMAGE_FORMAT"
,
STATUS_INVALID_IMAGE_FORMAT
},
{
"INVALID_IMAGE_NE_FORMAT"
,
STATUS_INVALID_IMAGE_NE_FORMAT
},
{
"INVALID_IMAGE_NOT_MZ"
,
STATUS_INVALID_IMAGE_NOT_MZ
},
{
"INVALID_IMAGE_PROTECT"
,
STATUS_INVALID_IMAGE_PROTECT
},
{
"INVALID_IMAGE_WIN_64"
,
STATUS_INVALID_IMAGE_WIN_64
},
{
"INVALID_PARAMETER"
,
STATUS_INVALID_PARAMETER
},
{
"INVALID_SECURITY_DESCR"
,
STATUS_INVALID_SECURITY_DESCR
},
{
"IO_TIMEOUT"
,
STATUS_IO_TIMEOUT
},
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment