gnupg_reopen_std - descriptor state problem

Marcin Gryszkalis mg at fork.pl
Thu Sep 6 22:26:24 CEST 2018


Hi there

I have perl web application running on FreeBSD that calls gnupg. 
During tests I started getting an error:
fatal: unable to reopen standard input
from gnupg_reopen_std.

I did some ktrace-ing and it seems that stdin has unexpected state:
fstat(0) indicated EBADF but the desccriptor was not closed.
After EBADF gnupg_reopen_std assumes it is closed and tries to reopen it to 
/dev/null 
(and in my case it gets new descriptor):

54974 gpg2     CALL  fstat(0,0x7fffffffdf70)
54974 gpg2     RET   fstat -1 errno 9 Bad file descriptor	
54974 gpg2     CALL  openat(AT_FDCWD,0x4aac8a,0<O_RDONLY>,<unused>0)
54974 gpg2     NAMI  "/dev/null"
54974 gpg2     RET   openat 5 <-- we don't get 0 but 5 (new file opened)

54974 gpg2     CALL  fstat(0x1,0x7fffffffdf70) <-- for stdout it's ok
54974 gpg2     STRU  struct stat {dev=74, ino=2, mode=010000, nlink=0, 
uid=1004, gid=1003, rdev=0, atime=1536171587.677756000, 
mtime=1536171587.677756000, ctime=1536171587.677756000, birthtime=0, 
size=0, blksize=4096, blocks=0, flags=0x0 }
54974 gpg2     RET   fstat 0

I don't really know what happens to stdin - the perl application binds 
CGI.pm input 
to stdin so it may possibly reach eof (but it shouldn't cause EBADF I 
guess).

I made a simple patch adding close():

 562   if (fstat (STDIN_FILENO, &statbuf) == -1 && errno ==EBADF)
 563     {
           close(STDIN_FILENO); <<<--- here
 564       if (open ("/dev/null",O_RDONLY) == STDIN_FILENO)
 565     did_stdin = 1;
 566       else
 567     did_stdin = 2;
 568     }

and it seems to work properly:

57475 gpg2     CALL  fstat(0,0x7fffffffdf70)
57475 gpg2     RET   fstat -1 errno 9 Bad file descriptor <-- fstat returns 
EBADF
57475 gpg2     CALL  close(0)
57475 gpg2     RET   close 0 <-- close returns OK!
57475 gpg2     CALL  openat(AT_FDCWD,0x4abb5b,0<O_RDONLY>,<unused>0)
57475 gpg2     NAMI  "/dev/null"
57475 gpg2     RET   openat 0

when calling gpg with already closed stdin it behaves as expected:

$ ktrace gpg2 --version  <&-

17007 gpg2     CALL  fstat(0,0x7fffffffe3e0)
17007 gpg2     RET   fstat -1 errno 9 Bad file descriptor <-- fstat returns 
EBADF
17007 gpg2     CALL  close(0)
17007 gpg2     RET   close -1 errno 9 Bad file descriptor <-- close returns 
EBADF as well
17007 gpg2     CALL  openat(AT_FDCWD,0x4abb5b,0<O_RDONLY>,<unused>0)
17007 gpg2     NAMI  "/dev/null"
17007 gpg2     RET   openat 0 <-- reopened stdin


Now to the point: I would provide patch if you think that it can get 
accepted (would be 
useful no to remember to patch gpg :) ).

I can't see any problems additional close() could cause - but I'm not sure 
about all unix plaftorms. 
Any comments?

best regards
-- 
Marcin Gryszkalis, PGP 0xA5DBEEC7 http://fork.pl/gpg.txt




More information about the Gnupg-devel mailing list