Gpgme gpgconf changes are sometimes not made
Closed, ResolvedPublic

Description

Kleopatra switched to the QGpgME API for engine gpgconf. Now ~50% of
configuration changes made on Windows are ignored. I can see the process call to
gpgconf in the gpgme log and the writes of the configuration change into the
pipe to gpgconf but but they never make it into the config file.

I've tried to reproduce this without Kleopatra on Linux and wrote a small
testcase that writes a configuration value (Changes keyserver to
hkp://foo@bar.baz) and reads it afterwards. This sometimes fails, sometimes not.
In difference to the windows behavior the actual config file is always written
with the correct value even if the test failed.

I thought that maybe gpgconf_write returned too early before the gpgconf process
was actually finished and inserted a waitpid on the spawned process after
gpgconf_write finished writing but this did not help.

In attached logs gpgme_bad / gpgme_good you can see around line 793 that
change-options is called and the option is written.

Then on line 934 you can see that the config value is still unchanged in the bad
case but the keyserver is foo.bar.baz in the good case.

The good log is a bit longer because the test aborted earlier inn the bad case.

werner added a subscriber: werner.Dec 20 2016, 3:27 PM

Can you repeat this also with GPA, which uses the gpgconf for ages?

Can you repeat this also with GPA, which uses the gpgconf for ages?

Yes, It's even more visible in GPA because according to the gpgme log GPA does a
list options right after the change. So e.g. If you check "quiet" in the gpg
options then hit apply the check box gets unselected after apply although the
config is changed. Log is similar to the ones attached. Change options is
visible but afterwards the list-options still returns the old value.

On Linux I could not reproduce it with gpa, but as I think it's a timing issue
that might be expected. Attached is a patch that adds a Qt test which exposes
the problem on Linux. I can translate that to plain C if it helps. But I think
the attached Logs are already obvious that there is an issue.

On Windows we copy the new file; on Unix we link-rename it. It might be worth
to change that old code to use estream and the same method for file updates as
we use elsewhere.

justus claimed this task.Jan 9 2017, 11:23 AM
justus added a subscriber: justus.
justus closed this task as Resolved.Jan 16 2017, 12:56 PM

After testing on Windows this problem is not resolved for Windows (I agree that
it's resolved for posix).

The issue there that I see now is not that it's a race between changing the
setting and immediately reading it again but that sometimes the communication
between gpgme and gpgconf fails.

See attached file no-read.txt for some debugging on this. GPGME writes a changed
option to gpgconf but gpgconf does not read it. I've used OutputDebugString and
DbgView to have syncronized debug output over process borders.

Not 100% reproducible but on my test system it fails very often.

aheinecke reopened this task as Open.Jan 23 2017, 12:14 PM
aheinecke added a project: In Progress.
justus closed this task as Resolved.

Fixed in 6f02133bb07726afa6950e5b4685e75621276e60 by backporting a fix from
gpg-error.