Bug 24857

Summary: File descriptor leak and frequent crashes of rpc.rstatd [PATCH]
Product: Base System Reporter: Martin Butkus <mb>
Component: binAssignee: freebsd-bugs (Nobody) <bugs>
Status: Closed FIXED    
Severity: Affects Only Me    
Priority: Normal    
Version: 4.2-STABLE   
Hardware: Any   
OS: Any   
Attachments:
Description Flags
file.diff none

Description Martin Butkus 2001-02-05 00:00:01 UTC
I run rpc.rstatd on several FreeBSD boxes. A monitoring
process polls every machine every five minutes.  Running 
rstatd from inetd gave me bogus results (network activity was 
reported way too high, etc.) so I resorted to running rstatd 
standalone. 

However, when run standalone, it crashed frequently, and I also 
discovered a file descriptor leak.

I have observed that:

1) rpc.rstatd opens /dev/mem and /dev/kmem multiple times 
   until running out of file descriptors.
2) rpc.rstatd often crashes within 24 hours 

I have found and fixed the file descriptor leak but the crashes 
continued. I have then backtraced a core dump and found that 
updatestat() had been called from within itself. 

I figured there was a timing problem, i.e. updatestat() was 
running while there was still an alarm pending.
Since updatestat() is the signal handler for SIGALRM, this 
triggered the recursive call of updatestat().

I have therefore added an "alarm(0)" call at the beginning of 
updatestat() in order to clear any pending alarms. 
With these two modification, rpc.rstatd has been running 
on all my machines flawlessly and continuously for more than 
a week now.

Fix: This patch (against rstat_proc.c ver 1.14) has made rstatd run stable 
for me:
How-To-Repeat: 	
This is difficult because on my network, rstatd is polled
frequently (every 5 minutes) by a monitoring program.  I don't know
if this triggers the bug(s). It could well be possible.  

The following actions have triggered the bug at my site:

	ad 1) run rpc.rstatd standalone
	   # /usr/libexec/rpc.rstatd
	   
	   wait long enough :(. For me, an rstatd crashed after 
 	   about 24 hours.

	
	ad 2) run rpc.rstatd standalone

	   # /usr/libexec/rpc.rstatd

	   Wait a few minutes, then do an 
	
	   # fstat

	   and see rstatd having opened /dev/mem several times.

	   Wait a few hours more and watch the file descriptor 
	   table run full :(.
Comment 1 Jonathan Chen freebsd_committer freebsd_triage 2001-08-03 01:20:40 UTC
> However, when run standalone, it crashed frequently, and I also
> discovered a file descriptor leak.
> 
> I have observed that:
> 
> 1) rpc.rstatd opens /dev/mem and /dev/kmem multiple times
>    until running out of file descriptors.
> 2) rpc.rstatd often crashes within 24 hours

The following patch is what I've applied to -CURRENT.  It simplifies what 
you have to fix (1) and more correctly fixes (2) (your code still allows a 
small window where the problem can still occur).  Please test it out.
To crash rpc.rstatd, I used something similar to the following:
rup localhost & ; rup localhost & ;rup localhost & ;rup localhost & ;[repeat]

Index: rstat_proc.c
===================================================================
RCS file: /export/ncvs/src/libexec/rpc.rstatd/rstat_proc.c,v
retrieving revision 1.14
diff -u -r1.14 rstat_proc.c
--- rstat_proc.c	1999/08/28 00:09:54	1.14
+++ rstat_proc.c	2001/08/03 00:12:15
@@ -115,6 +115,7 @@
 {
     stat_is_init = 1;
     setup();
+    alarm(0);
     updatestat();
     (void) signal(SIGALRM, updatestat);
     alarm(1);
@@ -203,6 +204,7 @@
 #ifdef DEBUG
                 fprintf(stderr, "about to closedown\n");
 #endif
+		kvm_close(kd);
                 if (from_inetd)
                         exit(0);
                 else {
Comment 2 Jonathan Chen freebsd_committer freebsd_triage 2001-08-03 01:24:12 UTC
State Changed
From-To: open->closed

Fixed in libexec/rpc.rstatd 1.15, MFC after 4.4