Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
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-cw
Commits
d0bea3d7
Commit
d0bea3d7
authored
Sep 23, 2020
by
Michael Müller
Committed by
Alexandre Julliard
Sep 24, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
server: Implement support for creating a process with a specified token.
Signed-off-by:
Zebediah Figura
<
z.figura12@gmail.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
2379e3c1
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
50 additions
and
32 deletions
+50
-32
security.c
dlls/advapi32/tests/security.c
+11
-13
process.c
dlls/ntdll/unix/process.c
+1
-1
server_protocol.h
include/wine/server_protocol.h
+3
-1
process.c
server/process.c
+13
-4
process.h
server/process.h
+1
-1
protocol.def
server/protocol.def
+1
-0
request.c
server/request.c
+1
-1
request.h
server/request.h
+11
-10
security.h
server/security.h
+1
-0
token.c
server/token.c
+5
-0
trace.c
server/trace.c
+2
-1
No files found.
dlls/advapi32/tests/security.c
View file @
d0bea3d7
...
...
@@ -7732,16 +7732,16 @@ static void test_duplicate_handle_access_child(void)
SetLastError
(
0xdeadbeef
);
event2
=
OpenEventA
(
EVENT_MODIFY_STATE
,
FALSE
,
"test_dup"
);
todo_wine
ok
(
!
event2
,
"expected failure
\n
"
);
todo_wine
ok
(
GetLastError
()
==
ERROR_ACCESS_DENIED
,
"got error %u
\n
"
,
GetLastError
());
ok
(
!
event2
,
"expected failure
\n
"
);
ok
(
GetLastError
()
==
ERROR_ACCESS_DENIED
,
"got error %u
\n
"
,
GetLastError
());
ret
=
DuplicateHandle
(
process
,
event
,
process
,
&
event2
,
EVENT_MODIFY_STATE
,
FALSE
,
0
);
ok
(
ret
,
"got error %u
\n
"
,
GetLastError
());
todo_wine
ok
(
ret
,
"got error %u
\n
"
,
GetLastError
());
SetLastError
(
0xdeadbeef
);
ret
=
DuplicateHandle
(
process
,
event
,
GetCurrentProcess
(),
&
event2
,
EVENT_MODIFY_STATE
,
FALSE
,
0
);
todo_wine
ok
(
!
ret
,
"expected failure
\n
"
);
todo_wine
ok
(
GetLastError
()
==
ERROR_ACCESS_DENIED
,
"got error %u
\n
"
,
GetLastError
());
ok
(
!
ret
,
"expected failure
\n
"
);
ok
(
GetLastError
()
==
ERROR_ACCESS_DENIED
,
"got error %u
\n
"
,
GetLastError
());
ret
=
DuplicateHandle
(
process
,
(
HANDLE
)(
ULONG_PTR
)
_atoi64
(
myARGV
[
5
]),
GetCurrentProcess
(),
&
token
,
0
,
FALSE
,
DUPLICATE_SAME_ACCESS
);
...
...
@@ -7823,17 +7823,15 @@ static void test_create_process_token(void)
ret
=
OpenProcessToken
(
GetCurrentProcess
(),
TOKEN_QUERY
,
&
token
);
ok
(
ret
,
"got error %u
\n
"
,
GetLastError
());
ret
=
CreateProcessAsUserA
(
token
,
NULL
,
cmdline
,
NULL
,
NULL
,
FALSE
,
0
,
NULL
,
NULL
,
&
si
,
&
pi
);
todo_wine
ok
(
!
ret
,
"expected failure
\n
"
);
todo_wine
ok
(
GetLastError
()
==
ERROR_ACCESS_DENIED
,
"got error %u
\n
"
,
GetLastError
());
if
(
ret
)
join_process
(
&
pi
);
ok
(
!
ret
,
"expected failure
\n
"
);
ok
(
GetLastError
()
==
ERROR_ACCESS_DENIED
,
"got error %u
\n
"
,
GetLastError
());
CloseHandle
(
token
);
ret
=
OpenProcessToken
(
GetCurrentProcess
(),
TOKEN_ASSIGN_PRIMARY
,
&
token
);
ok
(
ret
,
"got error %u
\n
"
,
GetLastError
());
ret
=
CreateProcessAsUserA
(
token
,
NULL
,
cmdline
,
NULL
,
NULL
,
FALSE
,
0
,
NULL
,
NULL
,
&
si
,
&
pi
);
todo_wine
ok
(
!
ret
,
"expected failure
\n
"
);
todo_wine
ok
(
GetLastError
()
==
ERROR_ACCESS_DENIED
,
"got error %u
\n
"
,
GetLastError
());
if
(
ret
)
join_process
(
&
pi
);
ok
(
!
ret
,
"expected failure
\n
"
);
ok
(
GetLastError
()
==
ERROR_ACCESS_DENIED
,
"got error %u
\n
"
,
GetLastError
());
CloseHandle
(
token
);
ret
=
OpenProcessToken
(
GetCurrentProcess
(),
TOKEN_QUERY
|
TOKEN_ASSIGN_PRIMARY
|
TOKEN_DUPLICATE
,
&
token
);
...
...
@@ -7875,8 +7873,8 @@ static void test_create_process_token_child(void)
}
else
{
todo_wine
ok
(
!
event
,
"expected failure
\n
"
);
todo_wine
ok
(
GetLastError
()
==
ERROR_ACCESS_DENIED
,
"got error %u
\n
"
,
GetLastError
());
ok
(
!
event
,
"expected failure
\n
"
);
ok
(
GetLastError
()
==
ERROR_ACCESS_DENIED
,
"got error %u
\n
"
,
GetLastError
());
}
}
...
...
dlls/ntdll/unix/process.c
View file @
d0bea3d7
...
...
@@ -894,7 +894,6 @@ NTSTATUS WINAPI NtCreateUserProcess( HANDLE *process_handle_ptr, HANDLE *thread_
TRACE
(
"%s image %s cmdline %s parent %p
\n
"
,
debugstr_us
(
&
path
),
debugstr_us
(
&
params
->
ImagePathName
),
debugstr_us
(
&
params
->
CommandLine
),
parent
);
if
(
debug
)
FIXME
(
"debug port %p not supported yet
\n
"
,
debug
);
if
(
token
)
FIXME
(
"token %p not supported yet
\n
"
,
token
);
unixdir
=
get_unix_curdir
(
params
);
...
...
@@ -942,6 +941,7 @@ NTSTATUS WINAPI NtCreateUserProcess( HANDLE *process_handle_ptr, HANDLE *thread_
SERVER_START_REQ
(
new_process
)
{
req
->
token
=
wine_server_obj_handle
(
token
);
req
->
parent_process
=
wine_server_obj_handle
(
parent
);
req
->
inherit_all
=
!!
(
process_flags
&
PROCESS_CREATE_FLAGS_INHERIT_HANDLES
);
req
->
create_flags
=
params
->
DebugFlags
;
/* hack: creation flags stored in DebugFlags for now */
...
...
include/wine/server_protocol.h
View file @
d0bea3d7
...
...
@@ -773,6 +773,7 @@ struct rawinput_device
struct
new_process_request
{
struct
request_header
__header
;
obj_handle_t
token
;
obj_handle_t
parent_process
;
int
inherit_all
;
unsigned
int
create_flags
;
...
...
@@ -786,6 +787,7 @@ struct new_process_request
/* VARARG(handles,uints,handles_size); */
/* VARARG(info,startup_info,info_size); */
/* VARARG(env,unicode_str); */
char
__pad_52
[
4
];
};
struct
new_process_reply
{
...
...
@@ -6300,7 +6302,7 @@ union generic_reply
/* ### protocol_version begin ### */
#define SERVER_PROTOCOL_VERSION 64
6
#define SERVER_PROTOCOL_VERSION 64
7
/* ### protocol_version end ### */
...
...
server/process.c
View file @
d0bea3d7
...
...
@@ -504,7 +504,7 @@ static void start_sigkill_timer( struct process *process )
/* if the function fails the fd is closed */
struct
process
*
create_process
(
int
fd
,
struct
process
*
parent
,
int
inherit_all
,
const
struct
security_descriptor
*
sd
,
const
obj_handle_t
*
handles
,
unsigned
int
handle_count
)
unsigned
int
handle_count
,
struct
token
*
token
)
{
struct
process
*
process
;
...
...
@@ -581,7 +581,7 @@ struct process *create_process( int fd, struct process *parent, int inherit_all,
:
alloc_handle_table
(
process
,
0
);
/* Note: for security reasons, starting a new process does not attempt
* to use the current impersonation token for the new process */
process
->
token
=
token_duplicate
(
parent
->
token
,
TRUE
,
0
,
NULL
,
NULL
,
0
,
NULL
,
0
);
process
->
token
=
token_duplicate
(
token
?
token
:
parent
->
token
,
TRUE
,
0
,
NULL
,
NULL
,
0
,
NULL
,
0
);
process
->
affinity
=
parent
->
affinity
;
}
if
(
!
process
->
handles
||
!
process
->
token
)
goto
error
;
...
...
@@ -1102,6 +1102,7 @@ DECL_HANDLER(new_process)
const
struct
security_descriptor
*
sd
;
const
struct
object_attributes
*
objattr
=
get_req_object_attributes
(
&
sd
,
&
name
,
NULL
);
struct
process
*
process
=
NULL
;
struct
token
*
token
=
NULL
;
struct
process
*
parent
;
struct
thread
*
parent_thread
=
current
;
int
socket_fd
=
thread_get_inflight_fd
(
current
,
req
->
socket_fd
);
...
...
@@ -1220,7 +1221,14 @@ DECL_HANDLER(new_process)
#undef FIXUP_LEN
}
if
(
!
(
process
=
create_process
(
socket_fd
,
parent
,
req
->
inherit_all
,
sd
,
handles
,
req
->
handles_size
/
sizeof
(
*
handles
)
)))
if
(
req
->
token
&&
!
(
token
=
get_token_obj
(
current
->
process
,
req
->
token
,
TOKEN_QUERY
|
TOKEN_ASSIGN_PRIMARY
)))
{
close
(
socket_fd
);
goto
done
;
}
if
(
!
(
process
=
create_process
(
socket_fd
,
parent
,
req
->
inherit_all
,
sd
,
handles
,
req
->
handles_size
/
sizeof
(
*
handles
),
token
)))
goto
done
;
process
->
startup_info
=
(
struct
startup_info
*
)
grab_object
(
info
);
...
...
@@ -1284,6 +1292,7 @@ DECL_HANDLER(new_process)
done
:
if
(
process
)
release_object
(
process
);
if
(
token
)
release_object
(
token
);
release_object
(
parent
);
release_object
(
info
);
}
...
...
@@ -1316,7 +1325,7 @@ DECL_HANDLER(exec_process)
close
(
socket_fd
);
return
;
}
if
(
!
(
process
=
create_process
(
socket_fd
,
NULL
,
0
,
NULL
,
NULL
,
0
)))
return
;
if
(
!
(
process
=
create_process
(
socket_fd
,
NULL
,
0
,
NULL
,
NULL
,
0
,
NULL
)))
return
;
create_thread
(
-
1
,
process
,
NULL
);
release_object
(
process
);
}
...
...
server/process.h
View file @
d0bea3d7
...
...
@@ -110,7 +110,7 @@ extern void free_ptid( unsigned int id );
extern
void
*
get_ptid_entry
(
unsigned
int
id
);
extern
struct
process
*
create_process
(
int
fd
,
struct
process
*
parent
,
int
inherit_all
,
const
struct
security_descriptor
*
sd
,
const
obj_handle_t
*
handles
,
unsigned
int
handle_count
);
unsigned
int
handle_count
,
struct
token
*
token
);
extern
data_size_t
init_process
(
struct
thread
*
thread
);
extern
struct
thread
*
get_process_first_thread
(
struct
process
*
process
);
extern
struct
process
*
get_process_from_id
(
process_id_t
id
);
...
...
server/protocol.def
View file @
d0bea3d7
...
...
@@ -787,6 +787,7 @@ struct rawinput_device
/* Create a new process from the context of the parent */
@REQ(new_process)
obj_handle_t token; /* process token */
obj_handle_t parent_process; /* parent process */
int inherit_all; /* inherit all handles from parent */
unsigned int create_flags; /* creation flags */
...
...
server/request.c
View file @
d0bea3d7
...
...
@@ -583,7 +583,7 @@ static void master_socket_poll_event( struct fd *fd, int event )
int
client
=
accept
(
get_unix_fd
(
master_socket
->
fd
),
(
struct
sockaddr
*
)
&
dummy
,
&
len
);
if
(
client
==
-
1
)
return
;
fcntl
(
client
,
F_SETFL
,
O_NONBLOCK
);
if
((
process
=
create_process
(
client
,
NULL
,
0
,
NULL
,
NULL
,
0
)))
if
((
process
=
create_process
(
client
,
NULL
,
0
,
NULL
,
NULL
,
0
,
NULL
)))
{
create_thread
(
-
1
,
process
,
NULL
);
release_object
(
process
);
...
...
server/request.h
View file @
d0bea3d7
...
...
@@ -719,16 +719,17 @@ C_ASSERT( sizeof(unsigned char) == 1 );
C_ASSERT
(
sizeof
(
unsigned
int
)
==
4
);
C_ASSERT
(
sizeof
(
unsigned
short
)
==
2
);
C_ASSERT
(
sizeof
(
user_handle_t
)
==
4
);
C_ASSERT
(
FIELD_OFFSET
(
struct
new_process_request
,
parent_process
)
==
12
);
C_ASSERT
(
FIELD_OFFSET
(
struct
new_process_request
,
inherit_all
)
==
16
);
C_ASSERT
(
FIELD_OFFSET
(
struct
new_process_request
,
create_flags
)
==
20
);
C_ASSERT
(
FIELD_OFFSET
(
struct
new_process_request
,
socket_fd
)
==
24
);
C_ASSERT
(
FIELD_OFFSET
(
struct
new_process_request
,
exe_file
)
==
28
);
C_ASSERT
(
FIELD_OFFSET
(
struct
new_process_request
,
access
)
==
32
);
C_ASSERT
(
FIELD_OFFSET
(
struct
new_process_request
,
cpu
)
==
36
);
C_ASSERT
(
FIELD_OFFSET
(
struct
new_process_request
,
info_size
)
==
40
);
C_ASSERT
(
FIELD_OFFSET
(
struct
new_process_request
,
handles_size
)
==
44
);
C_ASSERT
(
sizeof
(
struct
new_process_request
)
==
48
);
C_ASSERT
(
FIELD_OFFSET
(
struct
new_process_request
,
token
)
==
12
);
C_ASSERT
(
FIELD_OFFSET
(
struct
new_process_request
,
parent_process
)
==
16
);
C_ASSERT
(
FIELD_OFFSET
(
struct
new_process_request
,
inherit_all
)
==
20
);
C_ASSERT
(
FIELD_OFFSET
(
struct
new_process_request
,
create_flags
)
==
24
);
C_ASSERT
(
FIELD_OFFSET
(
struct
new_process_request
,
socket_fd
)
==
28
);
C_ASSERT
(
FIELD_OFFSET
(
struct
new_process_request
,
exe_file
)
==
32
);
C_ASSERT
(
FIELD_OFFSET
(
struct
new_process_request
,
access
)
==
36
);
C_ASSERT
(
FIELD_OFFSET
(
struct
new_process_request
,
cpu
)
==
40
);
C_ASSERT
(
FIELD_OFFSET
(
struct
new_process_request
,
info_size
)
==
44
);
C_ASSERT
(
FIELD_OFFSET
(
struct
new_process_request
,
handles_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
,
handle
)
==
16
);
...
...
server/security.h
View file @
d0bea3d7
...
...
@@ -53,6 +53,7 @@ extern const PSID security_high_label_sid;
/* token functions */
extern
struct
token
*
get_token_obj
(
struct
process
*
process
,
obj_handle_t
handle
,
unsigned
int
access
);
extern
struct
token
*
token_create_admin
(
void
);
extern
int
token_assign_label
(
struct
token
*
token
,
PSID
label
);
extern
struct
token
*
token_duplicate
(
struct
token
*
src_token
,
unsigned
primary
,
...
...
server/token.c
View file @
d0bea3d7
...
...
@@ -835,6 +835,11 @@ int token_assign_label( struct token *token, PSID label )
return
ret
;
}
struct
token
*
get_token_obj
(
struct
process
*
process
,
obj_handle_t
handle
,
unsigned
int
access
)
{
return
(
struct
token
*
)
get_handle_obj
(
process
,
handle
,
access
,
&
token_ops
);
}
struct
token
*
token_create_admin
(
void
)
{
struct
token
*
token
=
NULL
;
...
...
server/trace.c
View file @
d0bea3d7
...
...
@@ -1284,7 +1284,8 @@ typedef void (*dump_func)( const void *req );
static
void
dump_new_process_request
(
const
struct
new_process_request
*
req
)
{
fprintf
(
stderr
,
" parent_process=%04x"
,
req
->
parent_process
);
fprintf
(
stderr
,
" token=%04x"
,
req
->
token
);
fprintf
(
stderr
,
", parent_process=%04x"
,
req
->
parent_process
);
fprintf
(
stderr
,
", inherit_all=%d"
,
req
->
inherit_all
);
fprintf
(
stderr
,
", create_flags=%08x"
,
req
->
create_flags
);
fprintf
(
stderr
,
", socket_fd=%d"
,
req
->
socket_fd
);
...
...
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