From 572efae32f6fb311dff0e065d0d1dd527db60d0c Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Fri, 26 Sep 2008 16:16:09 -0400 Subject: rpc.statd: Stop overloading sockfd in utils/statd/rmtcall.c The Linux kernel's lockd requires that rpc.statd perform notification callbacks from a privileged source port. To guarantee rpc.statd gets a privileged source port but runs unprivileged, it calls statd_get_socket() then drops root privileges before starting it's svc request processing loop. Statd's svc request loop is the only caller of the process_foo() functions in utils/statd/rmtcall.c, but one of them, process_notify_list() attempts to invoke statd_get_socket() again. In today's code, this is unneeded because statd_get_socket() is always invoked before my_svc_run(). However, if it ever succeeded, it would get an unprivileged source port anyway, causing the kernel to reject all subsequent requests from statd. Thus the process_notify_list() function should not ever call statd_get_socket() because root privileges have been dropped by this point, and statd_get_socket() wouldn't get a privileged source port, causing the kernel to reject all subsequent SM_NOTIFY requests. So all of the process_foo functions in utils/statd/rmtcall.c should use the global sockfd instead of a local copy, as it already has a privileged source port. I've seen some unexplained behavior where statd starts making calls to the kernel via an unprivileged port. This could be one way that might occur. Signed-off-by: Chuck Lever Signed-off-by: Steve Dickson --- utils/statd/statd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'utils/statd/statd.c') diff --git a/utils/statd/statd.c b/utils/statd/statd.c index ea985e6..321f7a9 100644 --- a/utils/statd/statd.c +++ b/utils/statd/statd.c @@ -75,7 +75,6 @@ static struct option longopts[] = }; extern void sm_prog_1 (struct svc_req *, register SVCXPRT *); -extern int statd_get_socket(void); static void load_state_number(void); #ifdef SIMULATIONS @@ -477,7 +476,8 @@ int main (int argc, char **argv) } /* Make sure we have a privilege port for calling into the kernel */ - statd_get_socket(); + if (statd_get_socket() < 0) + exit(1); /* If sm-notify didn't take all the state files, load * state information into our notify-list so we can -- cgit