Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
62d3ffc4
Commit
62d3ffc4
authored
Feb 07, 2004
by
Trond Myklebust
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
RPCSEC_GSS: Make the upcalls detect if the userland daemon
dies while processing a request.
parent
6fb5d9bf
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
78 additions
and
21 deletions
+78
-21
include/linux/sunrpc/rpc_pipe_fs.h
include/linux/sunrpc/rpc_pipe_fs.h
+3
-1
net/sunrpc/auth_gss/auth_gss.c
net/sunrpc/auth_gss/auth_gss.c
+28
-0
net/sunrpc/rpc_pipe.c
net/sunrpc/rpc_pipe.c
+47
-20
No files found.
include/linux/sunrpc/rpc_pipe_fs.h
View file @
62d3ffc4
...
@@ -14,6 +14,7 @@ struct rpc_pipe_msg {
...
@@ -14,6 +14,7 @@ struct rpc_pipe_msg {
struct
rpc_pipe_ops
{
struct
rpc_pipe_ops
{
ssize_t
(
*
upcall
)(
struct
file
*
,
struct
rpc_pipe_msg
*
,
char
__user
*
,
size_t
);
ssize_t
(
*
upcall
)(
struct
file
*
,
struct
rpc_pipe_msg
*
,
char
__user
*
,
size_t
);
ssize_t
(
*
downcall
)(
struct
file
*
,
const
char
__user
*
,
size_t
);
ssize_t
(
*
downcall
)(
struct
file
*
,
const
char
__user
*
,
size_t
);
void
(
*
release_pipe
)(
struct
inode
*
);
void
(
*
destroy_msg
)(
struct
rpc_pipe_msg
*
);
void
(
*
destroy_msg
)(
struct
rpc_pipe_msg
*
);
};
};
...
@@ -21,8 +22,10 @@ struct rpc_inode {
...
@@ -21,8 +22,10 @@ struct rpc_inode {
struct
inode
vfs_inode
;
struct
inode
vfs_inode
;
void
*
private
;
void
*
private
;
struct
list_head
pipe
;
struct
list_head
pipe
;
struct
list_head
in_upcall
;
int
pipelen
;
int
pipelen
;
int
nreaders
;
int
nreaders
;
int
nwriters
;
wait_queue_head_t
waitq
;
wait_queue_head_t
waitq
;
#define RPC_PIPE_WAIT_FOR_OPEN 1
#define RPC_PIPE_WAIT_FOR_OPEN 1
int
flags
;
int
flags
;
...
@@ -36,7 +39,6 @@ RPC_I(struct inode *inode)
...
@@ -36,7 +39,6 @@ RPC_I(struct inode *inode)
return
container_of
(
inode
,
struct
rpc_inode
,
vfs_inode
);
return
container_of
(
inode
,
struct
rpc_inode
,
vfs_inode
);
}
}
extern
void
rpc_inode_setowner
(
struct
inode
*
,
void
*
);
extern
int
rpc_queue_upcall
(
struct
inode
*
,
struct
rpc_pipe_msg
*
);
extern
int
rpc_queue_upcall
(
struct
inode
*
,
struct
rpc_pipe_msg
*
);
extern
struct
dentry
*
rpc_mkdir
(
char
*
,
struct
rpc_clnt
*
);
extern
struct
dentry
*
rpc_mkdir
(
char
*
,
struct
rpc_clnt
*
);
...
...
net/sunrpc/auth_gss/auth_gss.c
View file @
62d3ffc4
...
@@ -482,6 +482,33 @@ gss_pipe_downcall(struct file *filp, const char *src, size_t mlen)
...
@@ -482,6 +482,33 @@ gss_pipe_downcall(struct file *filp, const char *src, size_t mlen)
return
err
;
return
err
;
}
}
static
void
gss_pipe_release
(
struct
inode
*
inode
)
{
struct
rpc_inode
*
rpci
=
RPC_I
(
inode
);
struct
rpc_clnt
*
clnt
;
struct
rpc_auth
*
auth
;
struct
gss_auth
*
gss_auth
;
clnt
=
rpci
->
private
;
auth
=
clnt
->
cl_auth
;
gss_auth
=
container_of
(
auth
,
struct
gss_auth
,
rpc_auth
);
spin_lock
(
&
gss_auth
->
lock
);
while
(
!
list_empty
(
&
gss_auth
->
upcalls
))
{
struct
gss_upcall_msg
*
gss_msg
;
gss_msg
=
list_entry
(
gss_auth
->
upcalls
.
next
,
struct
gss_upcall_msg
,
list
);
gss_msg
->
msg
.
errno
=
-
EPIPE
;
atomic_inc
(
&
gss_msg
->
count
);
__gss_unhash_msg
(
gss_msg
);
spin_unlock
(
&
gss_auth
->
lock
);
gss_release_msg
(
gss_msg
);
spin_lock
(
&
gss_auth
->
lock
);
}
spin_unlock
(
&
gss_auth
->
lock
);
}
void
void
gss_pipe_destroy_msg
(
struct
rpc_pipe_msg
*
msg
)
gss_pipe_destroy_msg
(
struct
rpc_pipe_msg
*
msg
)
{
{
...
@@ -774,6 +801,7 @@ static struct rpc_pipe_ops gss_upcall_ops = {
...
@@ -774,6 +801,7 @@ static struct rpc_pipe_ops gss_upcall_ops = {
.
upcall
=
gss_pipe_upcall
,
.
upcall
=
gss_pipe_upcall
,
.
downcall
=
gss_pipe_downcall
,
.
downcall
=
gss_pipe_downcall
,
.
destroy_msg
=
gss_pipe_destroy_msg
,
.
destroy_msg
=
gss_pipe_destroy_msg
,
.
release_pipe
=
gss_pipe_release
,
};
};
/*
/*
...
...
net/sunrpc/rpc_pipe.c
View file @
62d3ffc4
...
@@ -50,18 +50,16 @@ __rpc_purge_upcall(struct inode *inode, int err)
...
@@ -50,18 +50,16 @@ __rpc_purge_upcall(struct inode *inode, int err)
msg
->
errno
=
err
;
msg
->
errno
=
err
;
rpci
->
ops
->
destroy_msg
(
msg
);
rpci
->
ops
->
destroy_msg
(
msg
);
}
}
while
(
!
list_empty
(
&
rpci
->
in_upcall
))
{
msg
=
list_entry
(
rpci
->
pipe
.
next
,
struct
rpc_pipe_msg
,
list
);
list_del_init
(
&
msg
->
list
);
msg
->
errno
=
err
;
rpci
->
ops
->
destroy_msg
(
msg
);
}
rpci
->
pipelen
=
0
;
rpci
->
pipelen
=
0
;
wake_up
(
&
rpci
->
waitq
);
wake_up
(
&
rpci
->
waitq
);
}
}
void
rpc_purge_upcall
(
struct
inode
*
inode
,
int
err
)
{
down
(
&
inode
->
i_sem
);
__rpc_purge_upcall
(
inode
,
err
);
up
(
&
inode
->
i_sem
);
}
static
void
static
void
rpc_timeout_upcall_queue
(
void
*
data
)
rpc_timeout_upcall_queue
(
void
*
data
)
{
{
...
@@ -97,20 +95,31 @@ rpc_queue_upcall(struct inode *inode, struct rpc_pipe_msg *msg)
...
@@ -97,20 +95,31 @@ rpc_queue_upcall(struct inode *inode, struct rpc_pipe_msg *msg)
return
res
;
return
res
;
}
}
void
static
void
rpc_
inode_setowner
(
struct
inode
*
inode
,
void
*
privat
e
)
rpc_
close_pipes
(
struct
inode
*
inod
e
)
{
{
struct
rpc_inode
*
rpci
=
RPC_I
(
inode
);
struct
rpc_inode
*
rpci
=
RPC_I
(
inode
);
cancel_delayed_work
(
&
rpci
->
queue_timeout
);
cancel_delayed_work
(
&
rpci
->
queue_timeout
);
flush_scheduled_work
();
flush_scheduled_work
();
down
(
&
inode
->
i_sem
);
down
(
&
inode
->
i_sem
);
rpci
->
private
=
private
;
if
(
rpci
->
ops
!=
NULL
)
{
if
(
!
private
)
rpci
->
nreaders
=
0
;
__rpc_purge_upcall
(
inode
,
-
EPIPE
);
__rpc_purge_upcall
(
inode
,
-
EPIPE
);
rpci
->
nwriters
=
0
;
if
(
rpci
->
ops
->
release_pipe
)
rpci
->
ops
->
release_pipe
(
inode
);
rpci
->
ops
=
NULL
;
}
up
(
&
inode
->
i_sem
);
up
(
&
inode
->
i_sem
);
}
}
static
inline
void
rpc_inode_setowner
(
struct
inode
*
inode
,
void
*
private
)
{
RPC_I
(
inode
)
->
private
=
private
;
}
static
struct
inode
*
static
struct
inode
*
rpc_alloc_inode
(
struct
super_block
*
sb
)
rpc_alloc_inode
(
struct
super_block
*
sb
)
{
{
...
@@ -134,9 +143,11 @@ rpc_pipe_open(struct inode *inode, struct file *filp)
...
@@ -134,9 +143,11 @@ rpc_pipe_open(struct inode *inode, struct file *filp)
int
res
=
-
ENXIO
;
int
res
=
-
ENXIO
;
down
(
&
inode
->
i_sem
);
down
(
&
inode
->
i_sem
);
if
(
rpci
->
private
!=
NULL
)
{
if
(
rpci
->
ops
!=
NULL
)
{
if
(
filp
->
f_mode
&
FMODE_READ
)
if
(
filp
->
f_mode
&
FMODE_READ
)
rpci
->
nreaders
++
;
rpci
->
nreaders
++
;
if
(
filp
->
f_mode
&
FMODE_WRITE
)
rpci
->
nwriters
++
;
res
=
0
;
res
=
0
;
}
}
up
(
&
inode
->
i_sem
);
up
(
&
inode
->
i_sem
);
...
@@ -149,16 +160,24 @@ rpc_pipe_release(struct inode *inode, struct file *filp)
...
@@ -149,16 +160,24 @@ rpc_pipe_release(struct inode *inode, struct file *filp)
struct
rpc_inode
*
rpci
=
RPC_I
(
filp
->
f_dentry
->
d_inode
);
struct
rpc_inode
*
rpci
=
RPC_I
(
filp
->
f_dentry
->
d_inode
);
struct
rpc_pipe_msg
*
msg
;
struct
rpc_pipe_msg
*
msg
;
down
(
&
inode
->
i_sem
);
if
(
rpci
->
ops
==
NULL
)
goto
out
;
msg
=
(
struct
rpc_pipe_msg
*
)
filp
->
private_data
;
msg
=
(
struct
rpc_pipe_msg
*
)
filp
->
private_data
;
if
(
msg
!=
NULL
)
{
if
(
msg
!=
NULL
)
{
msg
->
errno
=
-
EPIPE
;
msg
->
errno
=
-
EPIPE
;
list_del_init
(
&
msg
->
list
);
rpci
->
ops
->
destroy_msg
(
msg
);
rpci
->
ops
->
destroy_msg
(
msg
);
}
}
down
(
&
inode
->
i_sem
);
if
(
filp
->
f_mode
&
FMODE_WRITE
)
rpci
->
nwriters
--
;
if
(
filp
->
f_mode
&
FMODE_READ
)
if
(
filp
->
f_mode
&
FMODE_READ
)
rpci
->
nreaders
--
;
rpci
->
nreaders
--
;
if
(
!
rpci
->
nreaders
)
if
(
!
rpci
->
nreaders
)
__rpc_purge_upcall
(
inode
,
-
EPIPE
);
__rpc_purge_upcall
(
inode
,
-
EPIPE
);
if
(
rpci
->
ops
->
release_pipe
)
rpci
->
ops
->
release_pipe
(
inode
);
out:
up
(
&
inode
->
i_sem
);
up
(
&
inode
->
i_sem
);
return
0
;
return
0
;
}
}
...
@@ -172,7 +191,7 @@ rpc_pipe_read(struct file *filp, char __user *buf, size_t len, loff_t *offset)
...
@@ -172,7 +191,7 @@ rpc_pipe_read(struct file *filp, char __user *buf, size_t len, loff_t *offset)
int
res
=
0
;
int
res
=
0
;
down
(
&
inode
->
i_sem
);
down
(
&
inode
->
i_sem
);
if
(
!
rpci
->
private
)
{
if
(
rpci
->
ops
==
NULL
)
{
res
=
-
EPIPE
;
res
=
-
EPIPE
;
goto
out_unlock
;
goto
out_unlock
;
}
}
...
@@ -182,7 +201,7 @@ rpc_pipe_read(struct file *filp, char __user *buf, size_t len, loff_t *offset)
...
@@ -182,7 +201,7 @@ rpc_pipe_read(struct file *filp, char __user *buf, size_t len, loff_t *offset)
msg
=
list_entry
(
rpci
->
pipe
.
next
,
msg
=
list_entry
(
rpci
->
pipe
.
next
,
struct
rpc_pipe_msg
,
struct
rpc_pipe_msg
,
list
);
list
);
list_
del_init
(
&
msg
->
list
);
list_
move
(
&
msg
->
list
,
&
rpci
->
in_upcall
);
rpci
->
pipelen
-=
msg
->
len
;
rpci
->
pipelen
-=
msg
->
len
;
filp
->
private_data
=
msg
;
filp
->
private_data
=
msg
;
msg
->
copied
=
0
;
msg
->
copied
=
0
;
...
@@ -194,6 +213,7 @@ rpc_pipe_read(struct file *filp, char __user *buf, size_t len, loff_t *offset)
...
@@ -194,6 +213,7 @@ rpc_pipe_read(struct file *filp, char __user *buf, size_t len, loff_t *offset)
res
=
rpci
->
ops
->
upcall
(
filp
,
msg
,
buf
,
len
);
res
=
rpci
->
ops
->
upcall
(
filp
,
msg
,
buf
,
len
);
if
(
res
<
0
||
msg
->
len
==
msg
->
copied
)
{
if
(
res
<
0
||
msg
->
len
==
msg
->
copied
)
{
filp
->
private_data
=
NULL
;
filp
->
private_data
=
NULL
;
list_del_init
(
&
msg
->
list
);
rpci
->
ops
->
destroy_msg
(
msg
);
rpci
->
ops
->
destroy_msg
(
msg
);
}
}
out_unlock:
out_unlock:
...
@@ -210,7 +230,7 @@ rpc_pipe_write(struct file *filp, const char __user *buf, size_t len, loff_t *of
...
@@ -210,7 +230,7 @@ rpc_pipe_write(struct file *filp, const char __user *buf, size_t len, loff_t *of
down
(
&
inode
->
i_sem
);
down
(
&
inode
->
i_sem
);
res
=
-
EPIPE
;
res
=
-
EPIPE
;
if
(
rpci
->
private
!=
NULL
)
if
(
rpci
->
ops
!=
NULL
)
res
=
rpci
->
ops
->
downcall
(
filp
,
buf
,
len
);
res
=
rpci
->
ops
->
downcall
(
filp
,
buf
,
len
);
up
(
&
inode
->
i_sem
);
up
(
&
inode
->
i_sem
);
return
res
;
return
res
;
...
@@ -226,7 +246,7 @@ rpc_pipe_poll(struct file *filp, struct poll_table_struct *wait)
...
@@ -226,7 +246,7 @@ rpc_pipe_poll(struct file *filp, struct poll_table_struct *wait)
poll_wait
(
filp
,
&
rpci
->
waitq
,
wait
);
poll_wait
(
filp
,
&
rpci
->
waitq
,
wait
);
mask
=
POLLOUT
|
POLLWRNORM
;
mask
=
POLLOUT
|
POLLWRNORM
;
if
(
rpci
->
private
==
NULL
)
if
(
rpci
->
ops
==
NULL
)
mask
|=
POLLERR
|
POLLHUP
;
mask
|=
POLLERR
|
POLLHUP
;
if
(
!
list_empty
(
&
rpci
->
pipe
))
if
(
!
list_empty
(
&
rpci
->
pipe
))
mask
|=
POLLIN
|
POLLRDNORM
;
mask
|=
POLLIN
|
POLLRDNORM
;
...
@@ -242,7 +262,7 @@ rpc_pipe_ioctl(struct inode *ino, struct file *filp,
...
@@ -242,7 +262,7 @@ rpc_pipe_ioctl(struct inode *ino, struct file *filp,
switch
(
cmd
)
{
switch
(
cmd
)
{
case
FIONREAD
:
case
FIONREAD
:
if
(
!
rpci
->
private
)
if
(
rpci
->
ops
==
NULL
)
return
-
EPIPE
;
return
-
EPIPE
;
len
=
rpci
->
pipelen
;
len
=
rpci
->
pipelen
;
if
(
filp
->
private_data
)
{
if
(
filp
->
private_data
)
{
...
@@ -484,6 +504,7 @@ rpc_depopulate(struct dentry *parent)
...
@@ -484,6 +504,7 @@ rpc_depopulate(struct dentry *parent)
do
{
do
{
dentry
=
dvec
[
--
n
];
dentry
=
dvec
[
--
n
];
if
(
dentry
->
d_inode
)
{
if
(
dentry
->
d_inode
)
{
rpc_close_pipes
(
dentry
->
d_inode
);
rpc_inode_setowner
(
dentry
->
d_inode
,
NULL
);
rpc_inode_setowner
(
dentry
->
d_inode
,
NULL
);
simple_unlink
(
dir
,
dentry
);
simple_unlink
(
dir
,
dentry
);
}
}
...
@@ -563,7 +584,10 @@ __rpc_rmdir(struct inode *dir, struct dentry *dentry)
...
@@ -563,7 +584,10 @@ __rpc_rmdir(struct inode *dir, struct dentry *dentry)
int
error
;
int
error
;
shrink_dcache_parent
(
dentry
);
shrink_dcache_parent
(
dentry
);
rpc_inode_setowner
(
dentry
->
d_inode
,
NULL
);
if
(
dentry
->
d_inode
)
{
rpc_close_pipes
(
dentry
->
d_inode
);
rpc_inode_setowner
(
dentry
->
d_inode
,
NULL
);
}
if
((
error
=
simple_rmdir
(
dir
,
dentry
))
!=
0
)
if
((
error
=
simple_rmdir
(
dir
,
dentry
))
!=
0
)
return
error
;
return
error
;
if
(
!
error
)
{
if
(
!
error
)
{
...
@@ -715,6 +739,7 @@ rpc_unlink(char *path)
...
@@ -715,6 +739,7 @@ rpc_unlink(char *path)
}
}
d_drop
(
dentry
);
d_drop
(
dentry
);
if
(
dentry
->
d_inode
)
{
if
(
dentry
->
d_inode
)
{
rpc_close_pipes
(
dentry
->
d_inode
);
rpc_inode_setowner
(
dentry
->
d_inode
,
NULL
);
rpc_inode_setowner
(
dentry
->
d_inode
,
NULL
);
error
=
simple_unlink
(
dir
,
dentry
);
error
=
simple_unlink
(
dir
,
dentry
);
}
}
...
@@ -790,6 +815,8 @@ init_once(void * foo, kmem_cache_t * cachep, unsigned long flags)
...
@@ -790,6 +815,8 @@ init_once(void * foo, kmem_cache_t * cachep, unsigned long flags)
inode_init_once
(
&
rpci
->
vfs_inode
);
inode_init_once
(
&
rpci
->
vfs_inode
);
rpci
->
private
=
NULL
;
rpci
->
private
=
NULL
;
rpci
->
nreaders
=
0
;
rpci
->
nreaders
=
0
;
rpci
->
nwriters
=
0
;
INIT_LIST_HEAD
(
&
rpci
->
in_upcall
);
INIT_LIST_HEAD
(
&
rpci
->
pipe
);
INIT_LIST_HEAD
(
&
rpci
->
pipe
);
rpci
->
pipelen
=
0
;
rpci
->
pipelen
=
0
;
init_waitqueue_head
(
&
rpci
->
waitq
);
init_waitqueue_head
(
&
rpci
->
waitq
);
...
...
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