vdr-1.3.27 still gives me SIGINTs

Message ID 20050705062031.6BAD284C45@nathan.muc.de
State New
Headers

Commit Message

Harald Milz July 5, 2005, 6:20 a.m. UTC
  Hi,

my living room vdr still gives me the goose bumps as far as SIGINTs from an
unknown source (I posted that before... no clue who is the bad guy). 

Anyway, this patch keeps vdr from accepting SIGINTs from UID != 0. Ctrl-C
as root still works. (And BTW signal() is deprecated, and the man page says
about signal(2)

       Trying to change the semantics of this call using defines and includes
       is  not  a  good idea. It is better to avoid signal altogether, and use
       sigaction(2) instead.


NOTES
       The effects of this call in a multi-threaded process are unspecified.
  

Patch

--- vdr-1.3.27/vdr.c	2005-06-18 13:19:07.000000000 +0200
+++ vdr-1.3.27-sigint/vdr.c	2005-07-03 23:32:20.709975045 +0200
@@ -67,17 +67,28 @@ 
 #define EXIT(v) { ExitCode = (v); goto Exit; }
 
 static int Interrupted = 0;
+static pid_t Int_From = 0;
 
-static void SignalHandler(int signum)
+static void SignalHandler(int signum, siginfo_t *si, void *uc)
 {
-  if (signum != SIGPIPE) {
+  struct sigaction sa;
+  Int_From = si->si_pid;
+  // accept Ctrl-C only from a controlling terminal or shell
+  if (signum == SIGINT) {
+     if (Int_From == 0) {
+        Interrupted = signum;
+        Interface->Interrupt();
+     }
+  } else if (signum != SIGPIPE) {
      Interrupted = signum;
      Interface->Interrupt();
-     }
-  signal(signum, SignalHandler);
+  }
+  sa.sa_flags = SA_SIGINFO;
+  sa.sa_sigaction = SignalHandler;
+  sigaction(signum, &sa, NULL);
 }
 
-static void Watchdog(int signum)
+static void Watchdog(int signum, siginfo_t *si, void *uc)
 {
   // Something terrible must have happened that prevented the 'alarm()' from
   // being called in time, so let's get out of here:
@@ -88,7 +99,7 @@ 
 int main(int argc, char *argv[])
 {
   // Save terminal settings:
-
+  struct sigaction sa, oldsigact;
   struct termios savedTm;
   bool HasStdin = (tcgetpgrp(STDIN_FILENO) == getpid() || getppid() != (pid_t)1) && tcgetattr(STDIN_FILENO, &savedTm) == 0;
 
@@ -500,12 +511,65 @@ 
 
   // Signal handlers:
 
+/*
   if (signal(SIGHUP,  SignalHandler) == SIG_IGN) signal(SIGHUP,  SIG_IGN);
+*/
+  sa.sa_sigaction = SignalHandler;
+  sa.sa_flags = SA_SIGINFO;
+  sigaction (SIGHUP, &sa, &oldsigact);
+  if (oldsigact.sa_handler == SIG_IGN) {
+    sa.sa_handler = SIG_IGN;
+    sa.sa_flags = 0;
+    sigaction (SIGHUP, &sa, NULL);
+  }
+/*
   if (signal(SIGINT,  SignalHandler) == SIG_IGN) signal(SIGINT,  SIG_IGN);
+*/
+  sa.sa_sigaction = SignalHandler;
+  sa.sa_flags = SA_SIGINFO;
+  sigaction (SIGINT, &sa, &oldsigact);
+  if (oldsigact.sa_handler == SIG_IGN) {
+    sa.sa_handler = SIG_IGN;
+    sa.sa_flags = 0;
+    sigaction (SIGINT, &sa, NULL);
+  }
+/*
   if (signal(SIGTERM, SignalHandler) == SIG_IGN) signal(SIGTERM, SIG_IGN);
+*/
+  sa.sa_sigaction = SignalHandler;
+  sa.sa_flags = SA_SIGINFO;
+  sigaction (SIGTERM, &sa, &oldsigact);
+  if (oldsigact.sa_handler == SIG_IGN) {
+    sa.sa_handler = SIG_IGN;
+    sa.sa_flags = 0;
+    sigaction (SIGTERM, &sa, NULL);
+  }
+/*
   if (signal(SIGPIPE, SignalHandler) == SIG_IGN) signal(SIGPIPE, SIG_IGN);
+*/
+  sa.sa_sigaction = SignalHandler;
+  sa.sa_flags = SA_SIGINFO;
+  sigaction (SIGPIPE, &sa, &oldsigact);
+  if (oldsigact.sa_handler == SIG_IGN) {
+    sa.sa_handler = SIG_IGN;
+    sa.sa_flags = 0;
+    sigaction (SIGPIPE, &sa, NULL);
+  }
+
   if (WatchdogTimeout > 0)
+/*
      if (signal(SIGALRM, Watchdog)   == SIG_IGN) signal(SIGALRM, SIG_IGN);
+*/
+  {
+    sa.sa_sigaction = Watchdog;
+    sa.sa_flags = SA_SIGINFO;
+    sigaction (SIGALRM, &sa, &oldsigact);
+    if (oldsigact.sa_handler == SIG_IGN) {
+      sa.sa_handler = SIG_IGN;
+      sa.sa_flags = 0;
+      sigaction (SIGALRM, &sa, NULL);
+    }
+  }
 
   // Watchdog:
 
@@ -891,8 +955,11 @@ 
                     ForceShutdown = false;
                     if (timer)
                        dsyslog("next timer event at %s", *TimeToString(Next));
-                    if (WatchdogTimeout > 0)
-                       signal(SIGALRM, SIG_IGN);
+                    if (WatchdogTimeout > 0) {
+                       sa.sa_handler = SIG_IGN;
+                       sa.sa_flags = 0;
+                       sigaction(SIGALRM, &sa, NULL);
+                    }
                     if (Interface->Confirm(tr("Press any key to cancel shutdown"), UserShutdown ? 5 : SHUTDOWNWAIT, true)) {
                        cControl::Shutdown();
                        int Channel = timer ? timer->Channel()->Number() : 0;
@@ -906,9 +973,19 @@ 
                        }
                     else if (WatchdogTimeout > 0) {
                        alarm(WatchdogTimeout);
+/*
                        if (signal(SIGALRM, Watchdog) == SIG_IGN)
                           signal(SIGALRM, SIG_IGN);
+*/
+                       sa.sa_sigaction = Watchdog;
+                       sa.sa_flags = SA_SIGINFO;
+                       sigaction (SIGALRM, &sa, &oldsigact);
+                       if (oldsigact.sa_handler == SIG_IGN) {
+                         sa.sa_handler = SIG_IGN;
+                         sa.sa_flags = 0;
+                         sigaction (SIGALRM, &sa, NULL);
                        }
+	            }
                     LastActivity = time(NULL); // don't try again too soon
                     UserShutdown = false;
                     continue; // skip the rest of the housekeeping for now
@@ -923,7 +1000,7 @@ 
            }
         }
   if (Interrupted)
-     isyslog("caught signal %d", Interrupted);
+       isyslog("caught signal %d from %d", Interrupted, Int_From);
 
 Exit: