OpenCoverage

randread.c

Absolute File Name:/home/opencoverage/opencoverage/guest-scripts/coreutils/src/gl/lib/randread.c
Source codeSwitch to Preprocessed file
LineSourceCount
1/* Generate buffers of random data.-
2-
3 Copyright (C) 2006-2018 Free Software Foundation, Inc.-
4-
5 This program is free software: you can redistribute it and/or modify-
6 it under the terms of the GNU General Public License as published by-
7 the Free Software Foundation, either version 3 of the License, or-
8 (at your option) any later version.-
9-
10 This program is distributed in the hope that it will be useful,-
11 but WITHOUT ANY WARRANTY; without even the implied warranty of-
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the-
13 GNU General Public License for more details.-
14-
15 You should have received a copy of the GNU General Public License-
16 along with this program. If not, see <https://www.gnu.org/licenses/>. */-
17-
18/* Written by Paul Eggert. */-
19-
20/* FIXME: Improve performance by adding support for the RDRAND machine-
21 instruction if available (e.g., Ivy Bridge processors). */-
22-
23#include <config.h>-
24-
25#include "randread.h"-
26-
27#include <errno.h>-
28#include <error.h>-
29#include <exitfail.h>-
30#include <fcntl.h>-
31#include <quote.h>-
32#include <stdalign.h>-
33#include <stdbool.h>-
34#include <stdint.h>-
35#include <stdio.h>-
36#include <stdlib.h>-
37#include <string.h>-
38#include <sys/time.h>-
39#include <unistd.h>-
40-
41#include "gettext.h"-
42#define _(msgid) gettext (msgid)-
43-
44#include "rand-isaac.h"-
45#include "stdio-safer.h"-
46#include "unlocked-io.h"-
47#include "xalloc.h"-
48-
49#ifndef __attribute__-
50# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8)-
51# define __attribute__(x) /* empty */-
52# endif-
53#endif-
54-
55#ifndef ATTRIBUTE_NORETURN-
56# define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__))-
57#endif-
58-
59#ifndef MIN-
60# define MIN(a, b) ((a) < (b) ? (a) : (b))-
61#endif-
62-
63#if _STRING_ARCH_unaligned || _STRING_INLINE_unaligned-
64# define ALIGNED_POINTER(ptr, type) true-
65#else-
66# define ALIGNED_POINTER(ptr, type) ((size_t) (ptr) % alignof (type) == 0)-
67#endif-
68-
69#ifndef NAME_OF_NONCE_DEVICE-
70# define NAME_OF_NONCE_DEVICE "/dev/urandom"-
71#endif-
72-
73/* The maximum buffer size used for reads of random data. Using the-
74 value 2 * ISAAC_BYTES makes this the largest power of two that-
75 would not otherwise cause struct randread_source to grow. */-
76#define RANDREAD_BUFFER_SIZE (2 * ISAAC_BYTES)-
77-
78/* A source of random data for generating random buffers. */-
79struct randread_source-
80{-
81 /* Stream to read random bytes from. If null, the current-
82 implementation uses an internal PRNG (ISAAC). */-
83 FILE *source;-
84-
85 /* Function to call, and its argument, if there is an input error or-
86 end of file when reading from the stream; errno is nonzero if-
87 there was an error. If this function returns, it should fix the-
88 problem before returning. The default handler assumes that-
89 handler_arg is the file name of the source. */-
90 void (*handler) (void const *);-
91 void const *handler_arg;-
92-
93 /* The buffer for SOURCE. It's kept here to simplify storage-
94 allocation and to make it easier to clear out buffered random-
95 data. */-
96 union-
97 {-
98 /* The stream buffer, if SOURCE is not null. */-
99 char c[RANDREAD_BUFFER_SIZE];-
100-
101 /* The buffered ISAAC pseudorandom buffer, if SOURCE is null. */-
102 struct isaac-
103 {-
104 /* The number of bytes that are buffered at the end of data.b. */-
105 size_t buffered;-
106-
107 /* State of the ISAAC generator. */-
108 struct isaac_state state;-
109-
110 /* Up to a buffer's worth of pseudorandom data. */-
111 union-
112 {-
113 isaac_word w[ISAAC_WORDS];-
114 unsigned char b[ISAAC_BYTES];-
115 } data;-
116 } isaac;-
117 } buf;-
118};-
119-
120-
121/* The default error handler. */-
122-
123static void ATTRIBUTE_NORETURN-
124randread_error (void const *file_name)-
125{-
126 if (file_name)
file_nameDescription
TRUEnever evaluated
FALSEnever evaluated
0
127 error (exit_failure, errno,
never executed: error (exit_failure, (*__errno_location ()) , (*__errno_location ()) == 0 ? dcgettext (((void *)0), "%s: end of file" , 5) : dcgettext (((void *)0), "%s: read error" , 5) , quote (file_name));
0
128 errno == 0 ? _("%s: end of file") : _("%s: read error"),
never executed: error (exit_failure, (*__errno_location ()) , (*__errno_location ()) == 0 ? dcgettext (((void *)0), "%s: end of file" , 5) : dcgettext (((void *)0), "%s: read error" , 5) , quote (file_name));
0
129 quote (file_name));
never executed: error (exit_failure, (*__errno_location ()) , (*__errno_location ()) == 0 ? dcgettext (((void *)0), "%s: end of file" , 5) : dcgettext (((void *)0), "%s: read error" , 5) , quote (file_name));
0
130 abort ();
never executed: abort ();
0
131}-
132-
133/* Simply return a new randread_source object with the default error-
134 handler. */-
135-
136static struct randread_source *-
137simple_new (FILE *source, void const *handler_arg)-
138{-
139 struct randread_source *s = xmalloc (sizeof *s);-
140 s->source = source;-
141 s->handler = randread_error;-
142 s->handler_arg = handler_arg;-
143 return s;
executed 655 times by 7 tests: return s;
Executed by:
  • cp
  • ln
  • mktemp
  • mv
  • shred
  • shuf
  • sort
655
144}-
145-
146/* Put a nonce value into BUFFER, with size BUFSIZE, but do not get-
147 more than BYTES_BOUND bytes' worth of random information from any-
148 nonce device. */-
149-
150static void-
151get_nonce (void *buffer, size_t bufsize, size_t bytes_bound)-
152{-
153 char *buf = buffer;-
154 ssize_t seeded = 0;-
155-
156 /* Get some data from FD if available. */-
157 int fd = open (NAME_OF_NONCE_DEVICE, O_RDONLY | O_BINARY);-
158 if (0 <= fd)
0 <= fdDescription
TRUEevaluated 649 times by 7 tests
Evaluated by:
  • cp
  • ln
  • mktemp
  • mv
  • shred
  • shuf
  • sort
FALSEnever evaluated
0-649
159 {-
160 seeded = read (fd, buf, MIN (bufsize, bytes_bound));-
161 if (seeded < 0)
seeded < 0Description
TRUEnever evaluated
FALSEevaluated 649 times by 7 tests
Evaluated by:
  • cp
  • ln
  • mktemp
  • mv
  • shred
  • shuf
  • sort
0-649
162 seeded = 0;
never executed: seeded = 0;
0
163 close (fd);-
164 }
executed 649 times by 7 tests: end of block
Executed by:
  • cp
  • ln
  • mktemp
  • mv
  • shred
  • shuf
  • sort
649
165-
166 /* If there's no nonce device, use a poor approximation-
167 by getting the time of day, etc. */-
168#define ISAAC_SEED(type, initialize_v) \-
169 if (seeded < bufsize) \-
170 { \-
171 type v; \-
172 size_t nbytes = MIN (sizeof v, bufsize - seeded); \-
173 initialize_v; \-
174 memcpy (buf + seeded, &v, nbytes); \-
175 seeded += nbytes; \-
176 }-
177 ISAAC_SEED (struct timeval, gettimeofday (&v, NULL));
executed 618 times by 6 tests: end of block
Executed by:
  • cp
  • ln
  • mktemp
  • mv
  • shuf
  • sort
seeded < bufsizeDescription
TRUEevaluated 618 times by 6 tests
Evaluated by:
  • cp
  • ln
  • mktemp
  • mv
  • shuf
  • sort
FALSEevaluated 31 times by 2 tests
Evaluated by:
  • shred
  • shuf
(sizeof v) < (...size - seeded)Description
TRUEevaluated 618 times by 6 tests
Evaluated by:
  • cp
  • ln
  • mktemp
  • mv
  • shuf
  • sort
FALSEnever evaluated
0-618
178 ISAAC_SEED (pid_t, v = getpid ());
executed 618 times by 6 tests: end of block
Executed by:
  • cp
  • ln
  • mktemp
  • mv
  • shuf
  • sort
seeded < bufsizeDescription
TRUEevaluated 618 times by 6 tests
Evaluated by:
  • cp
  • ln
  • mktemp
  • mv
  • shuf
  • sort
FALSEevaluated 31 times by 2 tests
Evaluated by:
  • shred
  • shuf
(sizeof v) < (...size - seeded)Description
TRUEevaluated 618 times by 6 tests
Evaluated by:
  • cp
  • ln
  • mktemp
  • mv
  • shuf
  • sort
FALSEnever evaluated
0-618
179 ISAAC_SEED (pid_t, v = getppid ());
executed 618 times by 6 tests: end of block
Executed by:
  • cp
  • ln
  • mktemp
  • mv
  • shuf
  • sort
seeded < bufsizeDescription
TRUEevaluated 618 times by 6 tests
Evaluated by:
  • cp
  • ln
  • mktemp
  • mv
  • shuf
  • sort
FALSEevaluated 31 times by 2 tests
Evaluated by:
  • shred
  • shuf
(sizeof v) < (...size - seeded)Description
TRUEevaluated 618 times by 6 tests
Evaluated by:
  • cp
  • ln
  • mktemp
  • mv
  • shuf
  • sort
FALSEnever evaluated
0-618
180 ISAAC_SEED (uid_t, v = getuid ());
executed 618 times by 6 tests: end of block
Executed by:
  • cp
  • ln
  • mktemp
  • mv
  • shuf
  • sort
seeded < bufsizeDescription
TRUEevaluated 618 times by 6 tests
Evaluated by:
  • cp
  • ln
  • mktemp
  • mv
  • shuf
  • sort
FALSEevaluated 31 times by 2 tests
Evaluated by:
  • shred
  • shuf
(sizeof v) < (...size - seeded)Description
TRUEevaluated 618 times by 6 tests
Evaluated by:
  • cp
  • ln
  • mktemp
  • mv
  • shuf
  • sort
FALSEnever evaluated
0-618
181 ISAAC_SEED (uid_t, v = getgid ());
executed 618 times by 6 tests: end of block
Executed by:
  • cp
  • ln
  • mktemp
  • mv
  • shuf
  • sort
seeded < bufsizeDescription
TRUEevaluated 618 times by 6 tests
Evaluated by:
  • cp
  • ln
  • mktemp
  • mv
  • shuf
  • sort
FALSEevaluated 31 times by 2 tests
Evaluated by:
  • shred
  • shuf
(sizeof v) < (...size - seeded)Description
TRUEevaluated 618 times by 6 tests
Evaluated by:
  • cp
  • ln
  • mktemp
  • mv
  • shuf
  • sort
FALSEnever evaluated
0-618
182-
183#ifdef lint-
184 /* Normally we like having the extra randomness from uninitialized-
185 parts of BUFFER. However, omit this randomness if we want to-
186 avoid false-positives from memory-checking debugging tools. */-
187 memset (buf + seeded, 0, bufsize - seeded);-
188#endif-
189}
executed 649 times by 7 tests: end of block
Executed by:
  • cp
  • ln
  • mktemp
  • mv
  • shred
  • shuf
  • sort
