Module: AFL

Defined in:
lib/afl/version.rb

Constant Summary collapse

VERSION =
'0.0.3'
FORKSRV_FD =
vFORKSRV_FD

Class Method Summary collapse

Class Method Details

._close_forksrv_fdsObject

Close the AFL forksrv file descriptors.



183
184
185
186
187
# File 'ext/afl_ext/afl_ext.c', line 183

static VALUE afl__close_forksrv_fds(VALUE _self) {
    close(FORKSRV_FD);
    close(FORKSRV_FD + 1);
    return Qnil;
}

._forkserver_readObject



121
122
123
124
125
126
127
128
129
130
131
# File 'ext/afl_ext/afl_ext.c', line 121

static VALUE afl__forkserver_read(VALUE _self) {
    unsigned int value;
    int ret = read(FORKSRV_FD, &value, 4);
    LOG("Read from forksrv value=%d ret=%d", value, ret);
    if (ret != 4) {
        LOG("Couldn't read from forksrv errno=%d", errno);
        VALUE exc = rb_const_get(AFL, rb_intern("RuntimeError"));
        rb_raise(exc, "Couldn't read from forksrv");
    }
    return INT2FIX(value);
}

._forkserver_write(v) ⇒ Object

Write a value (generally a child_pid) to the AFL forkserver.



136
137
138
139
140
141
142
143
144
145
146
# File 'ext/afl_ext/afl_ext.c', line 136

static VALUE afl__forkserver_write(VALUE _self, VALUE v) {
    unsigned int value = FIX2INT(v);

    int ret = write(FORKSRV_FD + 1, &value, 4);
    LOG("Wrote to forksrv_sock value=%d ret=%d\n", value, ret);
    if (ret != 4) {
        VALUE exc = rb_const_get(AFL, rb_intern("RuntimeError"));
        rb_raise(exc, "Couldn't write to forksrv");
    }
    return INT2FIX(ret);
}

._init_forkserverObject

Initialize the AFL forksrv by testing that we can write to it.



108
109
110
111
112
113
114
115
116
117
118
119
# File 'ext/afl_ext/afl_ext.c', line 108

static VALUE afl__init_forkserver(void) {
    LOG("Testing writing to forksrv fd=%d\n", FORKSRV_FD);

    int ret = write(FORKSRV_FD + 1, "\0\0\0\0", 4);
    if (ret != 4) {
        VALUE exc = rb_const_get(AFL, rb_intern("RuntimeError"));
        rb_raise(exc, "Couldn't write to forksrv");
    }

    LOG("Successfully wrote out nulls to forksrv ret=%d\n", ret);
    return Qnil;
}

._init_shmObject

Initialize AFL’s shared memory segment.



151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# File 'ext/afl_ext/afl_ext.c', line 151

static VALUE afl__init_shm(void) {
    LOG("Initializing SHM\n");
    VALUE exc = rb_const_get(AFL, rb_intern("RuntimeError"));

    if (init_done == Qtrue) {
        rb_raise(exc, "AFL already initialized");
    }

    const char * afl_shm_id_str = getenv(SHM_ENV_VAR);
    if (afl_shm_id_str == NULL) {
        rb_raise(
            exc,
            "No AFL SHM segment specified. AFL's SHM env var is not set."
            "Are we actually running inside AFL?");
    }

    const int afl_shm_id = atoi(afl_shm_id_str);
    afl_area = shmat(afl_shm_id, NULL, 0);
    if (afl_area == (void*) -1) {
        rb_raise(exc, "Couldn't map shm segment");
    }
    LOG("afl_area at 0x%zx\n", afl_area);

    init_done = Qtrue;

    LOG("Done initializing SHM\n");
    return Qtrue;
}

.bail!Object



189
190
191
192
193
194
195
196
197
198
# File 'ext/afl_ext/afl_ext.c', line 189

static VALUE afl_bail_bang(VALUE _self) {
    LOG("bailing\n");
#ifdef AFL_RUBY_EXT_DEBUG_LOG
    if (aflogf) {
        fclose(aflogf);
        aflogf = NULL;
    }
#endif
    _exit(0);
}

.trace(file_name, line_no) ⇒ Object

Write Ruby trace data to AFL’s shared memory.

TODO: link to the AFL code that this is mimicking.



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'ext/afl_ext/afl_ext.c', line 82

static VALUE afl_trace(VALUE _self, VALUE file_name, VALUE line_no) {
    static int prev_location;
    int offset;
    VALUE exc = rb_const_get(AFL, rb_intern("RuntimeError"));

    if (init_done == Qfalse) {
        rb_raise(exc, "AFL not initialized, call ::AFL.init first!");
    }

    char* fname = StringValueCStr(file_name);
    size_t lno = FIX2INT(line_no);
    unsigned int location = lhash(fname, lno) % MAP_SIZE;
    LOG("[+] %s:%zu\n", fname, lno);

    offset = location ^ prev_location;
    prev_location = location / 2;
    LOG("[!] offset 0x%x\n", offset);
    afl_area[offset] += 1;

    LOG("[-] done with trace");
    return Qtrue;
}