diff options
| author | Paul Eggert | 2016-01-17 17:16:12 -0800 |
|---|---|---|
| committer | Paul Eggert | 2016-01-17 17:17:01 -0800 |
| commit | 130d512045aa376333b664d58c501b3884187592 (patch) | |
| tree | fe7b2fa10229b204eeb16aa34d0191864caf9e70 /src | |
| parent | 0f3ea5e172e584875fa5808322af8a7c75503f7b (diff) | |
| download | emacs-130d512045aa376333b664d58c501b3884187592.tar.gz emacs-130d512045aa376333b664d58c501b3884187592.zip | |
Initialize GnuTLS before calling gnutls_rnd
* src/gnutls.c (emacs_gnutls_global_init): Now extern.
Don’t set gnutls_global_initialized if gnutls_global_init fails.
* src/sysdep.c: Include "gnutls.h", and <gnutls/crypto.h>
if 2.12 or later, which has gnutls_rnd.
(emacs_gnutls_global_init, gnutls_rnd): New fallback
placeholder macros if before 2.12.
(init_random): Initialize gnutls globals before trying to
use gnutls_rnd.
Diffstat (limited to 'src')
| -rw-r--r-- | src/gnutls.c | 10 | ||||
| -rw-r--r-- | src/gnutls.h | 1 | ||||
| -rw-r--r-- | src/sysdep.c | 54 |
3 files changed, 40 insertions, 25 deletions
diff --git a/src/gnutls.c b/src/gnutls.c index a1d058fcd48..01a5983d3b0 100644 --- a/src/gnutls.c +++ b/src/gnutls.c | |||
| @@ -1112,15 +1112,17 @@ The return value is a property list with top-level keys :warnings and | |||
| 1112 | /* Initialize global GnuTLS state to defaults. | 1112 | /* Initialize global GnuTLS state to defaults. |
| 1113 | Call `gnutls-global-deinit' when GnuTLS usage is no longer needed. | 1113 | Call `gnutls-global-deinit' when GnuTLS usage is no longer needed. |
| 1114 | Return zero on success. */ | 1114 | Return zero on success. */ |
| 1115 | static Lisp_Object | 1115 | Lisp_Object |
| 1116 | emacs_gnutls_global_init (void) | 1116 | emacs_gnutls_global_init (void) |
| 1117 | { | 1117 | { |
| 1118 | int ret = GNUTLS_E_SUCCESS; | 1118 | int ret = GNUTLS_E_SUCCESS; |
| 1119 | 1119 | ||
| 1120 | if (!gnutls_global_initialized) | 1120 | if (!gnutls_global_initialized) |
| 1121 | ret = gnutls_global_init (); | 1121 | { |
| 1122 | 1122 | ret = gnutls_global_init (); | |
| 1123 | gnutls_global_initialized = 1; | 1123 | if (ret == GNUTLS_E_SUCCESS) |
| 1124 | gnutls_global_initialized = 1; | ||
| 1125 | } | ||
| 1124 | 1126 | ||
| 1125 | return gnutls_make_error (ret); | 1127 | return gnutls_make_error (ret); |
| 1126 | } | 1128 | } |
diff --git a/src/gnutls.h b/src/gnutls.h index c4fe738bfa0..8e879c168bd 100644 --- a/src/gnutls.h +++ b/src/gnutls.h | |||
| @@ -83,6 +83,7 @@ extern ptrdiff_t emacs_gnutls_record_check_pending (gnutls_session_t state); | |||
| 83 | extern void emacs_gnutls_transport_set_errno (gnutls_session_t state, int err); | 83 | extern void emacs_gnutls_transport_set_errno (gnutls_session_t state, int err); |
| 84 | #endif | 84 | #endif |
| 85 | extern Lisp_Object emacs_gnutls_deinit (Lisp_Object); | 85 | extern Lisp_Object emacs_gnutls_deinit (Lisp_Object); |
| 86 | extern Lisp_Object emacs_gnutls_global_init (void); | ||
| 86 | 87 | ||
| 87 | #endif | 88 | #endif |
| 88 | 89 | ||
diff --git a/src/sysdep.c b/src/sysdep.c index 7f64a3b9fbc..6b2b2053a24 100644 --- a/src/sysdep.c +++ b/src/sysdep.c | |||
| @@ -99,6 +99,14 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 99 | #include "process.h" | 99 | #include "process.h" |
| 100 | #include "cm.h" | 100 | #include "cm.h" |
| 101 | 101 | ||
| 102 | #include "gnutls.h" | ||
| 103 | #if 0x020c00 <= GNUTLS_VERSION_NUMBER | ||
| 104 | # include <gnutls/crypto.h> | ||
| 105 | #else | ||
| 106 | # define emacs_gnutls_global_init() Qnil | ||
| 107 | # define gnutls_rnd(level, data, len) (-1) | ||
| 108 | #endif | ||
| 109 | |||
| 102 | #ifdef WINDOWSNT | 110 | #ifdef WINDOWSNT |
| 103 | #include <direct.h> | 111 | #include <direct.h> |
| 104 | /* In process.h which conflicts with the local copy. */ | 112 | /* In process.h which conflicts with the local copy. */ |
| @@ -2096,22 +2104,26 @@ void | |||
| 2096 | init_random (void) | 2104 | init_random (void) |
| 2097 | { | 2105 | { |
| 2098 | random_seed v; | 2106 | random_seed v; |
| 2099 | bool success = false; | 2107 | if (! (EQ (emacs_gnutls_global_init (), Qt) |
| 2100 | #ifndef WINDOWSNT | 2108 | && gnutls_rnd (GNUTLS_RND_NONCE, &v, sizeof v) == 0)) |
| 2101 | int fd = emacs_open ("/dev/urandom", O_RDONLY | O_BINARY, 0); | ||
| 2102 | if (fd >= 0) | ||
| 2103 | { | 2109 | { |
| 2104 | success = emacs_read (fd, &v, sizeof v) == sizeof v; | 2110 | bool success = false; |
| 2105 | emacs_close (fd); | 2111 | #ifndef WINDOWSNT |
| 2106 | } | 2112 | int fd = emacs_open ("/dev/urandom", O_RDONLY | O_BINARY, 0); |
| 2113 | if (0 <= fd) | ||
| 2114 | { | ||
| 2115 | success = emacs_read (fd, &v, sizeof v) == sizeof v; | ||
| 2116 | emacs_close (fd); | ||
| 2117 | } | ||
| 2107 | #else | 2118 | #else |
| 2108 | success = w32_init_random (&v, sizeof v) == 0; | 2119 | success = w32_init_random (&v, sizeof v) == 0; |
| 2109 | #endif | 2120 | #endif |
| 2110 | if (! success) | 2121 | if (! success) |
| 2111 | { | 2122 | { |
| 2112 | /* Fall back to current time value + PID. */ | 2123 | /* Fall back to current time value + PID. */ |
| 2113 | struct timespec t = current_timespec (); | 2124 | struct timespec t = current_timespec (); |
| 2114 | v = getpid () ^ t.tv_sec ^ t.tv_nsec; | 2125 | v = getpid () ^ t.tv_sec ^ t.tv_nsec; |
| 2126 | } | ||
| 2115 | } | 2127 | } |
| 2116 | set_random_seed (v); | 2128 | set_random_seed (v); |
| 2117 | } | 2129 | } |
| @@ -2163,7 +2175,7 @@ snprintf (char *buf, size_t bufsize, char const *format, ...) | |||
| 2163 | xfree (b); | 2175 | xfree (b); |
| 2164 | } | 2176 | } |
| 2165 | 2177 | ||
| 2166 | if (nbytes > INT_MAX) | 2178 | if (INT_MAX < nbytes) |
| 2167 | { | 2179 | { |
| 2168 | #ifdef EOVERFLOW | 2180 | #ifdef EOVERFLOW |
| 2169 | errno = EOVERFLOW; | 2181 | errno = EOVERFLOW; |
| @@ -2221,7 +2233,7 @@ emacs_backtrace (int backtrace_limit) | |||
| 2221 | { | 2233 | { |
| 2222 | emacs_write (STDERR_FILENO, "\nBacktrace:\n", 12); | 2234 | emacs_write (STDERR_FILENO, "\nBacktrace:\n", 12); |
| 2223 | backtrace_symbols_fd (buffer, npointers, STDERR_FILENO); | 2235 | backtrace_symbols_fd (buffer, npointers, STDERR_FILENO); |
| 2224 | if (npointers > bounded_limit) | 2236 | if (bounded_limit < npointers) |
| 2225 | emacs_write (STDERR_FILENO, "...\n", 4); | 2237 | emacs_write (STDERR_FILENO, "...\n", 4); |
| 2226 | } | 2238 | } |
| 2227 | } | 2239 | } |
| @@ -2250,7 +2262,7 @@ emacs_open (const char *file, int oflags, int mode) | |||
| 2250 | oflags |= O_CLOEXEC; | 2262 | oflags |= O_CLOEXEC; |
| 2251 | while ((fd = open (file, oflags, mode)) < 0 && errno == EINTR) | 2263 | while ((fd = open (file, oflags, mode)) < 0 && errno == EINTR) |
| 2252 | QUIT; | 2264 | QUIT; |
| 2253 | if (! O_CLOEXEC && fd >= 0) | 2265 | if (! O_CLOEXEC && 0 <= fd) |
| 2254 | fcntl (fd, F_SETFD, FD_CLOEXEC); | 2266 | fcntl (fd, F_SETFD, FD_CLOEXEC); |
| 2255 | return fd; | 2267 | return fd; |
| 2256 | } | 2268 | } |
| @@ -2817,9 +2829,9 @@ time_from_jiffies (unsigned long long tval, long hz) | |||
| 2817 | unsigned long long frac = tval % hz; | 2829 | unsigned long long frac = tval % hz; |
| 2818 | int ns; | 2830 | int ns; |
| 2819 | 2831 | ||
| 2820 | if (s > TYPE_MAXIMUM (time_t)) | 2832 | if (TYPE_MAXIMUM (time_t) < s) |
| 2821 | time_overflow (); | 2833 | time_overflow (); |
| 2822 | if (ULLONG_MAX / TIMESPEC_RESOLUTION >= LONG_MAX - 1 | 2834 | if (LONG_MAX - 1 <= ULLONG_MAX / TIMESPEC_RESOLUTION |
| 2823 | || frac <= ULLONG_MAX / TIMESPEC_RESOLUTION) | 2835 | || frac <= ULLONG_MAX / TIMESPEC_RESOLUTION) |
| 2824 | ns = frac * TIMESPEC_RESOLUTION / hz; | 2836 | ns = frac * TIMESPEC_RESOLUTION / hz; |
| 2825 | else | 2837 | else |
| @@ -3037,7 +3049,7 @@ system_process_attributes (Lisp_Object pid) | |||
| 3037 | record_unwind_protect_int (close_file_unwind, fd); | 3049 | record_unwind_protect_int (close_file_unwind, fd); |
| 3038 | nread = emacs_read (fd, procbuf, sizeof procbuf - 1); | 3050 | nread = emacs_read (fd, procbuf, sizeof procbuf - 1); |
| 3039 | } | 3051 | } |
| 3040 | if (nread > 0) | 3052 | if (0 < nread) |
| 3041 | { | 3053 | { |
| 3042 | procbuf[nread] = '\0'; | 3054 | procbuf[nread] = '\0'; |
| 3043 | p = procbuf; | 3055 | p = procbuf; |
| @@ -3164,12 +3176,12 @@ system_process_attributes (Lisp_Object pid) | |||
| 3164 | if (nread) | 3176 | if (nread) |
| 3165 | { | 3177 | { |
| 3166 | /* We don't want trailing null characters. */ | 3178 | /* We don't want trailing null characters. */ |
| 3167 | for (p = cmdline + nread; p > cmdline && !p[-1]; p--) | 3179 | for (p = cmdline + nread; cmdline < p && !p[-1]; p--) |
| 3168 | continue; | 3180 | continue; |
| 3169 | 3181 | ||
| 3170 | /* Escape-quote whitespace and backslashes. */ | 3182 | /* Escape-quote whitespace and backslashes. */ |
| 3171 | q = cmdline + cmdline_size; | 3183 | q = cmdline + cmdline_size; |
| 3172 | while (p > cmdline) | 3184 | while (cmdline < p) |
| 3173 | { | 3185 | { |
| 3174 | char c = *--p; | 3186 | char c = *--p; |
| 3175 | *--q = c ? c : ' '; | 3187 | *--q = c ? c : ' '; |