649
190-
191-
192/* Create and initialize a random data source from NAME, or use a-
193 reasonable default source if NAME is null. BYTES_BOUND is an upper-
194 bound on the number of bytes that will be needed. If zero, it is a-
195 hard bound; otherwise it is just an estimate.-
196-
197 If NAME is not null, NAME is saved for use as the argument of the-
198 default handler. Unless a non-default handler is used, NAME's-
199 lifetime should be at least that of the returned value.-
200-
201 Return NULL (setting errno) on failure. */-
202-
203struct randread_source *-
204randread_new (char const *name, size_t bytes_bound)-
205{-
206 if (bytes_bound == 0)
bytes_bound == 0Description
TRUEevaluated 4 times by 1 test
Evaluated by:
  • shuf
FALSEevaluated 651 times by 7 tests
Evaluated by:
  • cp
  • ln
  • mktemp
  • mv
  • shred
  • shuf
  • sort
4-651
207 return simple_new (NULL, NULL);
executed 4 times by 1 test: return simple_new ( ((void *)0) , ((void *)0) );
Executed by:
  • shuf
4
208 else-
209 {-
210 FILE *source = NULL;-
211 struct randread_source *s;-
212-
213 if (name)
nameDescription
TRUEevaluated 2 times by 2 tests
Evaluated by:
  • shred
  • sort
FALSEevaluated 649 times by 7 tests
Evaluated by:
  • cp
  • ln
  • mktemp
  • mv
  • shred
  • shuf
  • sort
2-649
214 if (! (source = fopen_safer (name, "rb")))
! (source = fo... (name, "rb"))Description
TRUEnever evaluated
FALSEevaluated 2 times by 2 tests
Evaluated by:
  • shred
  • sort
0-2
215 return NULL;
never executed: return ((void *)0) ;
0
216-
217 s = simple_new (source, name);-
218-
219 if (source)
sourceDescription
TRUEevaluated 2 times by 2 tests
Evaluated by:
  • shred
  • sort
FALSEevaluated 649 times by 7 tests
Evaluated by:
  • cp
  • ln
  • mktemp
  • mv
  • shred
  • shuf
  • sort
2-649
220 setvbuf (source, s->buf.c, _IOFBF, MIN (sizeof s->buf.c, bytes_bound));
executed 2 times by 2 tests: setvbuf (source, s->buf.c, 0 , ((sizeof s->buf.c) < (bytes_bound) ? (sizeof s->buf.c) : (bytes_bound)));
Executed by:
  • shred
  • sort
2
221 else-
222 {-
223 s->buf.isaac.buffered = 0;-
224 get_nonce (s->buf.isaac.state.m, sizeof s->buf.isaac.state.m,-
225 bytes_bound);-
226 isaac_seed (&s->buf.isaac.state);-
227 }
executed 649 times by 7 tests: end of block
Executed by:
  • cp
  • ln
  • mktemp
  • mv
  • shred
  • shuf
  • sort
649
228-
229 return s;
executed 651 times by 7 tests: return s;
Executed by:
  • cp
  • ln
  • mktemp
  • mv
  • shred
  • shuf
  • sort
651
230 }-
231}-
232-
233-
234/* Set S's handler and its argument. HANDLER (HANDLER_ARG) is called-
235 when there is a read error or end of file from the random data-
236 source; errno is nonzero if there was an error. If HANDLER-
237 returns, it should fix the problem before returning. The default-
238 handler assumes that handler_arg is the file name of the source; it-
239 does not return. */-
240-
241void-
242randread_set_handler (struct randread_source *s, void (*handler) (void const *))-
243{-
244 s->handler = handler;-
245}
never executed: end of block
0
246-
247void-
248randread_set_handler_arg (struct randread_source *s, void const *handler_arg)-
249{-
250 s->handler_arg = handler_arg;-
251}
never executed: end of block
0
252-
253-
254/* Place SIZE random bytes into the buffer beginning at P, using-
255 the stream in S. */-
256-
257static void-
258readsource (struct randread_source *s, unsigned char *p, size_t size)-
259{-
260 while (true)-
261 {-
262 size_t inbytes = fread (p, sizeof *p, size, s->source);-
263 int fread_errno = errno;-
264 p += inbytes;-
265 size -= inbytes;-
266 if (size == 0)
size == 0Description
TRUEevaluated 18 times by 2 tests
Evaluated by:
  • shred
  • sort
FALSEnever evaluated
0-18
267 break;
executed 18 times by 2 tests: break;
Executed by:
  • shred
  • sort
18
268 errno = (ferror (s->source) ? fread_errno : 0);-
269 s->handler (s->handler_arg);-
270 }
never executed: end of block
0
271}
executed 18 times by 2 tests: end of block
Executed by:
  • shred
  • sort
