| OLD | NEW |
| 1 /* This Source Code Form is subject to the terms of the Mozilla Public | 1 /* This Source Code Form is subject to the terms of the Mozilla Public |
| 2 * License, v. 2.0. If a copy of the MPL was not distributed with this | 2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
| 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
| 4 | 4 |
| 5 #include <stdio.h> | 5 #include <stdio.h> |
| 6 #include <string.h> | 6 #include <string.h> |
| 7 #include <signal.h> | 7 #include <signal.h> |
| 8 #include <unistd.h> | 8 #include <unistd.h> |
| 9 #include <limits.h> | 9 #include <limits.h> |
| 10 #include <errno.h> | 10 #include <errno.h> |
| (...skipping 952 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 963 } | 963 } |
| 964 #endif | 964 #endif |
| 965 | 965 |
| 966 } | 966 } |
| 967 | 967 |
| 968 #define TOTAL_FILE_LIMIT 1000000 /* one million */ | 968 #define TOTAL_FILE_LIMIT 1000000 /* one million */ |
| 969 | 969 |
| 970 size_t RNG_FileUpdate(const char *fileName, size_t limit) | 970 size_t RNG_FileUpdate(const char *fileName, size_t limit) |
| 971 { | 971 { |
| 972 FILE * file; | 972 FILE * file; |
| 973 size_t bytes; | 973 int fd; |
| 974 int bytes; |
| 974 size_t fileBytes = 0; | 975 size_t fileBytes = 0; |
| 975 struct stat stat_buf; | 976 struct stat stat_buf; |
| 976 unsigned char buffer[BUFSIZ]; | 977 unsigned char buffer[BUFSIZ]; |
| 977 static size_t totalFileBytes = 0; | 978 static size_t totalFileBytes = 0; |
| 978 | 979 |
| 979 /* suppress valgrind warnings due to holes in struct stat */ | 980 /* suppress valgrind warnings due to holes in struct stat */ |
| 980 memset(&stat_buf, 0, sizeof(stat_buf)); | 981 memset(&stat_buf, 0, sizeof(stat_buf)); |
| 981 | 982 |
| 982 if (stat((char *)fileName, &stat_buf) < 0) | 983 if (stat((char *)fileName, &stat_buf) < 0) |
| 983 return fileBytes; | 984 return fileBytes; |
| 984 RNG_RandomUpdate(&stat_buf, sizeof(stat_buf)); | 985 RNG_RandomUpdate(&stat_buf, sizeof(stat_buf)); |
| 985 | 986 |
| 986 file = fopen((char *)fileName, "r"); | 987 file = fopen(fileName, "r"); |
| 987 if (file != NULL) { | 988 if (file != NULL) { |
| 989 /* Read from the underlying file descriptor directly to bypass stdio |
| 990 * buffering and avoid reading more bytes than we need from |
| 991 * /dev/urandom. NOTE: we can't use fread with unbuffered I/O because |
| 992 * fread may return EOF in unbuffered I/O mode on Android. |
| 993 * |
| 994 * Moreover, we read into a buffer of size BUFSIZ, so buffered I/O |
| 995 * has no performance advantage. */ |
| 996 fd = fileno(file); |
| 997 /* 'file' was just opened, so this should not fail. */ |
| 998 PORT_Assert(fd != -1); |
| 988 while (limit > fileBytes) { | 999 while (limit > fileBytes) { |
| 989 bytes = PR_MIN(sizeof buffer, limit - fileBytes); | 1000 bytes = PR_MIN(sizeof buffer, limit - fileBytes); |
| 990 » bytes = fread(buffer, 1, bytes, file); | 1001 » bytes = read(fd, buffer, bytes); |
| 991 » if (bytes == 0) | 1002 » if (bytes <= 0) |
| 992 break; | 1003 break; |
| 993 RNG_RandomUpdate(buffer, bytes); | 1004 RNG_RandomUpdate(buffer, bytes); |
| 994 fileBytes += bytes; | 1005 fileBytes += bytes; |
| 995 totalFileBytes += bytes; | 1006 totalFileBytes += bytes; |
| 996 /* after TOTAL_FILE_LIMIT has been reached, only read in first | 1007 /* after TOTAL_FILE_LIMIT has been reached, only read in first |
| 997 ** buffer of data from each subsequent file. | 1008 ** buffer of data from each subsequent file. |
| 998 */ | 1009 */ |
| 999 if (totalFileBytes > TOTAL_FILE_LIMIT) | 1010 if (totalFileBytes > TOTAL_FILE_LIMIT) |
| 1000 break; | 1011 break; |
| 1001 } | 1012 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1013 void RNG_FileForRNG(const char *fileName) | 1024 void RNG_FileForRNG(const char *fileName) |
| 1014 { | 1025 { |
| 1015 RNG_FileUpdate(fileName, TOTAL_FILE_LIMIT); | 1026 RNG_FileUpdate(fileName, TOTAL_FILE_LIMIT); |
| 1016 } | 1027 } |
| 1017 | 1028 |
| 1018 void ReadSingleFile(const char *fileName) | 1029 void ReadSingleFile(const char *fileName) |
| 1019 { | 1030 { |
| 1020 FILE * file; | 1031 FILE * file; |
| 1021 unsigned char buffer[BUFSIZ]; | 1032 unsigned char buffer[BUFSIZ]; |
| 1022 | 1033 |
| 1023 file = fopen((char *)fileName, "rb"); | 1034 file = fopen(fileName, "rb"); |
| 1024 if (file != NULL) { | 1035 if (file != NULL) { |
| 1025 while (fread(buffer, 1, sizeof(buffer), file) > 0) | 1036 while (fread(buffer, 1, sizeof(buffer), file) > 0) |
| 1026 ; | 1037 ; |
| 1027 fclose(file); | 1038 fclose(file); |
| 1028 } | 1039 } |
| 1029 } | 1040 } |
| 1030 | 1041 |
| 1031 #define _POSIX_PTHREAD_SEMANTICS | 1042 #define _POSIX_PTHREAD_SEMANTICS |
| 1032 #include <dirent.h> | 1043 #include <dirent.h> |
| 1033 | 1044 |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1135 } | 1146 } |
| 1136 | 1147 |
| 1137 /* | 1148 /* |
| 1138 * Modified to abort the process if it failed to read from /dev/urandom. | 1149 * Modified to abort the process if it failed to read from /dev/urandom. |
| 1139 * | 1150 * |
| 1140 * See crbug.com/244661 for details. | 1151 * See crbug.com/244661 for details. |
| 1141 */ | 1152 */ |
| 1142 size_t RNG_SystemRNG(void *dest, size_t maxLen) | 1153 size_t RNG_SystemRNG(void *dest, size_t maxLen) |
| 1143 { | 1154 { |
| 1144 FILE *file; | 1155 FILE *file; |
| 1145 size_t bytes; | 1156 int fd; |
| 1157 int bytes; |
| 1146 size_t fileBytes = 0; | 1158 size_t fileBytes = 0; |
| 1147 unsigned char *buffer = dest; | 1159 unsigned char *buffer = dest; |
| 1148 | 1160 |
| 1149 file = fopen("/dev/urandom", "r"); | 1161 file = fopen("/dev/urandom", "r"); |
| 1150 if (file == NULL) { | 1162 if (file == NULL) { |
| 1151 fprintf(stderr, "[ERROR:%s(%d)] NSS failed to read from /dev/urandom. " | 1163 fprintf(stderr, "[ERROR:%s(%d)] NSS failed to read from /dev/urandom. " |
| 1152 "Abort process.\n", __FILE__, __LINE__); | 1164 "Abort process.\n", __FILE__, __LINE__); |
| 1153 fflush(stderr); | 1165 fflush(stderr); |
| 1154 abort(); | 1166 abort(); |
| 1155 } | 1167 } |
| 1168 /* Read from the underlying file descriptor directly to bypass stdio |
| 1169 * buffering and avoid reading more bytes than we need from /dev/urandom. |
| 1170 * NOTE: we can't use fread with unbuffered I/O because fread may return |
| 1171 * EOF in unbuffered I/O mode on Android. |
| 1172 */ |
| 1173 fd = fileno(file); |
| 1174 /* 'file' was just opened, so this should not fail. */ |
| 1175 PORT_Assert(fd != -1); |
| 1156 while (maxLen > fileBytes) { | 1176 while (maxLen > fileBytes) { |
| 1157 bytes = maxLen - fileBytes; | 1177 bytes = maxLen - fileBytes; |
| 1158 » bytes = fread(buffer, 1, bytes, file); | 1178 » bytes = read(fd, buffer, bytes); |
| 1159 » if (bytes == 0) | 1179 » if (bytes <= 0) |
| 1160 break; | 1180 break; |
| 1161 fileBytes += bytes; | 1181 fileBytes += bytes; |
| 1162 buffer += bytes; | 1182 buffer += bytes; |
| 1163 } | 1183 } |
| 1164 fclose(file); | 1184 fclose(file); |
| 1165 if (fileBytes != maxLen) { | 1185 if (fileBytes != maxLen) { |
| 1166 fprintf(stderr, "[ERROR:%s(%d)] NSS failed to read from /dev/urandom. " | 1186 fprintf(stderr, "[ERROR:%s(%d)] NSS failed to read from /dev/urandom. " |
| 1167 "Abort process.\n", __FILE__, __LINE__); | 1187 "Abort process.\n", __FILE__, __LINE__); |
| 1168 fflush(stderr); | 1188 fflush(stderr); |
| 1169 abort(); | 1189 abort(); |
| 1170 } | 1190 } |
| 1171 return fileBytes; | 1191 return fileBytes; |
| 1172 } | 1192 } |
| OLD | NEW |