[Pkg-gnupg-commit] [gnupg2] 01/01: scdaemon fixes from gniibe

Daniel Kahn Gillmor dkg at fifthhorseman.net
Fri Feb 17 08:31:49 UTC 2017


This is an automated email from the git hooks/post-receive script.

dkg pushed a commit to branch master
in repository gnupg2.

commit a462489633dd00a87fa3195cc72d3f7cc332069f
Author: Daniel Kahn Gillmor <dkg at fifthhorseman.net>
Date:   Fri Feb 17 03:30:59 2017 -0500

    scdaemon fixes from gniibe
---
 debian/patches/0030-scd-Fix-factory-reset.patch | 353 ++++++++++++++++++++++++
 debian/patches/series                           |   1 +
 2 files changed, 354 insertions(+)

diff --git a/debian/patches/0030-scd-Fix-factory-reset.patch b/debian/patches/0030-scd-Fix-factory-reset.patch
new file mode 100644
index 0000000..09951bb
--- /dev/null
+++ b/debian/patches/0030-scd-Fix-factory-reset.patch
@@ -0,0 +1,353 @@
+From: NIIBE Yutaka <gniibe at fsij.org>
+Date: Fri, 17 Feb 2017 03:30:05 -0500
+Subject: scd: Fix factory-reset.
+
+Signed-off-by: NIIBE Yutaka <gniibe at fsij.org>
+
+Backport from master branch:
+
+    99d4dfe83
+    e2792813a
+    031e3fa7b
+---
+ scd/app-common.h |  3 +-
+ scd/app.c        | 83 +++++++++++++++++++++++++++++++-------------------------
+ scd/command.c    |  6 ++--
+ scd/scdaemon.c   | 51 +++++++++++++++++++++++++++++++---
+ scd/scdaemon.h   |  1 +
+ 5 files changed, 99 insertions(+), 45 deletions(-)
+
+diff --git a/scd/app-common.h b/scd/app-common.h
+index b979f5476..c7a057521 100644
+--- a/scd/app-common.h
++++ b/scd/app-common.h
+@@ -54,6 +54,7 @@ struct app_ctx_s {
+   const char *apptype;
+   unsigned int card_version;
+   unsigned int card_status;
++  unsigned int reset_requested:1;
+   unsigned int require_get_status:1;
+   unsigned int did_chv1:1;
+   unsigned int force_chv1:1;   /* True if the card does not cache CHV1. */
+@@ -134,7 +135,7 @@ gpg_error_t select_application (ctrl_t ctrl, const char *name, app_t *r_app,
+                                 int scan, const unsigned char *serialno_bin,
+                                 size_t serialno_bin_len);
+ char *get_supported_applications (void);
+-void release_application (app_t app);
++void release_application (app_t app, int locked_already);
+ gpg_error_t app_munge_serialno (app_t app);
+ gpg_error_t app_write_learn_status (app_t app, ctrl_t ctrl,
+                                     unsigned int flags);
+diff --git a/scd/app.c b/scd/app.c
+index 8fb0d4553..af86ab830 100644
+--- a/scd/app.c
++++ b/scd/app.c
+@@ -136,40 +136,32 @@ check_application_conflict (const char *name, app_t app)
+ }
+ 
+ 
+-static void
+-release_application_internal (app_t app)
+-{
+-  if (!app->ref_count)
+-    log_bug ("trying to release an already released context\n");
+-
+-  --app->ref_count;
+-}
+-
+ gpg_error_t
+ app_reset (app_t app, ctrl_t ctrl, int send_reset)
+ {
+-  gpg_error_t err;
+-
+-  err = lock_app (app, ctrl);
+-  if (err)
+-    return err;
++  gpg_error_t err = 0;
+ 
+   if (send_reset)
+     {
+-      int sw = apdu_reset (app->slot);
++      int sw;
++
++      lock_app (app, ctrl);
++      sw = apdu_reset (app->slot);
+       if (sw)
+         err = gpg_error (GPG_ERR_CARD_RESET);
+ 
+-      /* Release the same application which is used by other sessions.  */
+-      send_client_notifications (app, 1);
++      app->reset_requested = 1;
++      unlock_app (app);
++
++      scd_kick_the_loop ();
++      gnupg_sleep (1);
+     }
+   else
+     {
+       ctrl->app_ctx = NULL;
+-      release_application_internal (app);
++      release_application (app, 0);
+     }
+ 
+-  unlock_app (app);
+   return err;
+ }
+ 
+@@ -465,6 +457,8 @@ deallocate_app (app_t app)
+     }
+ 
+   xfree (app->serialno);
++
++  unlock_app (app);
+   xfree (app);
+ }
+ 
+@@ -474,7 +468,7 @@ deallocate_app (app_t app)
+    actually deferring the deallocation to allow for a later reuse by
+    a new connection. */
+ void
+-release_application (app_t app)
++release_application (app_t app, int locked_already)
+ {
+   if (!app)
+     return;
+@@ -484,9 +478,15 @@ release_application (app_t app)
+      is using the card - this way the PIN cache and other cached data
+      are preserved.  */
+ 
+-  lock_app (app, NULL);
+-  release_application_internal (app);
+-  unlock_app (app);
++  if (!locked_already)
++    lock_app (app, NULL);
++
++  if (!app->ref_count)
++    log_bug ("trying to release an already released context\n");
++
++  --app->ref_count;
++  if (!locked_already)
++    unlock_app (app);
+ }
+ 
+ 
+@@ -1023,11 +1023,16 @@ scd_update_reader_status_file (void)
+   npth_mutex_lock (&app_list_lock);
+   for (a = app_top; a; a = app_next)
+     {
++      unsigned int status;
++
++      lock_app (a, NULL);
+       app_next = a->next;
+-      if (a->require_get_status)
++
++      if (a->reset_requested)
++        status = 0;
++      else
+         {
+           int sw;
+-          unsigned int status;
+           sw = apdu_get_status (a->slot, 0, &status);
+ 
+           if (sw == SW_HOST_NO_READER)
+@@ -1038,22 +1043,26 @@ scd_update_reader_status_file (void)
+           else if (sw)
+             {
+               /* Get status failed.  Ignore that.  */
++              unlock_app (a);
+               continue;
+             }
++        }
++
++      if (a->card_status != status)
++        {
++          report_change (a->slot, a->card_status, status);
++          send_client_notifications (a, status == 0);
+ 
+-          if (a->card_status != status)
++          if (status == 0)
++            {
++              log_debug ("Removal of a card: %d\n", a->slot);
++              apdu_close_reader (a->slot);
++              deallocate_app (a);
++            }
++          else
+             {
+-              report_change (a->slot, a->card_status, status);
+-              send_client_notifications (a, status == 0);
+-
+-              if (status == 0)
+-                {
+-                  log_debug ("Removal of a card: %d\n", a->slot);
+-                  apdu_close_reader (a->slot);
+-                  deallocate_app (a);
+-                }
+-              else
+-                a->card_status = status;
++              a->card_status = status;
++              unlock_app (a);
+             }
+         }
+     }
+diff --git a/scd/command.c b/scd/command.c
+index 0ae6d29aa..b17c4a109 100644
+--- a/scd/command.c
++++ b/scd/command.c
+@@ -227,7 +227,7 @@ open_card_with_request (ctrl_t ctrl, const char *apptype, const char *serialno)
+ 
+   /* Re-scan USB devices.  Release APP, before the scan.  */
+   ctrl->app_ctx = NULL;
+-  release_application (app);
++  release_application (app, 0);
+ 
+   if (serialno)
+     serialno_bin = hex_to_buffer (serialno, &serialno_bin_len);
+@@ -1492,7 +1492,7 @@ cmd_restart (assuan_context_t ctx, char *line)
+   if (app)
+     {
+       ctrl->app_ctx = NULL;
+-      release_application (app);
++      release_application (app, 0);
+     }
+   if (locked_session && ctrl->server_local == locked_session)
+     {
+@@ -1919,7 +1919,7 @@ send_client_notifications (app_t app, int removal)
+           {
+             sl->ctrl_backlink->app_ctx = NULL;
+             sl->card_removed = 1;
+-            release_application (app);
++            release_application (app, 1);
+           }
+ 
+         if (!sl->event_signal || !sl->assuan_ctx)
+diff --git a/scd/scdaemon.c b/scd/scdaemon.c
+index 74fed4454..02f0e7221 100644
+--- a/scd/scdaemon.c
++++ b/scd/scdaemon.c
+@@ -52,6 +52,7 @@
+ #include "ccid-driver.h"
+ #include "gc-opt-flags.h"
+ #include "asshelp.h"
++#include "exechelp.h"
+ #include "../common/init.h"
+ 
+ #ifndef ENAMETOOLONG
+@@ -224,7 +225,8 @@ static assuan_sock_nonce_t socket_nonce;
+    disabled but it won't perform any ticker specific actions. */
+ static int ticker_disabled;
+ 
+-
++/* FD to notify update of usb devices.  */
++static int notify_fd;
+ 

+ static char *create_socket_name (char *standard_name);
+ static gnupg_fd_t create_server_socket (const char *name,
+@@ -1181,6 +1183,16 @@ start_connection_thread (void *arg)
+ }
+ 
+ 
++void
++scd_kick_the_loop (void)
++{
++  int ret;
++
++  /* Kick the select loop.  */
++  ret = write (notify_fd, "", 1);
++  (void)ret;
++}
++
+ /* Connection handler loop.  Wait for connection requests and spawn a
+    thread after accepting a connection.  LISTEN_FD is allowed to be -1
+    in which case this code will only do regular timeouts and handle
+@@ -1202,9 +1214,23 @@ handle_connections (int listen_fd)
+ #ifndef HAVE_W32_SYSTEM
+   int signo;
+ #endif
++  int pipe_fd[2];
++
++  ret = gnupg_create_pipe (pipe_fd);
++  if (ret)
++    {
++      log_error ("pipe creation failed: %s\n", gpg_strerror (ret));
++      return;
++    }
++  notify_fd = pipe_fd[1];
+ 
+   ret = npth_attr_init(&tattr);
+-  /* FIXME: Check error.  */
++  if (ret)
++    {
++      log_error ("npth_attr_init failed: %s\n", strerror (ret));
++      return;
++    }
++
+   npth_attr_setdetachstate (&tattr, NPTH_CREATE_DETACHED);
+ 
+ #ifndef HAVE_W32_SYSTEM
+@@ -1233,6 +1259,8 @@ handle_connections (int listen_fd)
+ 
+   for (;;)
+     {
++      int max_fd;
++
+       if (shutdown_pending)
+         {
+           if (active_connections == 0)
+@@ -1261,14 +1289,20 @@ handle_connections (int listen_fd)
+          thus a simple assignment is fine to copy the entire set.  */
+       read_fdset = fdset;
+ 
++      FD_SET (pipe_fd[0], &read_fdset);
++      if (nfd < pipe_fd[0])
++        max_fd = pipe_fd[0];
++      else
++        max_fd = nfd;
++
+ #ifndef HAVE_W32_SYSTEM
+-      ret = npth_pselect (nfd+1, &read_fdset, NULL, NULL, &timeout, npth_sigev_sigmask());
++      ret = npth_pselect (max_fd+1, &read_fdset, NULL, NULL, &timeout, npth_sigev_sigmask());
+       saved_errno = errno;
+ 
+       while (npth_sigev_get_pending(&signo))
+ 	handle_signal (signo);
+ #else
+-      ret = npth_eselect (nfd+1, &read_fdset, NULL, NULL, &timeout, NULL, NULL);
++      ret = npth_eselect (max_fd+1, &read_fdset, NULL, NULL, &timeout, NULL, NULL);
+       saved_errno = errno;
+ #endif
+ 
+@@ -1284,6 +1318,13 @@ handle_connections (int listen_fd)
+ 	/* Timeout.  Will be handled when calculating the next timeout.  */
+ 	continue;
+ 
++      if (FD_ISSET (pipe_fd[0], &read_fdset))
++        {
++          char buf[256];
++
++          ret = read (pipe_fd[0], buf, sizeof buf);
++        }
++
+       if (listen_fd != -1 && FD_ISSET (listen_fd, &read_fdset))
+ 	{
+           ctrl_t ctrl;
+@@ -1322,6 +1363,8 @@ handle_connections (int listen_fd)
+ 	}
+     }
+ 
++  close (pipe_fd[0]);
++  close (pipe_fd[1]);
+   cleanup ();
+   log_info (_("%s %s stopped\n"), strusage(11), strusage(13));
+   npth_attr_destroy (&tattr);
+diff --git a/scd/scdaemon.h b/scd/scdaemon.h
+index d0bc98efe..fcab6489f 100644
+--- a/scd/scdaemon.h
++++ b/scd/scdaemon.h
+@@ -125,6 +125,7 @@ void send_status_info (ctrl_t ctrl, const char *keyword, ...)
+ void send_status_direct (ctrl_t ctrl, const char *keyword, const char *args);
+ void scd_update_reader_status_file (void);
+ void send_client_notifications (app_t app, int removal);
++void scd_kick_the_loop (void);
+ 
+ 
+ #endif /*SCDAEMON_H*/
diff --git a/debian/patches/series b/debian/patches/series
index bd3d6f6..afa84e1 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -27,3 +27,4 @@ gpg-agent-idling/0004-agent-Avoid-scheduled-checks-on-socket-when-inotify-.patch
 0027-doc-Clarify-abbreviation-of-help.patch
 0028-scd-Backport-two-fixes-from-master.patch
 0029-scd-Fix-use-case-of-PC-SC.patch
+0030-scd-Fix-factory-reset.patch

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-gnupg/gnupg2.git



More information about the Pkg-gnupg-commit mailing list