aboutsummaryrefslogtreecommitdiffstats
path: root/scd
diff options
context:
space:
mode:
Diffstat (limited to 'scd')
-rw-r--r--scd/app-openpgp.c11
-rw-r--r--scd/command.c4
-rw-r--r--scd/scdaemon.c39
3 files changed, 49 insertions, 5 deletions
diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c
index fb869b2bf..54f04c612 100644
--- a/scd/app-openpgp.c
+++ b/scd/app-openpgp.c
@@ -348,7 +348,8 @@ get_cached_data (app_t app, int tag,
err = iso7816_get_data (app->slot, exmode, tag, &p, &len);
if (err)
return err;
- *result = p;
+ if (len)
+ *result = p;
*resultlen = len;
/* Check whether we should cache this object. */
@@ -370,7 +371,10 @@ get_cached_data (app_t app, int tag,
c = xtrymalloc (sizeof *c + len);
if (c)
{
- memcpy (c->data, p, len);
+ if (len)
+ memcpy (c->data, p, len);
+ else
+ xfree (p);
c->length = len;
c->tag = tag;
c->next = app->app_local->cache;
@@ -2068,7 +2072,8 @@ pin2hash_if_kdf (app_t app, int chvno, char *pinvalue, int *r_pinlen)
size_t buflen;
if (app->app_local->extcap.kdf_do
- && (relptr = get_one_do (app, 0x00F9, &buffer, &buflen, NULL)))
+ && (relptr = get_one_do (app, 0x00F9, &buffer, &buflen, NULL))
+ && buflen == 110 && (buffer[2] == 0x03))
{
char *salt;
unsigned long s2k_count;
diff --git a/scd/command.c b/scd/command.c
index 6bcbce4fc..701151894 100644
--- a/scd/command.c
+++ b/scd/command.c
@@ -1848,7 +1848,8 @@ send_status_info (ctrl_t ctrl, const char *keyword, ...)
p = buf;
n = 0;
- while ( (value = va_arg (arg_ptr, const unsigned char *)) )
+ while ( (value = va_arg (arg_ptr, const unsigned char *))
+ && n < DIM (buf)-2 )
{
valuelen = va_arg (arg_ptr, size_t);
if (!valuelen)
@@ -1865,6 +1866,7 @@ send_status_info (ctrl_t ctrl, const char *keyword, ...)
{
sprintf (p, "%%%02X", *value);
p += 3;
+ n += 2;
}
else if (*value == ' ')
*p++ = '+';
diff --git a/scd/scdaemon.c b/scd/scdaemon.c
index 3ad265781..cebeea9d3 100644
--- a/scd/scdaemon.c
+++ b/scd/scdaemon.c
@@ -236,6 +236,10 @@ static HANDLE the_event;
/* PID to notify update of usb devices. */
static pid_t main_thread_pid;
#endif
+#ifdef HAVE_PSELECT_NO_EINTR
+/* FD to notify changes. */
+static int notify_fd;
+#endif
static char *create_socket_name (char *standard_name);
static gnupg_fd_t create_server_socket (const char *name,
@@ -1210,6 +1214,8 @@ scd_kick_the_loop (void)
if (ret == 0)
log_error ("SetEvent for scd_kick_the_loop failed: %s\n",
w32_strerror (-1));
+#elif defined(HAVE_PSELECT_NO_EINTR)
+ write (notify_fd, "", 1);
#else
ret = kill (main_thread_pid, SIGCONT);
if (ret < 0)
@@ -1241,6 +1247,17 @@ handle_connections (int listen_fd)
#else
int signo;
#endif
+#ifdef HAVE_PSELECT_NO_EINTR
+ 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];
+#endif
ret = npth_attr_init(&tattr);
if (ret)
@@ -1298,6 +1315,7 @@ handle_connections (int listen_fd)
for (;;)
{
int periodical_check;
+ int max_fd = nfd;
if (shutdown_pending)
{
@@ -1326,8 +1344,14 @@ handle_connections (int listen_fd)
thus a simple assignment is fine to copy the entire set. */
read_fdset = fdset;
+#ifdef HAVE_PSELECT_NO_EINTR
+ FD_SET (pipe_fd[0], &read_fdset);
+ if (max_fd < pipe_fd[0])
+ max_fd = pipe_fd[0];
+#endif
+
#ifndef HAVE_W32_SYSTEM
- ret = npth_pselect (nfd+1, &read_fdset, NULL, NULL, t,
+ ret = npth_pselect (max_fd+1, &read_fdset, NULL, NULL, t,
npth_sigev_sigmask ());
saved_errno = errno;
@@ -1353,6 +1377,15 @@ handle_connections (int listen_fd)
/* Timeout. Will be handled when calculating the next timeout. */
continue;
+#ifdef HAVE_PSELECT_NO_EINTR
+ if (FD_ISSET (pipe_fd[0], &read_fdset))
+ {
+ char buf[256];
+
+ read (pipe_fd[0], buf, sizeof buf);
+ }
+#endif
+
if (listen_fd != -1 && FD_ISSET (listen_fd, &read_fdset))
{
ctrl_t ctrl;
@@ -1394,6 +1427,10 @@ handle_connections (int listen_fd)
if (the_event != INVALID_HANDLE_VALUE)
CloseHandle (the_event);
#endif
+#ifdef HAVE_PSELECT_NO_EINTR
+ close (pipe_fd[0]);
+ close (pipe_fd[1]);
+#endif
cleanup ();
log_info (_("%s %s stopped\n"), strusage(11), strusage(13));
npth_attr_destroy (&tattr);