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
35431ed0
Commit
35431ed0
authored
Apr 18, 2011
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
server: Check sharing options when duplicating an fd object.
parent
94fbcd7c
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
48 additions
and
44 deletions
+48
-44
fd.c
server/fd.c
+48
-44
No files found.
server/fd.c
View file @
35431ed0
...
...
@@ -1471,6 +1471,48 @@ static void fd_destroy( struct object *obj )
}
}
/* check if the desired access is possible without violating */
/* the sharing mode of other opens of the same file */
static
unsigned
int
check_sharing
(
struct
fd
*
fd
,
unsigned
int
access
,
unsigned
int
sharing
,
unsigned
int
open_flags
,
unsigned
int
options
)
{
unsigned
int
existing_sharing
=
FILE_SHARE_READ
|
FILE_SHARE_WRITE
|
FILE_SHARE_DELETE
;
unsigned
int
existing_access
=
0
;
struct
list
*
ptr
;
fd
->
access
=
access
;
fd
->
sharing
=
sharing
;
LIST_FOR_EACH
(
ptr
,
&
fd
->
inode
->
open
)
{
struct
fd
*
fd_ptr
=
LIST_ENTRY
(
ptr
,
struct
fd
,
inode_entry
);
if
(
fd_ptr
!=
fd
)
{
/* if access mode is 0, sharing mode is ignored */
if
(
fd_ptr
->
access
)
existing_sharing
&=
fd_ptr
->
sharing
;
existing_access
|=
fd_ptr
->
access
;
}
}
if
(((
access
&
FILE_UNIX_READ_ACCESS
)
&&
!
(
existing_sharing
&
FILE_SHARE_READ
))
||
((
access
&
FILE_UNIX_WRITE_ACCESS
)
&&
!
(
existing_sharing
&
FILE_SHARE_WRITE
))
||
((
access
&
DELETE
)
&&
!
(
existing_sharing
&
FILE_SHARE_DELETE
)))
return
STATUS_SHARING_VIOLATION
;
if
(((
existing_access
&
FILE_MAPPING_WRITE
)
&&
!
(
sharing
&
FILE_SHARE_WRITE
))
||
((
existing_access
&
FILE_MAPPING_IMAGE
)
&&
(
access
&
FILE_UNIX_WRITE_ACCESS
)))
return
STATUS_SHARING_VIOLATION
;
if
((
existing_access
&
FILE_MAPPING_IMAGE
)
&&
(
options
&
FILE_DELETE_ON_CLOSE
))
return
STATUS_CANNOT_DELETE
;
if
((
existing_access
&
FILE_MAPPING_ACCESS
)
&&
(
open_flags
&
O_TRUNC
))
return
STATUS_USER_MAPPED_FILE
;
if
(
!
access
)
return
0
;
/* if access mode is 0, sharing mode is ignored (except for mappings) */
if
(((
existing_access
&
FILE_UNIX_READ_ACCESS
)
&&
!
(
sharing
&
FILE_SHARE_READ
))
||
((
existing_access
&
FILE_UNIX_WRITE_ACCESS
)
&&
!
(
sharing
&
FILE_SHARE_WRITE
))
||
((
existing_access
&
DELETE
)
&&
!
(
sharing
&
FILE_SHARE_DELETE
)))
return
STATUS_SHARING_VIOLATION
;
return
0
;
}
/* set the events that select waits for on this fd */
void
set_fd_events
(
struct
fd
*
fd
,
int
events
)
{
...
...
@@ -1581,13 +1623,12 @@ struct fd *alloc_pseudo_fd( const struct fd_ops *fd_user_ops, struct object *use
/* duplicate an fd object for a different user */
struct
fd
*
dup_fd_object
(
struct
fd
*
orig
,
unsigned
int
access
,
unsigned
int
sharing
,
unsigned
int
options
)
{
unsigned
int
err
;
struct
fd
*
fd
=
alloc_fd_object
();
if
(
!
fd
)
return
NULL
;
fd
->
access
=
access
;
fd
->
options
=
options
;
fd
->
sharing
=
sharing
;
fd
->
cacheable
=
orig
->
cacheable
;
if
(
orig
->
unix_name
)
...
...
@@ -1611,6 +1652,11 @@ struct fd *dup_fd_object( struct fd *orig, unsigned int access, unsigned int sha
fd
->
closed
=
closed
;
fd
->
inode
=
(
struct
inode
*
)
grab_object
(
orig
->
inode
);
list_add_head
(
&
fd
->
inode
->
open
,
&
fd
->
inode_entry
);
if
((
err
=
check_sharing
(
fd
,
access
,
sharing
,
0
,
options
)))
{
set_error
(
err
);
goto
failed
;
}
}
else
if
((
fd
->
unix_fd
=
dup
(
orig
->
unix_fd
))
==
-
1
)
{
...
...
@@ -1630,48 +1676,6 @@ void set_no_fd_status( struct fd *fd, unsigned int status )
fd
->
no_fd_status
=
status
;
}
/* check if the desired access is possible without violating */
/* the sharing mode of other opens of the same file */
static
unsigned
int
check_sharing
(
struct
fd
*
fd
,
unsigned
int
access
,
unsigned
int
sharing
,
unsigned
int
open_flags
,
unsigned
int
options
)
{
unsigned
int
existing_sharing
=
FILE_SHARE_READ
|
FILE_SHARE_WRITE
|
FILE_SHARE_DELETE
;
unsigned
int
existing_access
=
0
;
struct
list
*
ptr
;
fd
->
access
=
access
;
fd
->
sharing
=
sharing
;
LIST_FOR_EACH
(
ptr
,
&
fd
->
inode
->
open
)
{
struct
fd
*
fd_ptr
=
LIST_ENTRY
(
ptr
,
struct
fd
,
inode_entry
);
if
(
fd_ptr
!=
fd
)
{
/* if access mode is 0, sharing mode is ignored */
if
(
fd_ptr
->
access
)
existing_sharing
&=
fd_ptr
->
sharing
;
existing_access
|=
fd_ptr
->
access
;
}
}
if
(((
access
&
FILE_UNIX_READ_ACCESS
)
&&
!
(
existing_sharing
&
FILE_SHARE_READ
))
||
((
access
&
FILE_UNIX_WRITE_ACCESS
)
&&
!
(
existing_sharing
&
FILE_SHARE_WRITE
))
||
((
access
&
DELETE
)
&&
!
(
existing_sharing
&
FILE_SHARE_DELETE
)))
return
STATUS_SHARING_VIOLATION
;
if
(((
existing_access
&
FILE_MAPPING_WRITE
)
&&
!
(
sharing
&
FILE_SHARE_WRITE
))
||
((
existing_access
&
FILE_MAPPING_IMAGE
)
&&
(
access
&
FILE_SHARE_WRITE
)))
return
STATUS_SHARING_VIOLATION
;
if
((
existing_access
&
FILE_MAPPING_IMAGE
)
&&
(
options
&
FILE_DELETE_ON_CLOSE
))
return
STATUS_CANNOT_DELETE
;
if
((
existing_access
&
FILE_MAPPING_ACCESS
)
&&
(
open_flags
&
O_TRUNC
))
return
STATUS_USER_MAPPED_FILE
;
if
(
!
access
)
return
0
;
/* if access mode is 0, sharing mode is ignored (except for mappings) */
if
(((
existing_access
&
FILE_UNIX_READ_ACCESS
)
&&
!
(
sharing
&
FILE_SHARE_READ
))
||
((
existing_access
&
FILE_UNIX_WRITE_ACCESS
)
&&
!
(
sharing
&
FILE_SHARE_WRITE
))
||
((
existing_access
&
DELETE
)
&&
!
(
sharing
&
FILE_SHARE_DELETE
)))
return
STATUS_SHARING_VIOLATION
;
return
0
;
}
/* sets the user of an fd that previously had no user */
void
set_fd_user
(
struct
fd
*
fd
,
const
struct
fd_ops
*
user_ops
,
struct
object
*
user
)
{
...
...
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