<div dir="ltr">In this latest patch, I'm also verifying if access returns ENOENT (which originally was raising errno for me).<br><pre>diff --git a/src/fips.c b/src/fips.c
index 1ac7f477..43f70c75 100644
--- a/src/fips.c
+++ b/src/fips.c
@@ -101,6 +101,7 @@ _gcry_initialize_fips_mode (int force)
 {
   static int done;
   gpg_error_t err;
+  int saved_errno;
 
   /* Make sure we are not accidentally called twice.  */
   if (done)
@@ -127,8 +128,14 @@ _gcry_initialize_fips_mode (int force)
      file.  The filename is hardwired so that there won't be any
      confusion on whether /etc/gcrypt/ or /usr/local/etc/gcrypt/ is
      actually used.  The file itself may be empty.  */
+  saved_errno = errno;
   if ( !access (FIPS_FORCE_FILE, F_OK) )
     {
+      /* don't set errno for access if FIPS_FORCE_FILE doesn't exist */
+      if (errno == ENOENT)
+        {
+          errno = saved_errno;
+        }
       gcry_assert (!_gcry_no_fips_mode_required);
       goto leave;
     }
@@ -137,9 +144,17 @@ _gcry_initialize_fips_mode (int force)
   {
     static const char procfname[] = "/proc/sys/crypto/fips_enabled";
     FILE *fp;
-    int saved_errno;
-
+    saved_errno = errno;
+    /* since procfname may not exist and that's okay, we should ignore
+       if fopen sets errno to ENOENT (no such file) */
     fp = fopen (procfname, "r");
+    /* if file doesn't exist, which is a condition described here:
+     <a href="https://www.gnupg.org/documentation/manuals/gcrypt/Enabling-FIPS-mode.html">https://www.gnupg.org/documentation/manuals/gcrypt/Enabling-FIPS-mode.html</a> */
+    if (errno == ENOENT)
+      {
+       /* restore errno's value before fopen call */
+        errno = saved_errno;
+    }
     if (fp)
       {
         char line[256];
@@ -197,9 +212,16 @@ _gcry_initialize_fips_mode (int force)
         }
 
 
+      saved_errno = errno;
       /* If the FIPS force files exists, is readable and has a number
          != 0 on its first line, we enable the enforced fips mode.  */
       fp = fopen (FIPS_FORCE_FILE, "r");
+      if (errno == ENOENT)
+        {
+          /* since FIPS_FORCE_FILE may not exist, we ignore if fopen
+            returns ENOENT (file not found) */
+          errno = saved_errno;
+        }
       if (fp)
         {
           char line[256];
</pre></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Em qui., 20 de ago. de 2020 às 21:05, Antonio Harres <<a href="mailto:tom.mharres@gmail.com">tom.mharres@gmail.com</a>> escreveu:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div><div>I will also attach gdb's output, here my program is called tool.c. When it attempts to initialize libcurl, it changes errno to ENOENT because of /etc/gcrypt/fips_enabled, this also changes errno attached to libcurl, which, in turn, makes my program exit with an "FIle/ directory not found message".<br>I almost forgot, answering your previous question:<br></div>No, I am not under the impression that libgcrypt may not change errno when I call any arbitrary function, but that this specific circumstance differs from the documented behaviour by not considering /etc/gcrypt/fips_enabled *may* not exist.<br></div>Also, my setup doesn't have neither files that gcrypt tries to open to check fips mode, which is the debian default configuration.<br><div><div><div><div><br>Breakpoint 2, main (argc=1, argv=0x7fffffffe128) at tool.c:656<br>656             if ( curl_global_init(CURL_GLOBAL_ALL) != 0 ) { // init libcurl<br>(gdb) watch *errno_p<br>Hardware watchpoint 3: *errno_p<br>(gdb) c<br>Continuing.<br><br>Hardware watchpoint 3: *errno_p<br><br>Old value = 0<br>New value = 2<br>0x00007ffff7e0171c in __access (file=0x7ffff76c335b "/etc/gcrypt/fips_enabled", type=0) at ../sysdeps/unix/sysv/linux/access.c:27<br>27      ../sysdeps/unix/sysv/linux/access.c: No such file or directory.<br>(gdb) bt<br>#0  0x00007ffff7e0171c in __access (file=0x7ffff76c335b "/etc/gcrypt/fips_enabled", type=0)<br>    at ../sysdeps/unix/sysv/linux/access.c:27<br>#1  0x00007ffff760024e in ?? () from /lib/x86_64-linux-gnu/libgcrypt.so.20<br>#2  0x00007ffff75f88ea in ?? () from /lib/x86_64-linux-gnu/libgcrypt.so.20<br>#3  0x00007ffff75f9a5f in ?? () from /lib/x86_64-linux-gnu/libgcrypt.so.20<br>#4  0x00007ffff75f5789 in gcry_control () from /lib/x86_64-linux-gnu/libgcrypt.so.20<br>#5  0x00007ffff7c76794 in libssh2_init () from /lib/x86_64-linux-gnu/libssh2.so.1<br>#6  0x00007ffff7f428fb in ?? () from /lib/x86_64-linux-gnu/libcurl-gnutls.so.4<br>#7  0x00007ffff7f032d7 in ?? () from /lib/x86_64-linux-gnu/libcurl-gnutls.so.4<br>#8  0x0000555555556110 in main (argc=1, argv=0x7fffffffe128) at tool.c:656<br>(gdb) <br></div></div></div></div></div>
</blockquote></div>