18
272-
273-
274/* Place SIZE pseudorandom bytes into the buffer beginning at P, using-
275 the buffered ISAAC generator in ISAAC. */-
276-
277static void-
278readisaac (struct isaac *isaac, void *p, size_t size)-
279{-
280 size_t inbytes = isaac->buffered;-
281-
282 while (true)-
283 {-
284 char *char_p = p;-
285-
286 if (size <= inbytes)
size <= inbytesDescription
TRUEevaluated 6236 times by 7 tests
Evaluated by:
  • cp
  • ln
  • mktemp
  • mv
  • shred
  • shuf
  • sort
FALSEevaluated 685 times by 7 tests
Evaluated by:
  • cp
  • ln
  • mktemp
  • mv
  • shred
  • shuf
  • sort
685-6236
287 {-
288 memcpy (p, isaac->data.b + ISAAC_BYTES - inbytes, size);-
289 isaac->buffered = inbytes - size;-
290 return;
executed 6236 times by 7 tests: return;
Executed by:
  • cp
  • ln
  • mktemp
  • mv
  • shred
  • shuf
  • sort
6236
291 }-
292-
293 memcpy (p, isaac->data.b + ISAAC_BYTES - inbytes, inbytes);-
294 p = char_p + inbytes;-
295 size -= inbytes;-
296-
297 /* If P is aligned, write to *P directly to avoid the overhead-
298 of copying from the buffer. */-
299 if (ALIGNED_POINTER (p, isaac_word))-
300 {-
301 isaac_word *wp = p;-
302 while (ISAAC_BYTES <= size)
((1 << 8) * si...word)) <= sizeDescription
TRUEevaluated 1023 times by 1 test
Evaluated by:
  • shred
FALSEevaluated 669 times by 7 tests
Evaluated by:
  • cp
  • ln
  • mktemp
  • mv
  • shred
  • shuf
  • sort
669-1023
303 {-
304 isaac_refill (&isaac->state, wp);-
305 wp += ISAAC_WORDS;-
306 size -= ISAAC_BYTES;-
307 if (size == 0)
size == 0Description
TRUEevaluated 16 times by 1 test
Evaluated by:
  • shred
FALSEevaluated 1007 times by 1 test
Evaluated by:
  • shred
16-1007
308 {-
309 isaac->buffered = 0;-
310 return;
executed 16 times by 1 test: return;
Executed by:
  • shred
16
311 }-
312 }
executed 1007 times by 1 test: end of block
Executed by:
  • shred
1007
313 p = wp;-
314 }
executed 669 times by 7 tests: end of block
Executed by:
  • cp
  • ln
  • mktemp
  • mv
  • shred
  • shuf
  • sort
669
315-
316 isaac_refill (&isaac->state, isaac->data.w);-
317 inbytes = ISAAC_BYTES;-
318 }
executed 669 times by 7 tests: end of block
Executed by:
  • cp
  • ln
  • mktemp
  • mv
  • shred
  • shuf
  • sort
