[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