[evolution-patches] Re: [Evolution-hackers] Deadlock in camel-gpg-context.c
- From: Jeffrey Stedfast <fejj ximian com>
- To: Christophe Saout <christophe saout de>
- Cc: evolution-hackers ximian com, evolution-patches ximian com
- Subject: [evolution-patches] Re: [Evolution-hackers] Deadlock in camel-gpg-context.c
- Date: 21 Apr 2003 15:27:18 -0400
Attached is a patch to clean up the camel-gpg-context code to deal with
this scenerio.
We don't even need the seen_eof1 bit in gpg_verify() for determining if
we've gotten a TRUST_* status message since we can easily tell by
checking gpg->trust != GPG_TRUST_UNKNOWN.
Jeff
On Mon, 2003-04-21 at 15:05, Jeffrey Stedfast wrote:
> On Mon, 2003-04-21 at 13:55, Christophe Saout wrote:
> > Am Mon, 2003-04-21 um 19.41 schrieb Jeffrey Stedfast:
> >
> > > > In camel/camel-gpg-context.c (evo 1.3 cvs) there is a problem:
> > > >
> > > > In gpg_ctx_op_step the file descriptors stdout_fd, stderr_fd and
> > > > status_fd are polled for input.
> > > >
> > > > But stdout_fd is not read when there is no gpg->ostream to get the data
> > > > (if (FD_ISSET (gpg->stdout_fd, &rdset) && gpg->ostream)).
> > > >
> > > > So the end of file state cannot be detected and thus gpg->seen_eof1
> > > > won't be set.
> > > >
> > > > If that happens gpg_ctx_op_complete fails to detect when gpg has
> > > > finished and the users of these functions run in an endless loop.
> > >
> > > When can this condition ever happen?
> >
> > When gpg_ctx_op_step is called with gpg->ostream being NULL.
> > gpg_verify and gpg_import_keys don't set them (it actually happened to
> > me when trying to verify a signature).
>
> a few things:
>
> 1) gpg_import_keys() is not yet in use, so this isn't a real concern.
>
> 2) seen_eof1 is used differently in the case of gpg_verify(). Instead of
> being used as a eof marker, it is used to denote that we have gotten a
> trust metric for the data being verified. ie, we parsed a
> TRUST_[NEVER,MARGINAL,FULLY,ULTIMATE] status line from gpg's --status-fd
>
> apparently you have discovered a bug in gpg, although the
> camel-gpg-context code is a bit dodgy in this case as well.
>
> Jeff
--
Jeffrey Stedfast
Evolution Hacker - Ximian, Inc.
fejj ximian com - www.ximian.com
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/evolution/camel/ChangeLog,v
retrieving revision 1.1798
diff -u -r1.1798 ChangeLog
--- ChangeLog 19 Apr 2003 03:15:49 -0000 1.1798
+++ ChangeLog 21 Apr 2003 19:17:26 -0000
@@ -1,3 +1,14 @@
+2003-04-21 Jeffrey Stedfast <fejj ximian com>
+
+ * camel-gpg-context.c (gpg_ctx_parse_status): Don't set seen_eof1
+ here anymore once we get a trust metric.
+ (gpg_ctx_new): Init seen_eof1 to TRUE here.
+ (gpg_ctx_set_ostream): Change seen_eof1 to FALSE here this way we
+ only ever have to set this if we are expecting output.
+ (gpg_ctx_parse_status): Don't set seen_eof1 for importing either.
+ (gpg_ctx_op_step): Only FD_SET() those fd's that we have not yet
+ finished reading.
+
2003-04-16 Jeffrey Stedfast <fejj ximian com>
* camel-url-scanner.c (camel_url_web_end): Urls are unlikely to
Index: camel-gpg-context.c
===================================================================
RCS file: /cvs/gnome/evolution/camel/camel-gpg-context.c,v
retrieving revision 1.33
diff -u -r1.33 camel-gpg-context.c
--- camel-gpg-context.c 16 Apr 2003 17:02:10 -0000 1.33
+++ camel-gpg-context.c 21 Apr 2003 19:17:26 -0000
@@ -300,7 +300,7 @@
camel_object_ref (CAMEL_OBJECT (session));
gpg->userid_hint = g_hash_table_new (g_str_hash, g_str_equal);
gpg->complete = FALSE;
- gpg->seen_eof1 = FALSE;
+ gpg->seen_eof1 = TRUE;
gpg->seen_eof2 = FALSE;
gpg->pid = (pid_t) -1;
gpg->exit_status = 0;
@@ -424,6 +424,7 @@
if (gpg->ostream)
camel_object_unref (CAMEL_OBJECT (gpg->ostream));
gpg->ostream = ostream;
+ gpg->seen_eof1 = FALSE;
}
static const char *
@@ -875,11 +876,6 @@
} else if (!strncmp (status, "ULTIMATE", 8)) {
gpg->trust = GPG_TRUST_ULTIMATE;
}
-
- /* Since verifying a signature will never produce output
- on gpg's stdout descriptor, we use this EOF bit for
- making sure that we get a TRUST metric. */
- gpg->seen_eof1 = TRUE;
} else if (!strncmp (status, "VALIDSIG", 8)) {
gpg->validsig = TRUE;
} else if (!strncmp (status, "BADSIG", 6)) {
@@ -908,11 +904,7 @@
}
break;
case GPG_CTX_MODE_IMPORT:
- /* hack to work around the fact that gpg
- doesn't write anything to stdout when
- importing keys */
- if (!strncmp (status, "IMPORT_RES", 10))
- gpg->seen_eof1 = TRUE;
+ /* noop */
break;
case GPG_CTX_MODE_EXPORT:
/* noop */
@@ -969,12 +961,21 @@
retry:
FD_ZERO (&rdset);
- FD_SET (gpg->stdout_fd, &rdset);
- FD_SET (gpg->stderr_fd, &rdset);
- FD_SET (gpg->status_fd, &rdset);
- maxfd = MAX (gpg->stdout_fd, gpg->stderr_fd);
- maxfd = MAX (maxfd, gpg->status_fd);
+ if (!gpg->seen_eof1) {
+ FD_SET (gpg->stdout_fd, &rdset);
+ maxfd = MAX (maxfd, gpg->stdout_fd);
+ }
+
+ if (!gpg->seen_eof2) {
+ FD_SET (gpg->stderr_fd, &rdset);
+ maxfd = MAX (maxfd, gpg->stderr_fd);
+ }
+
+ if (!gpg->complete) {
+ FD_SET (gpg->status_fd, &rdset);
+ maxfd = MAX (maxfd, gpg->status_fd);
+ }
if (gpg->stdin_fd != -1 || gpg->passwd_fd != -1) {
FD_ZERO (&wrset);
@@ -990,6 +991,8 @@
wrsetp = &wrset;
}
+ g_assert (maxfd > 0);
+
timeout.tv_sec = 10; /* timeout in seconds */
timeout.tv_usec = 0;
@@ -1184,6 +1187,7 @@
return gpg->complete && gpg->seen_eof1 && gpg->seen_eof2;
}
+#if 0
static gboolean
gpg_ctx_op_exited (struct _GpgCtx *gpg)
{
@@ -1202,6 +1206,7 @@
return FALSE;
}
+#endif
static void
gpg_ctx_op_cancel (struct _GpgCtx *gpg)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]