Bug 3563 - Error opening /dev/random on Solaris 10
: Error opening /dev/random on Solaris 10
Status: RESOLVED FIXED
: GSI C
Credentials and Proxies
: unspecified
: Sun Solaris
: P3 normal
: 4.0.8
Assigned To:
:
:
: 4743
:
  Show dependency treegraph
 
Reported: 2005-07-13 09:35 by
Modified: 2008-08-11 13:55 (History)


Attachments


Note

You need to log in before you can comment on or make changes to this bug.


Description From 2005-07-13 09:35:36
From the GT4-Friends list:

------------------------------------------------------------
Few days ago, I reported a problem with GT4.0 when submitting job using
globus-job-run on Solaris 10. I've found the cause and a solution. The
problem is due to OpenSSL as explained here:

http://www.mail-archive.com/openssl-dev@openssl.org/msg18853.html

So I had done is to comment out the O_NOFOLLOW option in
"source-trees/gsi/openssl_gpt/crypto/rand/rand_unix.c". Everything seems
to be working fine after rebuilding.

Melvin Koh wrote:
>
>TIME: Mon Jul 11 17:21:57 2005
> PID: 13417 -- Notice: 6: Got connection 127.0.0.1 at Mon Jul 11
>17:21:57 2005
>
>GSS authentication failure
>GSS Major Status: General failure
>GSS Minor Status Error Chain:
>globus_gsi_gssapi: Error with GSI proxy
>globus_gsi_proxy: Error with private key: Couldn't generate RSA key pair
>for proxy handle
>OpenSSL Error: rsa_gen.c:182: in library: rsa routines, function
>RSA_generate_key: BN lib
>OpenSSL Error: md_rand.c:503: in library: random number generator,
>function SSLEAY_RAND_BYTES: PRNG not seeded You need to read the OpenSSL
>FAQ, http://www.openssl.org/support/faq.html
>Failure: GSS failed Major:000d0000 Minor:00000004 Token:00000000
>
>TIME: Mon Jul 11 17:21:57 2005
> PID: 13417 -- Failure: GSS failed Major:000d0000 Minor:00000004
>Token:00000000
>

------------------------------------------------------------


From http://www.mail-archive.com/openssl-dev@openssl.org/msg18853.html

------------------------------------------------------------
I have built OpenSSL 0.9.7e on Solaris 10 (sparc). When the "openssl"
command is run it fails with a error which states that it was unable to
get sufficient entropy, even though Solaris has /dev/[u]random.

So I built OpenSSL on Solaris 9 and found that the "openssl" command
runs OK.

I then ran the "openssl" command under "truss" on both Solaris 9 and
10,  and found that on Solaris 10 the open() of the randomfile in
rand_unix.c was failing with EINVAL. On Solaris 10, the open() call is
made with an additional O_NOFOLLOW option which is not present in
Solaris 9 (I don't think that Solaris 9 has this option defined).

In rand_unix.c there is an #ifdef which tests to see if O_NOFOLLOW is
defined and if it is then this option is added to the open() call.

On Solaris 9 and 10 /dev/urandom and /dev/random actually exist
legitimately as symbolic links like so:

  /dev/random -> ../devices/pseudo/[EMAIL PROTECTED]:random
  /dev/urandom -> ../devices/pseudo/[EMAIL PROTECTED]:urandom

So on Solaris 10, the open() fails because it has been told not to
follow these links. (On Solaris 9 it suceeds because there is no
O_NOFOLLOW option.)

I have worked around this by removing the O_NOFOLLOW option from
rand_unix.c but it needs to be fixed either by allowing /dev/[u]random
to be a sybolic link, or by allowing this only on Solaris platforms.

------------------------------------------------------------
------- Comment #1 From 2007-12-06 15:16:05 -------
Can you try building GT4 using the instructions at
http://dev.globus.org/wiki/C_Security:_Vendor_OpenSSL to see if this fixes your
issue?

Joe
------- Comment #2 From 2008-03-19 15:27:11 -------
We just got tickled about this in bug 5933.  Can we fix the O_NOFOLLOW for
Solaris 10 in the branch?  If you need to test it on a Solaris 10 box for 4.2,
contact me for our login information.
------- Comment #3 From 2008-03-31 12:55:57 -------
For reference, the patch used for 4.0.8 binaries:

Index: crypto/rand/rand_unix.c
===================================================================
RCS file:
/home/globdev/CVS/globus-packages/gsi/openssl_gpt/crypto/rand/rand_unix.c,v
retrieving revision 1.1.1.2
diff -u -r1.1.1.2 rand_unix.c
--- crypto/rand/rand_unix.c     17 Mar 2004 17:53:43 -0000      1.1.1.2
+++ crypto/rand/rand_unix.c     28 Mar 2008 19:20:49 -0000
@@ -120,6 +120,7 @@
 #include <sys/types.h>
 #include <sys/time.h>
 #include <sys/times.h>
+#include <sys/stat.h>
 #include <fcntl.h>
 #include <unistd.h>
 #include <time.h>
@@ -151,9 +152,9 @@
        int n = 0;
 #endif
 #ifdef DEVRANDOM
-       static const char *randomfiles[] = { DEVRANDOM, NULL };
-       const char **randomfile = NULL;
-       int fd;
+       static const char *randomfiles[] = { DEVRANDOM };
+       struct stat randomstats[sizeof(randomfiles)/sizeof(randomfiles[0])];
+       int fd,i;
 #endif
 #ifdef DEVRANDOM_EGD
        static const char *egdsockets[] = { DEVRANDOM_EGD, NULL };
@@ -161,26 +162,39 @@
 #endif

 #ifdef DEVRANDOM
+       memset(randomstats,0,sizeof(randomstats));
        /* Use a random entropy pool device. Linux, FreeBSD and OpenBSD
         * have this. Use /dev/urandom if you can as /dev/random may block
         * if it runs out of random entries.  */

-       for (randomfile = randomfiles; *randomfile && n < ENTROPY_NEEDED;
randomfile++)
+       for (i=0; i<sizeof(randomfiles)/sizeof(randomfiles[0]) && n <
ENTROPY_NEEDED; i++)
                {
-               if ((fd = open(*randomfile, O_RDONLY|O_NONBLOCK
+               if ((fd = open(randomfiles[i], O_RDONLY
+#ifdef O_NONBLOCK
+                        |O_NONBLOCK
+#endif
 #ifdef O_NOCTTY /* If it happens to be a TTY (god forbid), do not make it
                   our controlling tty */
                        |O_NOCTTY
 #endif
-#ifdef O_NOFOLLOW /* Fail if the file is a symbolic link */
-                       |O_NOFOLLOW
-#endif
                        )) >= 0)
                        {
                        struct timeval t = { 0, 10*1000 }; /* Spend 10ms on
                                                              each file. */
-                       int r;
+                       int r,j;
                        fd_set fset;
+                       struct stat *st=&randomstats[i];
+
+                       /* Avoid using same input... Used to be O_NOFOLLOW
+                        * above, but it's not universally appropriate... */
+                       if (fstat(fd,st) != 0)  { close(fd); continue; }
+                       for (j=0;j<i;j++)
+                               {
+                               if (randomstats[j].st_ino==st->st_ino &&
+                                   randomstats[j].st_dev==st->st_dev)
+                                       break;
+                               }
+                       if (j<i)                { close(fd); continue; }

                        do
                                {
------- Comment #4 From 2008-04-04 07:00:09 -------
Charles confirmed this patch was used for the 4.0.7 binaries. I've committed it
to trunk and 4.0 branch.