Bug Summary

File:s/cmd/digest/digest.c
Warning:line 148, column 22
Potential leak of memory pointed to by 'hashName'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name digest.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/var/lib/jenkins/workspace/nss-scan-build/nss/cmd/digest -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/var/lib/jenkins/workspace/nss-scan-build/nss/cmd/digest -resource-dir /usr/lib/llvm-18/lib/clang/18 -D HAVE_STRERROR -D LINUX -D linux -D XP_UNIX -D XP_UNIX -D NSPR20 -D DEBUG -U NDEBUG -D _DEFAULT_SOURCE -D _BSD_SOURCE -D _POSIX_SOURCE -D SDB_MEASURE_USE_TEMP_DIR -D _REENTRANT -D DEBUG -U NDEBUG -D _DEFAULT_SOURCE -D _BSD_SOURCE -D _POSIX_SOURCE -D SDB_MEASURE_USE_TEMP_DIR -D _REENTRANT -D NSS_DISABLE_SSE3 -D NSS_NO_INIT_SUPPORT -D USE_UTIL_DIRECTLY -D NO_NSPR_10_SUPPORT -D SSL_DISABLE_DEPRECATED_CIPHER_SUITE_NAMES -I ../../../dist/Linux4.19_x86_64_gcc_glibc_PTH_64_DBG.OBJ/include -I ../../../dist/public/nss -I ../../../dist/private/nss -I ../../../dist/public/seccmd -I ../../../dist/public/dbm -internal-isystem /usr/lib/llvm-18/lib/clang/18/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -std=c99 -ferror-limit 19 -fgnuc-version=4.2.1 -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2024-05-18-082241-28900-1 -x c digest.c
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
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5#include "secutil.h"
6#include "pk11func.h"
7#include "sechash.h"
8#include "secoid.h"
9
10#if defined(XP_WIN) || (defined(__sun) && !defined(SVR4))
11#if !defined(WIN32)
12extern int fread(char *, size_t, size_t, FILE *);
13extern int fwrite(char *, size_t, size_t, FILE *);
14extern int fprintf(FILE *, char *, ...);
15#endif
16#endif
17
18#include "plgetopt.h"
19
20static SECOidData *
21HashNameToOID(const char *hashName)
22{
23 HASH_HashType htype;
24 SECOidData *hashOID;
25
26 for (htype = HASH_AlgNULL + 1; htype < HASH_AlgTOTAL; htype++) {
27 hashOID = SECOID_FindOIDByTagSECOID_FindOIDByTag_Util(HASH_GetHashOidTagByHashType(htype));
28 if (PORT_StrcasecmpPL_strcasecmp(hashName, hashOID->desc) == 0)
29 break;
30 }
31
32 if (htype == HASH_AlgTOTAL)
33 return NULL((void*)0);
34
35 return hashOID;
36}
37
38static void
39Usage(char *progName)
40{
41 HASH_HashType htype;
42
43 fprintf(stderrstderr,
44 "Usage: %s -t type [-i input] [-o output]\n",
45 progName);
46 fprintf(stderrstderr, "%-20s Specify the digest method (must be one of\n",
47 "-t type");
48 fprintf(stderrstderr, "%-20s ", "");
49 for (htype = HASH_AlgNULL + 1; htype < HASH_AlgTOTAL; htype++) {
50 fputs(SECOID_FindOIDByTagSECOID_FindOIDByTag_Util(HASH_GetHashOidTagByHashType(htype))->desc,
51 stderrstderr);
52 if (htype == (HASH_AlgTOTAL - 2))
53 fprintf(stderrstderr, " or ");
54 else if (htype != (HASH_AlgTOTAL - 1))
55 fprintf(stderrstderr, ", ");
56 }
57 fprintf(stderrstderr, " (case ignored))\n");
58 fprintf(stderrstderr, "%-20s Define an input file to use (default is stdin)\n",
59 "-i input");
60 fprintf(stderrstderr, "%-20s Define an output file to use (default is stdout)\n",
61 "-o output");
62 exit(-1);
63}
64
65static int
66DigestFile(FILE *outFile, FILE *inFile, SECOidData *hashOID)
67{
68 int nb;
69 unsigned char ibuf[4096], digest[HASH_LENGTH_MAX64];
70 PK11Context *hashcx;
71 unsigned int len;
72 SECStatus rv;
73
74 hashcx = PK11_CreateDigestContext(hashOID->offset);
75 if (hashcx == NULL((void*)0)) {
76 return -1;
77 }
78 PK11_DigestBegin(hashcx);
79
80 for (;;) {
81 if (feof(inFile))
82 break;
83 nb = fread(ibuf, 1, sizeof(ibuf), inFile);
84 if (nb != sizeof(ibuf)) {
85 if (nb == 0) {
86 if (ferror(inFile)) {
87 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_IO);
88 PK11_DestroyContext(hashcx, PR_TRUE1);
89 return -1;
90 }
91 /* eof */
92 break;
93 }
94 }
95 rv = PK11_DigestOp(hashcx, ibuf, nb);
96 if (rv != SECSuccess) {
97 PK11_DestroyContext(hashcx, PR_TRUE1);
98 return -1;
99 }
100 }
101
102 rv = PK11_DigestFinal(hashcx, digest, &len, HASH_LENGTH_MAX64);
103 PK11_DestroyContext(hashcx, PR_TRUE1);
104
105 if (rv != SECSuccess)
106 return -1;
107
108 nb = fwrite(digest, 1, len, outFile);
109 if (nb != len) {
110 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_IO);
111 return -1;
112 }
113
114 return 0;
115}
116
117#include "nss.h"
118
119int
120main(int argc, char **argv)
121{
122 char *progName;
123 FILE *inFile, *outFile;
124 char *hashName;
125 SECOidData *hashOID;
126 PLOptState *optstate;
127 PLOptStatus status;
128 SECStatus rv;
129
130 progName = strrchr(argv[0], '/');
131 progName = progName ? progName + 1 : argv[0];
1
Assuming 'progName' is non-null
2
'?' condition is true
132
133 inFile = NULL((void*)0);
134 outFile = NULL((void*)0);
135 hashName = NULL((void*)0);
136
137 rv = NSS_Init("/tmp");
138 if (rv != SECSuccess) {
3
Assuming 'rv' is equal to SECSuccess
4
Taking false branch
139 fprintf(stderrstderr, "%s: NSS_Init failed in directory %s\n",
140 progName, "/tmp");
141 return -1;
142 }
143
144 /*
145 * Parse command line arguments
146 */
147 optstate = PL_CreateOptState(argc, argv, "t:i:o:");
148 while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
5
Assuming the condition is true
6
Loop condition is true. Entering loop body
9
Execution continues on line 148
10
Assuming the condition is true
11
Loop condition is true. Entering loop body
13
Execution continues on line 148
14
Potential leak of memory pointed to by 'hashName'
149 switch (optstate->option) {
7
Control jumps to 'case 116:' at line 172
12
Control jumps to 'case 116:' at line 172
150 case '?':
151 Usage(progName);
152 break;
153
154 case 'i':
155 inFile = fopen(optstate->value, "r");
156 if (!inFile) {
157 fprintf(stderrstderr, "%s: unable to open \"%s\" for reading\n",
158 progName, optstate->value);
159 return -1;
160 }
161 break;
162
163 case 'o':
164 outFile = fopen(optstate->value, "w");
165 if (!outFile) {
166 fprintf(stderrstderr, "%s: unable to open \"%s\" for writing\n",
167 progName, optstate->value);
168 return -1;
169 }
170 break;
171
172 case 't':
173 hashName = strdup(optstate->value);
8
Memory is allocated
174 break;
175 }
176 }
177
178 if (!hashName)
179 Usage(progName);
180
181 if (!inFile)
182 inFile = stdinstdin;
183 if (!outFile)
184 outFile = stdoutstdout;
185
186 hashOID = HashNameToOID(hashName);
187 free(hashName);
188 if (hashOID == NULL((void*)0)) {
189 fprintf(stderrstderr, "%s: invalid digest type\n", progName);
190 Usage(progName);
191 }
192
193 if (DigestFile(outFile, inFile, hashOID)) {
194 fprintf(stderrstderr, "%s: problem digesting data (%s)\n",
195 progName, SECU_Strerror(PORT_GetError())PR_ErrorToString((PORT_GetError_Util()), 0));
196 return -1;
197 }
198
199 if (NSS_Shutdown() != SECSuccess) {
200 exit(1);
201 }
202
203 return 0;
204}