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
6a76a0ac
Commit
6a76a0ac
authored
Feb 21, 2007
by
Rob Shearman
Committed by
Alexandre Julliard
Feb 21, 2007
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
server: Check object's security when creating handles.
Don't check object's security when duplicating a handle of the same or lower access rights. Based on a patch by Vitaliy Margolen.
parent
ca6fe3fb
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
79 additions
and
12 deletions
+79
-12
security.c
dlls/advapi32/tests/security.c
+1
-1
handle.c
server/handle.c
+47
-11
security.h
server/security.h
+1
-0
token.c
server/token.c
+30
-0
No files found.
dlls/advapi32/tests/security.c
View file @
6a76a0ac
...
@@ -857,7 +857,7 @@ static void test_token_attr(void)
...
@@ -857,7 +857,7 @@ static void test_token_attr(void)
BYTE
buf
[
1024
];
BYTE
buf
[
1024
];
DWORD
bufsize
=
sizeof
(
buf
);
DWORD
bufsize
=
sizeof
(
buf
);
ret
=
GetTokenInformation
(
Token
,
TokenUser
,(
void
*
)
buf
,
bufsize
,
&
bufsize
);
ret
=
GetTokenInformation
(
Token
,
TokenUser
,(
void
*
)
buf
,
bufsize
,
&
bufsize
);
todo_wine
ok
(
ret
,
"GetTokenInformation failed with error %d
\n
"
,
GetLastError
());
ok
(
ret
,
"GetTokenInformation failed with error %d
\n
"
,
GetLastError
());
CloseHandle
(
Token
);
CloseHandle
(
Token
);
}
}
...
...
server/handle.c
View file @
6a76a0ac
...
@@ -36,6 +36,7 @@
...
@@ -36,6 +36,7 @@
#include "handle.h"
#include "handle.h"
#include "process.h"
#include "process.h"
#include "thread.h"
#include "thread.h"
#include "security.h"
#include "request.h"
#include "request.h"
struct
handle_entry
struct
handle_entry
...
@@ -222,11 +223,10 @@ static obj_handle_t alloc_entry( struct handle_table *table, void *obj, unsigned
...
@@ -222,11 +223,10 @@ static obj_handle_t alloc_entry( struct handle_table *table, void *obj, unsigned
/* allocate a handle for an object, incrementing its refcount */
/* allocate a handle for an object, incrementing its refcount */
/* return the handle, or 0 on error */
/* return the handle, or 0 on error */
obj_handle_t
alloc_handle
(
struct
process
*
process
,
void
*
ptr
,
unsigned
int
access
,
unsigned
int
attr
)
static
obj_handle_t
alloc_handle_no_access_check
(
struct
process
*
process
,
void
*
ptr
,
unsigned
int
access
,
unsigned
int
attr
)
{
{
struct
object
*
obj
=
ptr
;
struct
object
*
obj
=
ptr
;
access
=
obj
->
ops
->
map_access
(
obj
,
access
);
access
&=
~
RESERVED_ALL
;
access
&=
~
RESERVED_ALL
;
if
(
attr
&
OBJ_INHERIT
)
access
|=
RESERVED_INHERIT
;
if
(
attr
&
OBJ_INHERIT
)
access
|=
RESERVED_INHERIT
;
if
(
!
process
->
handles
)
if
(
!
process
->
handles
)
...
@@ -237,9 +237,20 @@ obj_handle_t alloc_handle( struct process *process, void *ptr, unsigned int acce
...
@@ -237,9 +237,20 @@ obj_handle_t alloc_handle( struct process *process, void *ptr, unsigned int acce
return
alloc_entry
(
process
->
handles
,
obj
,
access
);
return
alloc_entry
(
process
->
handles
,
obj
,
access
);
}
}
/* allocate a handle for an object, checking the dacl allows the process to */
/* access it and incrementing its refcount */
/* return the handle, or 0 on error */
obj_handle_t
alloc_handle
(
struct
process
*
process
,
void
*
ptr
,
unsigned
int
access
,
unsigned
int
attr
)
{
struct
object
*
obj
=
ptr
;
access
=
obj
->
ops
->
map_access
(
obj
,
access
);
if
(
access
&&
!
check_object_access
(
obj
,
&
access
))
return
0
;
return
alloc_handle_no_access_check
(
process
,
ptr
,
access
,
attr
);
}
/* allocate a global handle for an object, incrementing its refcount */
/* allocate a global handle for an object, incrementing its refcount */
/* return the handle, or 0 on error */
/* return the handle, or 0 on error */
static
obj_handle_t
alloc_global_handle
(
void
*
obj
,
unsigned
int
access
)
static
obj_handle_t
alloc_global_handle
_no_access_check
(
void
*
obj
,
unsigned
int
access
)
{
{
if
(
!
global_table
)
if
(
!
global_table
)
{
{
...
@@ -250,6 +261,15 @@ static obj_handle_t alloc_global_handle( void *obj, unsigned int access )
...
@@ -250,6 +261,15 @@ static obj_handle_t alloc_global_handle( void *obj, unsigned int access )
return
handle_local_to_global
(
alloc_entry
(
global_table
,
obj
,
access
));
return
handle_local_to_global
(
alloc_entry
(
global_table
,
obj
,
access
));
}
}
/* allocate a global handle for an object, checking the dacl allows the */
/* process to access it and incrementing its refcount and incrementing its refcount */
/* return the handle, or 0 on error */
static
obj_handle_t
alloc_global_handle
(
void
*
obj
,
unsigned
int
access
)
{
if
(
access
&&
!
check_object_access
(
obj
,
&
access
))
return
0
;
return
alloc_global_handle_no_access_check
(
obj
,
access
);
}
/* return a handle entry, or NULL if the handle is invalid */
/* return a handle entry, or NULL if the handle is invalid */
static
struct
handle_entry
*
get_handle
(
struct
process
*
process
,
obj_handle_t
handle
)
static
struct
handle_entry
*
get_handle
(
struct
process
*
process
,
obj_handle_t
handle
)
{
{
...
@@ -449,25 +469,41 @@ obj_handle_t duplicate_handle( struct process *src, obj_handle_t src_handle, str
...
@@ -449,25 +469,41 @@ obj_handle_t duplicate_handle( struct process *src, obj_handle_t src_handle, str
unsigned
int
access
,
unsigned
int
attr
,
unsigned
int
options
)
unsigned
int
access
,
unsigned
int
attr
,
unsigned
int
options
)
{
{
obj_handle_t
res
;
obj_handle_t
res
;
struct
handle_entry
*
entry
;
unsigned
int
src_access
;
struct
object
*
obj
=
get_handle_obj
(
src
,
src_handle
,
0
,
NULL
);
struct
object
*
obj
=
get_handle_obj
(
src
,
src_handle
,
0
,
NULL
);
if
(
!
obj
)
return
0
;
if
(
!
obj
)
return
0
;
if
(
options
&
DUP_HANDLE_SAME_ACCESS
)
if
((
entry
=
get_handle
(
src
,
src_handle
)))
{
src_access
=
entry
->
access
;
struct
handle_entry
*
entry
=
get_handle
(
src
,
src_handle
);
if
(
entry
)
access
=
entry
->
access
;
else
/* pseudo-handle, give it full access */
else
/* pseudo-handle, give it full access */
{
{
access
=
obj
->
ops
->
map_access
(
obj
,
GENERIC_ALL
);
src_
access
=
obj
->
ops
->
map_access
(
obj
,
GENERIC_ALL
);
clear_error
();
clear_error
();
}
}
}
src_access
&=
~
RESERVED_ALL
;
access
&=
~
RESERVED_ALL
;
if
(
options
&
DUP_HANDLE_SAME_ACCESS
)
access
=
src_access
;
else
access
=
obj
->
ops
->
map_access
(
obj
,
access
)
&
~
RESERVED_ALL
;
/* asking for the more access rights than src_access? */
if
(
access
&
~
src_access
)
{
if
(
options
&
DUP_HANDLE_MAKE_GLOBAL
)
if
(
options
&
DUP_HANDLE_MAKE_GLOBAL
)
res
=
alloc_global_handle
(
obj
,
access
);
res
=
alloc_global_handle
(
obj
,
access
);
else
else
res
=
alloc_handle
(
dst
,
obj
,
access
,
attr
);
res
=
alloc_handle
(
dst
,
obj
,
access
,
attr
);
}
else
{
if
(
options
&
DUP_HANDLE_MAKE_GLOBAL
)
res
=
alloc_global_handle_no_access_check
(
obj
,
access
);
else
res
=
alloc_handle_no_access_check
(
dst
,
obj
,
access
,
attr
);
}
release_object
(
obj
);
release_object
(
obj
);
return
res
;
return
res
;
}
}
...
...
server/security.h
View file @
6a76a0ac
...
@@ -47,6 +47,7 @@ extern int token_check_privileges( struct token *token, int all_required,
...
@@ -47,6 +47,7 @@ extern int token_check_privileges( struct token *token, int all_required,
unsigned
int
count
,
LUID_AND_ATTRIBUTES
*
usedprivs
);
unsigned
int
count
,
LUID_AND_ATTRIBUTES
*
usedprivs
);
extern
const
ACL
*
token_get_default_dacl
(
struct
token
*
token
);
extern
const
ACL
*
token_get_default_dacl
(
struct
token
*
token
);
extern
void
security_set_thread_token
(
struct
thread
*
thread
,
obj_handle_t
handle
);
extern
void
security_set_thread_token
(
struct
thread
*
thread
,
obj_handle_t
handle
);
extern
int
check_object_access
(
struct
object
*
obj
,
unsigned
int
*
access
);
static
inline
int
thread_single_check_privilege
(
struct
thread
*
thread
,
const
LUID
*
priv
)
static
inline
int
thread_single_check_privilege
(
struct
thread
*
thread
,
const
LUID
*
priv
)
{
{
...
...
server/token.c
View file @
6a76a0ac
...
@@ -1005,6 +1005,36 @@ static void set_object_sd( struct object *obj, const struct security_descriptor
...
@@ -1005,6 +1005,36 @@ static void set_object_sd( struct object *obj, const struct security_descriptor
obj
->
sd
=
pnew_sd
;
obj
->
sd
=
pnew_sd
;
}
}
int
check_object_access
(
struct
object
*
obj
,
unsigned
int
*
access
)
{
GENERIC_MAPPING
mapping
;
struct
token
*
token
=
current
->
token
?
current
->
token
:
current
->
process
->
token
;
LUID_AND_ATTRIBUTES
priv
;
unsigned
int
status
,
priv_count
=
1
;
int
res
;
mapping
.
GenericAll
=
obj
->
ops
->
map_access
(
obj
,
GENERIC_ALL
);
if
(
!
obj
->
sd
)
{
if
(
*
access
&
MAXIMUM_ALLOWED
)
*
access
=
mapping
.
GenericAll
;
return
TRUE
;
}
mapping
.
GenericRead
=
obj
->
ops
->
map_access
(
obj
,
GENERIC_READ
);
mapping
.
GenericWrite
=
obj
->
ops
->
map_access
(
obj
,
GENERIC_WRITE
);
mapping
.
GenericExecute
=
obj
->
ops
->
map_access
(
obj
,
GENERIC_EXECUTE
);
res
=
token_access_check
(
token
,
obj
->
sd
,
*
access
,
&
priv
,
&
priv_count
,
&
mapping
,
access
,
&
status
)
==
STATUS_SUCCESS
&&
status
==
STATUS_SUCCESS
;
if
(
!
res
)
set_error
(
STATUS_ACCESS_DENIED
);
return
res
;
}
/* open a security token */
/* open a security token */
DECL_HANDLER
(
open_token
)
DECL_HANDLER
(
open_token
)
{
{
...
...
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