• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <stdint.h>
2 #include <stddef.h>
3 #include <stdlib.h>
4 #include <stdio.h>
5 #include <stdbool.h>
6 #include <ftw.h>
7 
8 #include "config.h"
9 #include "gpg.h"
10 #include "../common/types.h"
11 #include "../common/iobuf.h"
12 #include "keydb.h"
13 #include "keyedit.h"
14 #include "../common/util.h"
15 #include "main.h"
16 #include "call-dirmngr.h"
17 #include "trustdb.h"
18 
19 #include <sys/stat.h>
20 #include <fcntl.h>
21 #include <sys/types.h>
22 #include <unistd.h>
23 #include <sys/mount.h>
24 
25 static bool initialized = false;
26 ctrl_t ctrlGlobal;
27 int fd;
28 char *filename;
29 
30 //hack not to include gpg.c which has main function
31 int g10_errors_seen = 0;
32 
33 void
g10_exit(int rc)34 g10_exit( int rc )
35 {
36     gcry_control (GCRYCTL_UPDATE_RANDOM_SEED_FILE);
37     gcry_control (GCRYCTL_TERM_SECMEM );
38     exit (rc);
39 }
40 
41 static void
gpg_deinit_default_ctrl(ctrl_t ctrl)42 gpg_deinit_default_ctrl (ctrl_t ctrl)
43 {
44 #ifdef USE_TOFU
45     tofu_closedbs (ctrl);
46 #endif
47     gpg_dirmngr_deinit_session_data (ctrl);
48 
49     keydb_release (ctrl->cached_getkey_kdb);
50 }
51 
52 static void
my_gcry_logger(void * dummy,int level,const char * format,va_list arg_ptr)53 my_gcry_logger (void *dummy, int level, const char *format, va_list arg_ptr)
54 {
55     return;
56 }
57 
unlink_cb(const char * fpath,const struct stat * sb,int typeflag)58 static int unlink_cb(const char *fpath, const struct stat *sb, int typeflag)
59 {
60     if (typeflag == FTW_F){
61         unlink(fpath);
62     }
63     return 0;
64 }
65 
rmrfdir(char * path)66 static void rmrfdir(char *path)
67 {
68     ftw(path, unlink_cb, 16);
69     if (rmdir(path) != 0) {
70         printf("failed rmdir, errno=%d\n", errno);
71     }
72 }
73 
74 // 65kb should be enough ;-)
75 #define MAX_LEN 0x10000
76 
LLVMFuzzerTestOneInput(const uint8_t * Data,size_t Size)77 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
78     IOBUF a;
79     armor_filter_context_t *afx = NULL;
80 
81     if (! initialized) {
82         ctrlGlobal = (ctrl_t) malloc(sizeof(*ctrlGlobal));
83         if (!ctrlGlobal) {
84             exit(1);
85         }
86         //deletes previous tmp dir and (re)create it as a ramfs
87         //system("umount /tmp/fuzzdirlist");
88         rmrfdir("/tmp/fuzzdirlist");
89         if (mkdir("/tmp/fuzzdirlist", 0700) < 0) {
90             printf("failed mkdir, errno=%d\n", errno);
91             if (errno != EEXIST) {
92                 return 0;
93             }
94         }
95         //system("mount -t tmpfs -o size=64M tmpfs /tmp/fuzzdirlist");
96         filename=strdup("/tmp/fuzzdirlist/fuzz.gpg");
97         if (!filename) {
98             free(ctrlGlobal);
99             return 0;
100         }
101         fd = open(filename, O_RDWR | O_CREAT, 0666);
102         if (fd == -1) {
103             free(filename);
104             free(ctrlGlobal);
105             printf("failed open, errno=%d\n", errno);
106             return 0;
107         }
108         gnupg_set_homedir("/tmp/fuzzdirlist/");
109         gpg_error_t gpgerr = keydb_add_resource ("pubring" EXTSEP_S GPGEXT_GPG, KEYDB_RESOURCE_FLAG_DEFAULT);
110         if (gpgerr != GPG_ERR_NO_ERROR) {
111             free(filename);
112             free(ctrlGlobal);
113             close(fd);
114             printf("failed keydb_add_resource, errno=%d\n", gpgerr);
115             return 0;
116         }
117         gpgerr = setup_trustdb (1, NULL);
118         if (gpgerr != GPG_ERR_NO_ERROR) {
119             free(filename);
120             free(ctrlGlobal);
121             close(fd);
122             printf("failed setup_trustdb, errno=%d\n", gpgerr);
123             return 0;
124         }
125         //populate /tmp/fuzzdirlist/ as homedir ~/.gnupg
126         strlist_t sl = NULL;
127         public_key_list (ctrlGlobal, sl, 0, 0);
128         free_strlist(sl);
129         //no output for stderr
130         log_set_file("/dev/null");
131         gcry_set_log_handler (my_gcry_logger, NULL);
132         gnupg_initialize_compliance (GNUPG_MODULE_NAME_GPG);
133         opt.list_packets=1;
134         set_packet_list_mode(1);
135         initialized = true;
136     }
137 
138     if (Size > MAX_LEN) {
139         // limit maximum size to avoid long computing times
140         return 0;
141     }
142 
143     memset(ctrlGlobal, 0, sizeof(*ctrlGlobal));
144     ctrlGlobal->magic = SERVER_CONTROL_MAGIC;
145 
146     if (ftruncate(fd, Size) == -1) {
147         return 0;
148     }
149     if (lseek (fd, 0, SEEK_SET) < 0) {
150         return 0;
151     }
152     if (write (fd, Data, Size) != Size) {
153         return 0;
154     }
155 
156     a = iobuf_open(filename);
157     if( !a ) {
158         printf("failed iobuf_open\n");
159         return 0;
160     }
161     if( use_armor_filter( a ) ) {
162         afx = new_armor_context ();
163         push_armor_filter (afx, a);
164     }
165     proc_packets (ctrlGlobal, NULL, a );
166     iobuf_close(a);
167     release_armor_context (afx);
168     gpg_deinit_default_ctrl (ctrlGlobal);
169 
170     return 0;
171 }
172