2.1.x 34c68ba8: freebsd 7.x: segfault/internal error in select()

Russell Jackson raj at csub.edu
Tue Jun 21 04:00:24 CEST 2011


On 06/20/2011 04:56 PM, Russell Jackson wrote:
> I'm getting a segfault on exit after logging this to syslog:
> 
> Exiting due to internal error: Failed in select: Invalid argument
> kernel: pid 87513 (radiusd), uid 133: exited on signal 11
> 
> select(2) indicates that EINVAL is returned when the timeout is invalid
> (being negative or too large). I modified the error message to include
> the value of "when" in lib/event.c. I then got:
> 
> Exiting due to internal error: Failed in select: Invalid argument: wake
> 4sec, 1000000usec
> 
> I suspected that tv_usec needs to be < USEC, so I kluged the code to
> subtract 1 from when.tv_usec if it's >= USEC. So far, I haven't had any
> more crashes.
> 

Here's said kludge.

diff --git a/src/lib/event.c b/src/lib/event.c
index ab937a5..a9c361b 100644
--- a/src/lib/event.c
+++ b/src/lib/event.c
@@ -374,6 +374,17 @@ int fr_event_loop(fr_event_list_t *el)
                                when.tv_sec = 0;
                                when.tv_usec = 0;
                        }
+
+                       /*
+                        * Make sure time interval is within bounds
+                        */
+                       if (when.tv_sec < 0) when.tv_sec = 0;
+
+                       if (when.tv_usec < 0) {
+                               when.tv_usec = 0;
+                       } else if (when.tv_usec >= USEC) {
+                               when.tv_usec = USEC - 1;
+                       }

                        wake = &when;
                } else {
@@ -388,8 +399,8 @@ int fr_event_loop(fr_event_list_t *el)
                read_fds = master_fds;
                rcode = select(maxfd + 1, &read_fds, NULL, NULL, wake);
                if ((rcode < 0) && (errno != EINTR)) {
-                       fr_strerror_printf("Failed in select: %s",
-                                          strerror(errno));
+                       fr_strerror_printf("Failed in select: %s: wake
%dsec, %dusec",
+                                          strerror(errno),
wake->tv_sec, wake->tv_usec);
                        el->dispatch = 0;
                        return -1;
                }

-- 
Russell A Jackson <raj at csub.edu>
Network Analyst
California State University, Bakersfield



More information about the Freeradius-Users mailing list