changeset 1779:36d4c027cba7

fuzzing: add workaround getpwuid/getpwnam
author Matt Johnston <matt@ucc.asn.au>
date Mon, 16 Nov 2020 22:44:30 +0800
parents 19cdeb3d2aac
children b5aedadc0008
files fuzz.h fuzz/fuzz-common.c
diffstat 2 files changed, 58 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/fuzz.h	Sun Nov 15 21:22:08 2020 +0800
+++ b/fuzz.h	Mon Nov 16 22:44:30 2020 +0800
@@ -99,6 +99,14 @@
 
 #endif /* FUZZ_NO_REPLACE_STDERR */
 
+struct passwd* fuzz_getpwuid(uid_t uid);
+struct passwd* fuzz_getpwnam(const char *login);
+/* guard for when fuzz.h is included by fuzz-common.c */
+#ifndef FUZZ_NO_REPLACE_GETPW
+#define getpwnam(x) fuzz_getpwnam(x)
+#define getpwuid(x) fuzz_getpwuid(x)
+#endif // FUZZ_NO_REPLACE_GETPW
+
 #endif // DROPBEAR_FUZZ
 
 #endif /* DROPBEAR_FUZZ_H */
--- a/fuzz/fuzz-common.c	Sun Nov 15 21:22:08 2020 +0800
+++ b/fuzz/fuzz-common.c	Mon Nov 16 22:44:30 2020 +0800
@@ -1,4 +1,5 @@
 #define FUZZ_NO_REPLACE_STDERR
+#define FUZZ_NO_REPLACE_GETPW
 #include "includes.h"
 
 #include "includes.h"
@@ -261,7 +262,7 @@
 
     if (authdone) {
         ses.authstate.authdone = 1;
-        char *me = getpwuid(getuid())->pw_name;
+        char *me = fuzz_getpwuid(getuid())->pw_name;
         fill_passwd(me);
     }
 
@@ -332,3 +333,51 @@
         assert(atomicio(vwrite, fuzz.recv_dumpfd, (void*)data, len) == len);
     }
 }
+
+static struct passwd pwd_root = {
+    .pw_name = "root",
+    .pw_passwd = "!",
+    .pw_uid = 0,
+    .pw_gid = 0,
+    .pw_dir = "/root",
+    .pw_shell = "/bin/sh",
+};
+
+static struct passwd pwd_other = {
+    .pw_name = "other",
+    .pw_passwd = "!",
+    .pw_uid = 100,
+    .pw_gid = 100,
+    .pw_dir = "/home/other",
+    .pw_shell = "/bin/sh",
+};
+
+
+/* oss-fuzz runs fuzzers under minijail, without /etc/passwd.
+We provide sufficient values for the fuzzers to run */
+struct passwd* fuzz_getpwnam(const char *login) {
+    if (!fuzz.fuzzing) {
+        return getpwnam(login);
+    }
+    if (strcmp(login, pwd_other.pw_name) == 0) {
+        return &pwd_other;
+    }
+    if (strcmp(login, pwd_root.pw_name) == 0) {
+        return &pwd_root;
+    }
+    return NULL;
+}
+
+struct passwd* fuzz_getpwuid(uid_t uid) {
+    if (!fuzz.fuzzing) {
+        return getpwuid(uid);
+    }
+    if (uid == pwd_other.pw_uid) {
+        return &pwd_other;
+    }
+    if (uid == pwd_root.pw_uid) {
+        return &pwd_root;
+    }
+    return NULL;
+}
+