1 /* Copyright 2020 Google Inc.
2
3 Licensed under the Apache License, Version 2.0 (the "License");
4 you may not use this file except in compliance with the License.
5 You may obtain a copy of the License at
6
7 http://www.apache.org/licenses/LICENSE-2.0
8
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations under the License.
14 */
15
16 #include <stdint.h>
17 #include <stddef.h>
18 #include <stdlib.h>
19 #include <stdio.h>
20 #include <stdbool.h>
21 #include <ftw.h>
22
23 #define INCLUDED_BY_MAIN_MODULE 1
24 #include "config.h"
25 #include "gpg.h"
26 #include "../common/types.h"
27 #include "../common/iobuf.h"
28 #include "keydb.h"
29 #include "keyedit.h"
30 #include "../common/util.h"
31 #include "main.h"
32 #include "call-dirmngr.h"
33 #include "trustdb.h"
34
35 #include <sys/stat.h>
36 #include <fcntl.h>
37 #include <sys/types.h>
38 #include <unistd.h>
39 #include <sys/mount.h>
40
41 static bool initialized = false;
42 ctrl_t ctrlGlobal;
43 int fd;
44 char *filename;
45
46 //hack not to include gpg.c which has main function
47 int g10_errors_seen = 0;
48
49 void
g10_exit(int rc)50 g10_exit( int rc )
51 {
52 gcry_control (GCRYCTL_UPDATE_RANDOM_SEED_FILE);
53 gcry_control (GCRYCTL_TERM_SECMEM );
54 exit (rc);
55 }
56
57 static void
gpg_deinit_default_ctrl(ctrl_t ctrl)58 gpg_deinit_default_ctrl (ctrl_t ctrl)
59 {
60 #ifdef USE_TOFU
61 tofu_closedbs (ctrl);
62 #endif
63 gpg_dirmngr_deinit_session_data (ctrl);
64
65 keydb_release (ctrl->cached_getkey_kdb);
66 }
67
68 static void
my_gcry_logger(void * dummy,int level,const char * format,va_list arg_ptr)69 my_gcry_logger (void *dummy, int level, const char *format, va_list arg_ptr)
70 {
71 return;
72 }
73
unlink_cb(const char * fpath,const struct stat * sb,int typeflag)74 static int unlink_cb(const char *fpath, const struct stat *sb, int typeflag)
75 {
76 if (typeflag == FTW_F){
77 unlink(fpath);
78 }
79 return 0;
80 }
81
rmrfdir(char * path)82 static void rmrfdir(char *path)
83 {
84 ftw(path, unlink_cb, 16);
85 if (rmdir(path) != 0) {
86 printf("failed rmdir, errno=%d\n", errno);
87 }
88 }
89
LLVMFuzzerTestOneInput(const uint8_t * Data,size_t Size)90 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
91
92 if (! initialized) {
93 ctrlGlobal = (ctrl_t) malloc(sizeof(*ctrlGlobal));
94 if (!ctrlGlobal) {
95 exit(1);
96 }
97 //deletes previous tmp dir and (re)create it as a ramfs
98 //system("umount /tmp/fuzzdirverify");
99 rmrfdir("/tmp/fuzzdirverify");
100 mkdir("/tmp/fuzzdirverify/", 0700);
101 //system("mount -t tmpfs -o size=64M tmpfs /tmp/fuzzdirverify");
102 filename=strdup("/tmp/fuzzdirverify/fuzz.gpg");
103 if (!filename) {
104 free(ctrlGlobal);
105 return 0;
106 }
107 fd = open("/tmp/fuzzdirverify/fuzz.gpg", O_RDWR | O_CREAT, 0600);
108 if (fd == -1) {
109 free(ctrlGlobal);
110 free(filename);
111 return 0;
112 }
113 gnupg_set_homedir("/tmp/fuzzdirverify/");
114 if (keydb_add_resource ("pubring" EXTSEP_S GPGEXT_GPG,
115 KEYDB_RESOURCE_FLAG_DEFAULT) != GPG_ERR_NO_ERROR) {
116 free(filename);
117 free(ctrlGlobal);
118 close(fd);
119 return 0;
120 }
121 if (setup_trustdb (1, NULL) != GPG_ERR_NO_ERROR) {
122 free(filename);
123 free(ctrlGlobal);
124 close(fd);
125 return 0;
126 }
127 //populate /tmp/fuzzdirverify/ as homedir ~/.gnupg
128 strlist_t sl = NULL;
129 public_key_list (ctrlGlobal, sl, 0, 0);
130 free_strlist(sl);
131 //no output for stderr
132 log_set_file("/dev/null");
133 gcry_set_log_handler (my_gcry_logger, NULL);
134 gnupg_initialize_compliance (GNUPG_MODULE_NAME_GPG);
135 initialized = true;
136 }
137
138 memset(ctrlGlobal, 0, sizeof(*ctrlGlobal));
139 ctrlGlobal->magic = SERVER_CONTROL_MAGIC;
140
141 if (ftruncate(fd, Size) == -1) {
142 return 0;
143 }
144 if (lseek (fd, 0, SEEK_SET) < 0) {
145 return 0;
146 }
147 if (write (fd, Data, Size) != Size) {
148 return 0;
149 }
150
151 verify_signatures(ctrlGlobal, 1, &filename);
152 gpg_deinit_default_ctrl (ctrlGlobal);
153 memset(ctrlGlobal, 0, sizeof(*ctrlGlobal));
154 ctrlGlobal->magic = SERVER_CONTROL_MAGIC;
155 verify_files(ctrlGlobal, 1, &filename);
156 gpg_deinit_default_ctrl (ctrlGlobal);
157
158 return 0;
159 }
160