pppd: Handle SIGINT and SIGTERM during interrupted syscalls (#148)
authorpali <7141871+pali@users.noreply.github.com>
Mon, 25 May 2020 05:35:55 +0000 (07:35 +0200)
committerGitHub <noreply@github.com>
Mon, 25 May 2020 05:35:55 +0000 (15:35 +1000)
When pppd receives SIGINT or SIGTERM it should handle it and not try to
restart interrupted syscall.

This change fixes problem that pppd cannot be terminated by SIGINT or
SIGTERM signal when pppd plugins are used.

Signed-off-by: Pali Rohár <pali@kernel.org>
pppd/plugins/passprompt.c
pppd/plugins/radius/sendserver.c
pppd/plugins/rp-pppoe/discovery.c
pppd/plugins/winbind.c
pppd/pppd.h
pppd/sys-solaris.c
pppd/utils.c

index babb6dc31bab6f1d71d1cabedfd844ba2a4d5158..44e381501fdd6eeb8e02148ddb892cdde5384198 100644 (file)
@@ -74,7 +74,7 @@ static int promptpass(char *user, char *passwd)
        if (red == 0)
            break;
        if (red < 0) {
        if (red == 0)
            break;
        if (red < 0) {
-           if (errno == EINTR)
+           if (errno == EINTR && !got_sigterm)
                continue;
            error("Can't read secret from %s: %m", promptprog);
            readgood = -1;
                continue;
            error("Can't read secret from %s: %m", promptprog);
            readgood = -1;
@@ -86,7 +86,7 @@ static int promptpass(char *user, char *passwd)
 
     /* now wait for child to exit */
     while (waitpid(kid, &wstat, 0) < 0) {
 
     /* now wait for child to exit */
     while (waitpid(kid, &wstat, 0) < 0) {
-       if (errno != EINTR) {
+       if (errno != EINTR || got_sigterm) {
            warn("error waiting for %s: %m", promptprog);
            break;
        }
            warn("error waiting for %s: %m", promptprog);
            break;
        }
index f68aa67f0380617b5941c1c574b9201b2731b30d..0c0ef30f8d37f41309cc395a9d3fad5153130f08 100644 (file)
@@ -302,7 +302,7 @@ int rc_send_server (SEND_DATA *data, char *msg, REQUEST_INFO *info)
                FD_SET (sockfd, &readfds);
                if (select (sockfd + 1, &readfds, NULL, NULL, &authtime) < 0)
                {
                FD_SET (sockfd, &readfds);
                if (select (sockfd + 1, &readfds, NULL, NULL, &authtime) < 0)
                {
-                       if (errno == EINTR)
+                       if (errno == EINTR && !got_sigterm)
                                continue;
                        error("rc_send_server: select: %m");
                        memset (secret, '\0', sizeof (secret));
                                continue;
                        error("rc_send_server: select: %m");
                        memset (secret, '\0', sizeof (secret));
index a4e4cec93ce1c21ebd8841813b6ee33cdc67d13f..fd851def2fededf5f53bb64fd7681406ad598fcf 100644 (file)
@@ -369,7 +369,7 @@ waitForPADO(PPPoEConnection *conn, int timeout)
 
            while(1) {
                r = select(conn->discoverySocket+1, &readable, NULL, NULL, &tv);
 
            while(1) {
                r = select(conn->discoverySocket+1, &readable, NULL, NULL, &tv);
-               if (r >= 0 || errno != EINTR) break;
+               if (r >= 0 || errno != EINTR || got_sigterm) break;
            }
            if (r < 0) {
                error("select (waitForPADO): %m");
            }
            if (r < 0) {
                error("select (waitForPADO): %m");
@@ -550,7 +550,7 @@ waitForPADS(PPPoEConnection *conn, int timeout)
 
            while(1) {
                r = select(conn->discoverySocket+1, &readable, NULL, NULL, &tv);
 
            while(1) {
                r = select(conn->discoverySocket+1, &readable, NULL, NULL, &tv);
-               if (r >= 0 || errno != EINTR) break;
+               if (r >= 0 || errno != EINTR || got_sigterm) break;
            }
            if (r < 0) {
                error("select (waitForPADS): %m");
            }
            if (r < 0) {
                error("select (waitForPADS): %m");
@@ -622,7 +622,7 @@ discovery(PPPoEConnection *conn)
 
     do {
        padiAttempts++;
 
     do {
        padiAttempts++;
-       if (padiAttempts > conn->discoveryAttempts) {
+       if (got_sigterm || padiAttempts > conn->discoveryAttempts) {
            warn("Timeout waiting for PADO packets");
            close(conn->discoverySocket);
            conn->discoverySocket = -1;
            warn("Timeout waiting for PADO packets");
            close(conn->discoverySocket);
            conn->discoverySocket = -1;
@@ -638,7 +638,7 @@ discovery(PPPoEConnection *conn)
     timeout = conn->discoveryTimeout;
     do {
        padrAttempts++;
     timeout = conn->discoveryTimeout;
     do {
        padrAttempts++;
-       if (padrAttempts > conn->discoveryAttempts) {
+       if (got_sigterm || padrAttempts > conn->discoveryAttempts) {
            warn("Timeout waiting for PADS packets");
            close(conn->discoverySocket);
            conn->discoverySocket = -1;
            warn("Timeout waiting for PADS packets");
            close(conn->discoverySocket);
            conn->discoverySocket = -1;
index 4638f46530469fa29812c5b45c56c06263d27745..0c395c34711af6cef39d3ac01e3603f7205ebbc5 100644 (file)
@@ -443,7 +443,7 @@ unsigned int run_ntlm_auth(const char *username,
                 return NOT_AUTHENTICATED;
         }
 
                 return NOT_AUTHENTICATED;
         }
 
-       while ((wait(&status) == -1) && errno == EINTR)
+       while ((wait(&status) == -1) && errno == EINTR && !got_sigterm)
                 ;
 
        if ((authenticated == AUTHENTICATED) && nt_key && !got_user_session_key) {
                 ;
 
        if ((authenticated == AUTHENTICATED) && nt_key && !got_user_session_key) {
index 4ab2ac1309902b05b21fe71a5113f3d16a066800..f44fe016c82847b6f402a635329aa082eba5d897 100644 (file)
@@ -223,6 +223,7 @@ struct notifier {
  * Global variables.
  */
 
  * Global variables.
  */
 
+extern int     got_sigterm;    /* SIGINT or SIGTERM was received */
 extern int     hungup;         /* Physical layer has disconnected */
 extern int     ifunit;         /* Interface unit number */
 extern char    ifname[];       /* Interface name */
 extern int     hungup;         /* Physical layer has disconnected */
 extern int     ifunit;         /* Interface unit number */
 extern char    ifname[];       /* Interface name */
index 65b173a79695b7e80b8b421072532073be513ca0..a85c73301ed2b474ee644f170ff733714811306d 100644 (file)
@@ -2427,7 +2427,7 @@ dlpi_get_reply(fd, reply, expected_prim, maxlen)
     pfd.events = POLLIN | POLLPRI;
     do {
        n = poll(&pfd, 1, 1000);
     pfd.events = POLLIN | POLLPRI;
     do {
        n = poll(&pfd, 1, 1000);
-    } while (n == -1 && errno == EINTR);
+    } while (n == -1 && errno == EINTR && !got_sigterm);
     if (n <= 0)
        return -1;
 
     if (n <= 0)
        return -1;
 
index 3602aa61674ab23c538d6e3cebdea511cde42a6e..23189d0ad105bd49f9c00c274ab6340cfd6ffb09 100644 (file)
@@ -835,7 +835,7 @@ complete_read(int fd, void *buf, size_t count)
        for (done = 0; done < count; ) {
                nb = read(fd, ptr, count - done);
                if (nb < 0) {
        for (done = 0; done < count; ) {
                nb = read(fd, ptr, count - done);
                if (nb < 0) {
-                       if (errno == EINTR)
+                       if (errno == EINTR && !got_sigterm)
                                continue;
                        return -1;
                }
                                continue;
                        return -1;
                }