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
c58a10c1
Commit
c58a10c1
authored
Sep 22, 2020
by
Nikolay Sivov
Committed by
Alexandre Julliard
Sep 22, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
server: Implement inherited handles list.
Signed-off-by:
Nikolay Sivov
<
nsivov@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
16832064
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
102 additions
and
18 deletions
+102
-18
process.c
dlls/kernel32/tests/process.c
+0
-1
process.c
dlls/ntdll/unix/process.c
+39
-0
server_protocol.h
include/wine/server_protocol.h
+3
-2
handle.c
server/handle.c
+30
-8
handle.h
server/handle.h
+2
-1
process.c
server/process.c
+20
-4
process.h
server/process.h
+2
-1
protocol.def
server/protocol.def
+2
-0
request.c
server/request.c
+1
-1
request.h
server/request.h
+1
-0
trace.c
server/trace.c
+2
-0
No files found.
dlls/kernel32/tests/process.c
View file @
c58a10c1
...
...
@@ -4102,7 +4102,6 @@ static void test_handle_list_attribute(BOOL child, HANDLE handle1, HANDLE handle
CloseHandle
(
handle1
);
ret
=
GetHandleInformation
(
handle2
,
&
flags
);
todo_wine
ok
(
!
ret
&&
GetLastError
()
==
ERROR_INVALID_HANDLE
,
"Unexpected return value, error %d.
\n
"
,
GetLastError
());
return
;
...
...
dlls/ntdll/unix/process.c
View file @
c58a10c1
...
...
@@ -812,6 +812,28 @@ done:
return
status
;
}
static
NTSTATUS
alloc_handle_list
(
const
PS_ATTRIBUTE
*
handles_attr
,
obj_handle_t
**
handles
,
data_size_t
*
handles_len
)
{
SIZE_T
count
,
i
;
HANDLE
*
src
;
*
handles
=
NULL
;
*
handles_len
=
0
;
if
(
!
handles_attr
)
return
STATUS_SUCCESS
;
count
=
handles_attr
->
Size
/
sizeof
(
HANDLE
);
if
(
!
(
*
handles
=
calloc
(
sizeof
(
**
handles
),
count
)))
return
STATUS_NO_MEMORY
;
src
=
handles_attr
->
ValuePtr
;
for
(
i
=
0
;
i
<
count
;
++
i
)
(
*
handles
)[
i
]
=
wine_server_obj_handle
(
src
[
i
]
);
*
handles_len
=
count
*
sizeof
(
**
handles
);
return
STATUS_SUCCESS
;
}
/**********************************************************************
* NtCreateUserProcess (NTDLL.@)
...
...
@@ -837,6 +859,9 @@ NTSTATUS WINAPI NtCreateUserProcess( HANDLE *process_handle_ptr, HANDLE *thread_
HANDLE
parent
=
0
,
debug
=
0
,
token
=
0
;
UNICODE_STRING
path
=
{
0
};
SIZE_T
i
,
attr_count
=
(
attr
->
TotalLength
-
sizeof
(
attr
->
TotalLength
))
/
sizeof
(
PS_ATTRIBUTE
);
const
PS_ATTRIBUTE
*
handles_attr
=
NULL
;
data_size_t
handles_size
;
obj_handle_t
*
handles
;
for
(
i
=
0
;
i
<
attr_count
;
i
++
)
{
...
...
@@ -855,6 +880,10 @@ NTSTATUS WINAPI NtCreateUserProcess( HANDLE *process_handle_ptr, HANDLE *thread_
case
PS_ATTRIBUTE_TOKEN
:
token
=
attr
->
Attributes
[
i
].
ValuePtr
;
break
;
case
PS_ATTRIBUTE_HANDLE_LIST
:
if
(
process_flags
&
PROCESS_CREATE_FLAGS_INHERIT_HANDLES
)
handles_attr
=
&
attr
->
Attributes
[
i
];
break
;
default:
if
(
attr
->
Attributes
[
i
].
Attribute
&
PS_ATTRIBUTE_INPUT
)
FIXME
(
"unhandled input attribute %lx
\n
"
,
attr
->
Attributes
[
i
].
Attribute
);
...
...
@@ -883,12 +912,19 @@ NTSTATUS WINAPI NtCreateUserProcess( HANDLE *process_handle_ptr, HANDLE *thread_
if
((
status
=
alloc_object_attributes
(
process_attr
,
&
objattr
,
&
attr_len
)))
goto
done
;
if
((
status
=
alloc_handle_list
(
handles_attr
,
&
handles
,
&
handles_size
)))
{
free
(
objattr
);
goto
done
;
}
/* create the socket for the new process */
if
(
socketpair
(
PF_UNIX
,
SOCK_STREAM
,
0
,
socketfd
)
==
-
1
)
{
status
=
STATUS_TOO_MANY_OPENED_FILES
;
free
(
objattr
);
free
(
handles
);
goto
done
;
}
#ifdef SO_PASSCRED
...
...
@@ -914,7 +950,9 @@ NTSTATUS WINAPI NtCreateUserProcess( HANDLE *process_handle_ptr, HANDLE *thread_
req
->
access
=
process_access
;
req
->
cpu
=
pe_info
.
cpu
;
req
->
info_size
=
startup_info_size
;
req
->
handles_size
=
handles_size
;
wine_server_add_data
(
req
,
objattr
,
attr_len
);
wine_server_add_data
(
req
,
handles
,
handles_size
);
wine_server_add_data
(
req
,
startup_info
,
startup_info_size
);
wine_server_add_data
(
req
,
params
->
Environment
,
env_size
);
if
(
!
(
status
=
wine_server_call
(
req
)))
...
...
@@ -926,6 +964,7 @@ NTSTATUS WINAPI NtCreateUserProcess( HANDLE *process_handle_ptr, HANDLE *thread_
}
SERVER_END_REQ
;
free
(
objattr
);
free
(
handles
);
if
(
status
)
{
...
...
include/wine/server_protocol.h
View file @
c58a10c1
...
...
@@ -781,10 +781,11 @@ struct new_process_request
unsigned
int
access
;
client_cpu_t
cpu
;
data_size_t
info_size
;
data_size_t
handles_size
;
/* VARARG(objattr,object_attributes); */
/* VARARG(handles,uints,handles_size); */
/* VARARG(info,startup_info,info_size); */
/* VARARG(env,unicode_str); */
char
__pad_44
[
4
];
};
struct
new_process_reply
{
...
...
@@ -6282,7 +6283,7 @@ union generic_reply
/* ### protocol_version begin ### */
#define SERVER_PROTOCOL_VERSION 64
3
#define SERVER_PROTOCOL_VERSION 64
4
/* ### protocol_version end ### */
...
...
server/handle.c
View file @
c58a10c1
...
...
@@ -355,7 +355,8 @@ static void shrink_handle_table( struct handle_table *table )
/* copy the handle table of the parent process */
/* return 1 if OK, 0 on error */
struct
handle_table
*
copy_handle_table
(
struct
process
*
process
,
struct
process
*
parent
)
struct
handle_table
*
copy_handle_table
(
struct
process
*
process
,
struct
process
*
parent
,
const
obj_handle_t
*
handles
,
unsigned
int
handle_count
)
{
struct
handle_table
*
parent_table
=
parent
->
handles
;
struct
handle_table
*
table
;
...
...
@@ -367,15 +368,36 @@ struct handle_table *copy_handle_table( struct process *process, struct process
if
(
!
(
table
=
alloc_handle_table
(
process
,
parent_table
->
count
)))
return
NULL
;
if
(
(
table
->
last
=
parent_table
->
last
)
>=
0
)
if
(
handles
)
{
struct
handle_entry
*
ptr
=
table
->
entries
;
memcpy
(
ptr
,
parent_table
->
entries
,
(
table
->
last
+
1
)
*
sizeof
(
struct
handle_entry
)
);
for
(
i
=
0
;
i
<=
table
->
last
;
i
++
,
ptr
++
)
struct
handle_entry
*
dst
,
*
src
;
int
index
;
dst
=
table
->
entries
;
memset
(
dst
,
0
,
parent_table
->
count
*
sizeof
(
*
dst
)
);
for
(
i
=
0
;
i
<
handle_count
;
i
++
)
{
src
=
get_handle
(
parent
,
handles
[
i
]
);
if
(
!
src
||
!
(
src
->
access
&
RESERVED_INHERIT
))
continue
;
grab_object_for_handle
(
src
->
ptr
);
index
=
handle_to_index
(
handles
[
i
]
);
dst
[
index
]
=
*
src
;
table
->
last
=
max
(
table
->
last
,
index
);
}
}
else
{
if
((
table
->
last
=
parent_table
->
last
)
>=
0
)
{
if
(
!
ptr
->
ptr
)
continue
;
if
(
ptr
->
access
&
RESERVED_INHERIT
)
grab_object_for_handle
(
ptr
->
ptr
);
else
ptr
->
ptr
=
NULL
;
/* don't inherit this entry */
struct
handle_entry
*
ptr
=
table
->
entries
;
memcpy
(
ptr
,
parent_table
->
entries
,
(
table
->
last
+
1
)
*
sizeof
(
struct
handle_entry
)
);
for
(
i
=
0
;
i
<=
table
->
last
;
i
++
,
ptr
++
)
{
if
(
!
ptr
->
ptr
)
continue
;
if
(
ptr
->
access
&
RESERVED_INHERIT
)
grab_object_for_handle
(
ptr
->
ptr
);
else
ptr
->
ptr
=
NULL
;
/* don't inherit this entry */
}
}
}
/* attempt to shrink the table */
...
...
server/handle.h
View file @
c58a10c1
...
...
@@ -50,7 +50,8 @@ extern obj_handle_t open_object( struct process *process, obj_handle_t parent, u
extern
obj_handle_t
find_inherited_handle
(
struct
process
*
process
,
const
struct
object_ops
*
ops
);
extern
void
close_process_handles
(
struct
process
*
process
);
extern
struct
handle_table
*
alloc_handle_table
(
struct
process
*
process
,
int
count
);
extern
struct
handle_table
*
copy_handle_table
(
struct
process
*
process
,
struct
process
*
parent
);
extern
struct
handle_table
*
copy_handle_table
(
struct
process
*
process
,
struct
process
*
parent
,
const
obj_handle_t
*
handles
,
unsigned
int
handle_count
);
extern
unsigned
int
get_handle_table_count
(
struct
process
*
process
);
#endif
/* __WINE_SERVER_HANDLE_H */
server/process.c
View file @
c58a10c1
...
...
@@ -500,7 +500,8 @@ static void start_sigkill_timer( struct process *process )
/* create a new 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
struct
security_descriptor
*
sd
,
const
obj_handle_t
*
handles
,
unsigned
int
handle_count
)
{
struct
process
*
process
;
...
...
@@ -573,7 +574,7 @@ struct process *create_process( int fd, struct process *parent, int inherit_all,
else
{
process
->
parent_id
=
parent
->
id
;
process
->
handles
=
inherit_all
?
copy_handle_table
(
process
,
parent
)
process
->
handles
=
inherit_all
?
copy_handle_table
(
process
,
parent
,
handles
,
handle_count
)
:
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 */
...
...
@@ -1101,6 +1102,7 @@ DECL_HANDLER(new_process)
struct
process
*
parent
;
struct
thread
*
parent_thread
=
current
;
int
socket_fd
=
thread_get_inflight_fd
(
current
,
req
->
socket_fd
);
const
obj_handle_t
*
handles
=
NULL
;
if
(
socket_fd
==
-
1
)
{
...
...
@@ -1162,6 +1164,19 @@ DECL_HANDLER(new_process)
info
->
data
=
NULL
;
info_ptr
=
get_req_data_after_objattr
(
objattr
,
&
info
->
data_size
);
if
((
req
->
handles_size
&
3
)
||
req
->
handles_size
>
info
->
data_size
)
{
set_error
(
STATUS_INVALID_PARAMETER
);
close
(
socket_fd
);
goto
done
;
}
if
(
req
->
handles_size
)
{
handles
=
info_ptr
;
info_ptr
=
(
const
char
*
)
info_ptr
+
req
->
handles_size
;
info
->
data_size
-=
req
->
handles_size
;
}
info
->
info_size
=
min
(
req
->
info_size
,
info
->
data_size
);
if
(
req
->
info_size
<
sizeof
(
*
info
->
data
))
...
...
@@ -1202,7 +1217,8 @@ DECL_HANDLER(new_process)
#undef FIXUP_LEN
}
if
(
!
(
process
=
create_process
(
socket_fd
,
parent
,
req
->
inherit_all
,
sd
)))
goto
done
;
if
(
!
(
process
=
create_process
(
socket_fd
,
parent
,
req
->
inherit_all
,
sd
,
handles
,
req
->
handles_size
/
sizeof
(
*
handles
)
)))
goto
done
;
process
->
startup_info
=
(
struct
startup_info
*
)
grab_object
(
info
);
...
...
@@ -1297,7 +1313,7 @@ DECL_HANDLER(exec_process)
close
(
socket_fd
);
return
;
}
if
(
!
(
process
=
create_process
(
socket_fd
,
NULL
,
0
,
NULL
)))
return
;
if
(
!
(
process
=
create_process
(
socket_fd
,
NULL
,
0
,
NULL
,
NULL
,
0
)))
return
;
create_thread
(
-
1
,
process
,
NULL
);
release_object
(
process
);
}
...
...
server/process.h
View file @
c58a10c1
...
...
@@ -109,7 +109,8 @@ extern unsigned int alloc_ptid( void *ptr );
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
struct
security_descriptor
*
sd
,
const
obj_handle_t
*
handles
,
unsigned
int
handle_count
);
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 @
c58a10c1
...
...
@@ -795,7 +795,9 @@ struct rawinput_device
unsigned int access; /* access rights for process object */
client_cpu_t cpu; /* CPU that the new process will use */
data_size_t info_size; /* size of startup info */
data_size_t handles_size; /* length of explicit handles list */
VARARG(objattr,object_attributes); /* object attributes */
VARARG(handles,uints,handles_size); /* handles list */
VARARG(info,startup_info,info_size); /* startup information */
VARARG(env,unicode_str); /* environment for new process */
@REPLY
...
...
server/request.c
View file @
c58a10c1
...
...
@@ -582,7 +582,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
)))
if
((
process
=
create_process
(
client
,
NULL
,
0
,
NULL
,
NULL
,
0
)))
{
create_thread
(
-
1
,
process
,
NULL
);
release_object
(
process
);
...
...
server/request.h
View file @
c58a10c1
...
...
@@ -725,6 +725,7 @@ 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_reply
,
info
)
==
8
);
C_ASSERT
(
FIELD_OFFSET
(
struct
new_process_reply
,
pid
)
==
12
);
...
...
server/trace.c
View file @
c58a10c1
...
...
@@ -1292,7 +1292,9 @@ static void dump_new_process_request( const struct new_process_request *req )
fprintf
(
stderr
,
", access=%08x"
,
req
->
access
);
dump_client_cpu
(
", cpu="
,
&
req
->
cpu
);
fprintf
(
stderr
,
", info_size=%u"
,
req
->
info_size
);
fprintf
(
stderr
,
", handles_size=%u"
,
req
->
handles_size
);
dump_varargs_object_attributes
(
", objattr="
,
cur_size
);
dump_varargs_uints
(
", handles="
,
min
(
cur_size
,
req
->
handles_size
)
);
dump_varargs_startup_info
(
", info="
,
min
(
cur_size
,
req
->
info_size
)
);
dump_varargs_unicode_str
(
", env="
,
cur_size
);
}
...
...
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