Improve handling of mlock error codes.
authorWerner Koch <wk@gnupg.org>
Fri, 9 Dec 2016 11:10:54 +0000 (12:10 +0100)
committerWerner Koch <wk@gnupg.org>
Fri, 9 Dec 2016 11:10:54 +0000 (12:10 +0100)
* acinclude.m4 (GNUPG_CHECK_MLOCK): Check also for EAGAIN which is a
legitimate return code and does not indicate a broken mlock().
* src/secmem.c (lock_pool_pages): Test ERR instead of ERRNO which
could have been overwritten by cap_from+text et al.
--

  On FreeBSD, if there are not enough free pages, mlock() can return
  EAGAIN, as documented in mlock(2). That doesn't mean that mlock is
  broken. I suspect this same issue also exists on the other BSD's.

Suggested-by: Ruben Kerkhof <ruben@rubenkerkhof.com>
This is (now) also true for Linux.

Signed-off-by: Werner Koch <wk@gnupg.org>
acinclude.m4
src/secmem.c

index 96be833..90b3cb9 100644 (file)
@@ -242,7 +242,7 @@ int main()
     pool += (pgsize - ((long int)pool % pgsize));
 
     err = mlock( pool, 4096 );
-    if( !err || errno == EPERM )
+    if( !err || errno == EPERM || errno == EGAIN)
         return 0; /* okay */
 
     return 1;  /* hmmm */
index 4fa267b..55424f2 100644 (file)
@@ -282,15 +282,15 @@ lock_pool_pages (void *p, size_t n)
 
   if (err)
     {
-      if (errno != EPERM
-#ifdef EAGAIN  /* OpenBSD returns this */
-         && errno != EAGAIN
+      if (err != EPERM
+#ifdef EAGAIN  /* BSD and also Linux may return EAGAIN */
+         && err != EAGAIN
 #endif
 #ifdef ENOSYS  /* Some SCOs return this (function not implemented) */
-         && errno != ENOSYS
+         && err != ENOSYS
 #endif
 #ifdef ENOMEM  /* Linux might return this. */
-            && errno != ENOMEM
+            && err != ENOMEM
 #endif
          )
        log_error ("can't lock memory: %s\n", strerror (err));
@@ -341,15 +341,15 @@ lock_pool_pages (void *p, size_t n)
 
   if (err)
     {
-      if (errno != EPERM
-#ifdef EAGAIN  /* OpenBSD returns this. */
-         && errno != EAGAIN
+      if (err != EPERM
+#ifdef EAGAIN  /* BSD and also Linux may return this. */
+         && err != EAGAIN
 #endif
 #ifdef ENOSYS  /* Some SCOs return this (function not implemented). */
-         && errno != ENOSYS
+         && err != ENOSYS
 #endif
 #ifdef ENOMEM  /* Linux might return this. */
-            && errno != ENOMEM
+            && err != ENOMEM
 #endif
          )
        log_error ("can't lock memory: %s\n", strerror (err));