View | Details | Raw Unified | Return to bug 1025084
Collapse All | Expand All

(-)xserver/configure.ac (-2 / +2 lines)
Lines 132-138 AM_CONDITIONAL(SPECIAL_DTRACE_OBJECTS, [ Link Here
132
AC_HEADER_DIRENT
132
AC_HEADER_DIRENT
133
AC_HEADER_STDC
133
AC_HEADER_STDC
134
AC_CHECK_HEADERS([fcntl.h stdlib.h string.h unistd.h dlfcn.h stropts.h \
134
AC_CHECK_HEADERS([fcntl.h stdlib.h string.h unistd.h dlfcn.h stropts.h \
135
 fnmatch.h sys/mkdev.h sys/sysmacros.h sys/utsname.h])
135
 fnmatch.h sys/mkdev.h sys/sysmacros.h sys/utsname.h sys/syscall.h])
136
136
137
dnl Checks for typedefs, structures, and compiler characteristics.
137
dnl Checks for typedefs, structures, and compiler characteristics.
138
AC_C_CONST
138
AC_C_CONST
Lines 164-170 AC_REPLACE_FUNCS([reallocarray strcasecm Link Here
164
AM_CONDITIONAL(POLL, [test "x$ac_cv_func_poll" = "xyes"])
164
AM_CONDITIONAL(POLL, [test "x$ac_cv_func_poll" = "xyes"])
165
165
166
AC_CHECK_LIB([bsd], [arc4random_buf])
166
AC_CHECK_LIB([bsd], [arc4random_buf])
167
AC_CHECK_FUNCS([arc4random_buf])
167
AC_CHECK_FUNCS([arc4random_buf getentropy])
168
168
169
AC_CHECK_DECLS([program_invocation_short_name], [], [], [[#include <errno.h>]])
169
AC_CHECK_DECLS([program_invocation_short_name], [], [], [[#include <errno.h>]])
170
170
(-)xserver/include/dix-config.h.in (+6 lines)
Lines 164-169 Link Here
164
/* Define to 1 if you have the `arc4random_buf' function. */
164
/* Define to 1 if you have the `arc4random_buf' function. */
165
#undef HAVE_ARC4RANDOM_BUF
165
#undef HAVE_ARC4RANDOM_BUF
166
166
167
/* Define to 1 if you have the `getentropy' function. */
168
#undef HAVE_GETENTROPY
169
167
/* Define to use libc SHA1 functions */
170
/* Define to use libc SHA1 functions */
168
#undef HAVE_SHA1_IN_LIBC
171
#undef HAVE_SHA1_IN_LIBC
169
172
Lines 241-246 Link Here
241
/* Define to 1 if you have the <sys/utsname.h> header file. */
244
/* Define to 1 if you have the <sys/utsname.h> header file. */
242
#undef HAVE_SYS_UTSNAME_H
245
#undef HAVE_SYS_UTSNAME_H
243
246
247
/* Define to 1 if you have the <sys/syscall.h> header file. */
248
#undef HAVE_SYS_SYSCALL_H
249
244
/* Define to 1 if you have the `timingsafe_memcmp' function. */
250
/* Define to 1 if you have the `timingsafe_memcmp' function. */
245
#undef HAVE_TIMINGSAFE_MEMCMP
251
#undef HAVE_TIMINGSAFE_MEMCMP
246
252
(-)xserver/os/auth.c (-5 / +127 lines)
Lines 48-53 from The Open Group. Link Here
48
#ifdef HAVE_LIBBSD
48
#ifdef HAVE_LIBBSD
49
#include   <bsd/stdlib.h>       /* for arc4random_buf() */
49
#include   <bsd/stdlib.h>       /* for arc4random_buf() */
50
#endif
50
#endif
51
#include   <errno.h>
52
#ifdef HAVE_SYS_SYSCALL_H
53
#include   <syscall.h>
54
#endif
51
55
52
struct protocol {
56
struct protocol {
53
    unsigned short name_length;
57
    unsigned short name_length;
Lines 302-319 GenerateAuthorization(unsigned name_leng Link Here
302
    return -1;
306
    return -1;
303
}
307
}
304
308
309
#if ! defined(HAVE_ARC4RANDOM_BUF)
310
311
// fallback function to get random data directly from /dev/urandom
312
313
static int
314
GetUrandom ( char *buffer, size_t length )
315
{
316
    int random_fd = -1;
317
    int res = -1;
318
    size_t filled = 0;
319
320
    // larger requests are typically rejected by getentropy() / getrandom()
321
    // because they could block or return partially filled buffers
322
    if( length > 256 ) {
323
        errno = EIO;
324
        return -1;
325
    }
326
327
    random_fd = open("/dev/urandom", O_RDONLY | O_CLOEXEC);
328
329
    if( random_fd == -1 ) {
330
        return -1;
331
    }
332
333
    while( filled < length ) {
334
        res = read(random_fd, (char*)buffer + filled, length - filled);
335
336
        if( res == -1 ) {
337
            // shouldn't actually happen acc. to man(4) random,
338
            // but you never know
339
            if( errno == EINTR ) {
340
                continue;
341
            }
342
343
            return -1;
344
        }
345
        else if( res == 0 ) {
346
            // no more bytes available? should not happen
347
            errno = EIO;
348
            return -1;
349
        }
350
351
        filled += res;
352
    }
353
354
    return 0;
355
}
356
357
#endif // ! defined(HAVE_ARC4RANDOM_BUF)
358
359
#if !defined(HAVE_GETENTROPY) && defined(HAVE_SYS_SYSCALL_H) && defined(SYS_getrandom)
360
#    define TRY_GETRANDOM
361
#endif
362
363
#ifdef TRY_GETRANDOM
364
365
/*
366
 * wrapper for the getrandom() syscall which was for a long time implemented
367
 * in the Linux kernel, but not wrapped in glibc
368
 */
369
static int
370
GetRandom ( char *buffer, size_t length )
371
{
372
    int res;
373
    size_t filled = 0;
374
375
    // larger requests are typically rejected by getentropy() / getrandom()
376
    // because they could block or return partially filled buffers
377
    if( length > 256 )
378
    {
379
        errno = EIO;
380
        return -1;
381
    }
382
383
    while( filled < length )
384
    {
385
        /*
386
         * glibc does not contain a syscall wrapper for this in older
387
         * versions
388
         */
389
        res = syscall(SYS_getrandom, (char*)buffer + filled, length - filled, 0);
390
391
        if( res == -1 )
392
        {
393
            if( errno == EINTR ) {
394
                continue;
395
            }
396
397
            return -1;
398
        }
399
        else if( res == 0 )
400
        {
401
            // no more bytes available? should not happen
402
            errno = EIO;
403
            return -1;
404
        }
405
406
        filled += res;
407
    }
408
409
    return 0;
410
}
411
412
#endif /* TRY_GETRANDOM */
413
305
void
414
void
306
GenerateRandomData(int len, char *buf)
415
GenerateRandomData(int len, char *buf)
307
{
416
{
308
#ifdef HAVE_ARC4RANDOM_BUF
417
#ifdef HAVE_ARC4RANDOM_BUF
309
    arc4random_buf(buf, len);
418
    arc4random_buf(buf, len);
310
#else
419
#else
311
    int fd;
420
    int ret = -1;
421
#   ifdef HAVE_GETENTROPY
422
    /* use getentropy instead */
423
    ret = getentropy (auth, len);
424
#   elif defined(TRY_GETRANDOM)
425
    /* try getrandom() wrapper */
426
    ret = GetRandom(buf, len);
427
#   endif
428
429
    if( ret == -1 ) {
430
        // fallback to manual reading of /dev/urandom
431
        ret = GetUrandom(buf, len);
432
    }
312
433
313
    fd = open("/dev/urandom", O_RDONLY);
434
    if( ret == -1 ) {
314
    read(fd, buf, len);
435
        // no error return possible, rather abort than have security problems
315
    close(fd);
436
        OsAbort();
316
#endif
437
    }
438
#endif // HAVE_ARC4RANDOM_BUF
317
}
439
}
318
440
319
#endif                          /* XCSECURITY */
441
#endif                          /* XCSECURITY */

Return to bug 1025084