669
319}
never executed: end of block
0
320-
321-
322/* Consume random data from *S to generate a random buffer BUF of size-
323 SIZE. */-
324-
325void-
326randread (struct randread_source *s, void *buf, size_t size)-
327{-
328 if (s->source)
s->sourceDescription
TRUEevaluated 18 times by 2 tests
Evaluated by:
  • shred
  • sort
FALSEevaluated 6252 times by 7 tests
Evaluated by:
  • cp
  • ln
  • mktemp
  • mv
  • shred
  • shuf
  • sort
18-6252
329 readsource (s, buf, size);
executed 18 times by 2 tests: readsource (s, buf, size);
Executed by:
  • shred
  • sort
18
330 else-
331 readisaac (&s->buf.isaac, buf, size);
executed 6252 times by 7 tests: readisaac (&s->buf.isaac, buf, size);
Executed by:
  • cp
  • ln
  • mktemp
  • mv
  • shred
  • shuf
  • sort
6252
332}-
333-
334-
335/* Clear *S so that it no longer contains undelivered random data, and-
336 deallocate any system resources associated with *S. Return 0 if-
337 successful, a negative number (setting errno) if not (this is rare,-
338 but can occur in theory if there is an input error). */-
339-
340int-
341randread_free (struct randread_source *s)-
342{-
343 FILE *source = s->source;-
344 explicit_bzero (s, sizeof *s);-
345 free (s);-
346 return (source ? fclose (source) : 0);
executed 635 times by 6 tests: return (source ? rpl_fclose (source) : 0);
Executed by:
  • cp
  • ln
  • mktemp
  • mv
  • shred
  • sort
635
347}-
Source codeSwitch to Preprocessed file

Generated by Squish Coco 4.1.2