etc.git


etc

~ scripts and random things
git clone https://github.com/djnnvx/etc.git
log | files | refs | archive

fuzz_lws_mock.c (7899B)

      1 /* Mock implementations of libwebsockets runtime functions for fuzzing ttyd.
      2  * lws_hdr_copy / lws_hdr_custom_* return fuzzer-controlled data so AFL++
      3  * can drive the auth logic.  All other lws functions are safe no-ops.      */
      4 
      5 #include "fuzz-include/libwebsockets.h"
      6 #include "fuzz_lws_mock.h"
      7 #include <string.h>
      8 #include <stdio.h>
      9 #include <stdint.h>
     10 #include <stdlib.h>
     11 
     12 /* ── fuzzer-controlled state ─────────────────────────────────────────── */
     13 char _fuzz_auth_header[4096];
     14 int  _fuzz_auth_header_len;
     15 char _fuzz_custom_header[4096];
     16 int  _fuzz_custom_header_len;
     17 char _fuzz_uri_path[4096];
     18 int  _fuzz_uri_path_len;
     19 char _fuzz_origin[4096];
     20 int  _fuzz_origin_len;
     21 char _fuzz_host[4096];
     22 int  _fuzz_host_len;
     23 
     24 char _fuzz_uri_args[FUZZ_MAX_URI_ARGS][256];
     25 int  _fuzz_uri_args_len[FUZZ_MAX_URI_ARGS];
     26 int  _fuzz_uri_args_count;
     27 
     28 int    _fuzz_is_final_fragment = 1;
     29 size_t _fuzz_remaining_payload = 0;
     30 
     31 void fuzz_lws_reset(void) {
     32     memset(_fuzz_auth_header,   0, sizeof(_fuzz_auth_header));
     33     _fuzz_auth_header_len   = 0;
     34     memset(_fuzz_custom_header, 0, sizeof(_fuzz_custom_header));
     35     _fuzz_custom_header_len = 0;
     36     memset(_fuzz_uri_path, 0, sizeof(_fuzz_uri_path));
     37     _fuzz_uri_path_len = 0;
     38     memset(_fuzz_origin, 0, sizeof(_fuzz_origin));
     39     _fuzz_origin_len = 0;
     40     memset(_fuzz_host, 0, sizeof(_fuzz_host));
     41     _fuzz_host_len = 0;
     42     memset(_fuzz_uri_args, 0, sizeof(_fuzz_uri_args));
     43     memset(_fuzz_uri_args_len, 0, sizeof(_fuzz_uri_args_len));
     44     _fuzz_uri_args_count = 0;
     45     _fuzz_is_final_fragment = 1;
     46     _fuzz_remaining_payload = 0;
     47 }
     48 
     49 /* ── header accessors ────────────────────────────────────────────────── */
     50 
     51 /* Helper: copy from a source buffer into dest, return bytes copied */
     52 static int copy_hdr(char *dest, int len, const char *src, int srclen) {
     53     if (!dest || len <= 0) return 0;
     54     if (!src || srclen <= 0) { dest[0] = '\0'; return 0; }
     55     int n = srclen < len - 1 ? srclen : len - 1;
     56     memcpy(dest, src, n);
     57     dest[n] = '\0';
     58     return n;
     59 }
     60 
     61 int lws_hdr_copy(struct lws *wsi, char *dest, int len,
     62                  enum lws_token_indexes h) {
     63     switch (h) {
     64     case WSI_TOKEN_HTTP_AUTHORIZATION:
     65         return copy_hdr(dest, len, _fuzz_auth_header, _fuzz_auth_header_len);
     66     case WSI_TOKEN_GET_URI:
     67     case WSI_TOKEN_HTTP_COLON_PATH:
     68         return copy_hdr(dest, len, _fuzz_uri_path, _fuzz_uri_path_len);
     69     case WSI_TOKEN_ORIGIN:
     70         return copy_hdr(dest, len, _fuzz_origin, _fuzz_origin_len);
     71     case WSI_TOKEN_HOST:
     72         return copy_hdr(dest, len, _fuzz_host, _fuzz_host_len);
     73     default:
     74         if (dest && len > 0) dest[0] = '\0';
     75         return 0;
     76     }
     77 }
     78 
     79 int lws_hdr_custom_length(struct lws *wsi, const char *name, int nlen) {
     80     return _fuzz_custom_header_len;
     81 }
     82 
     83 int lws_hdr_custom_copy(struct lws *wsi, char *dst, int len,
     84                          const char *name, int nlen) {
     85     return copy_hdr(dst, len, _fuzz_custom_header, _fuzz_custom_header_len);
     86 }
     87 
     88 int lws_hdr_copy_fragment(struct lws *wsi, char *dst, int len,
     89                            enum lws_token_indexes h, int frag_idx) {
     90     if (h == WSI_TOKEN_HTTP_URI_ARGS &&
     91         frag_idx < _fuzz_uri_args_count && frag_idx < FUZZ_MAX_URI_ARGS) {
     92         return copy_hdr(dst, len,
     93                         _fuzz_uri_args[frag_idx],
     94                         _fuzz_uri_args_len[frag_idx]);
     95     }
     96     if (dst && len > 0) dst[0] = '\0';
     97     return 0;
     98 }
     99 
    100 /* ── URI parsing ─────────────────────────────────────────────────────── */
    101 /* Simple parser that extracts protocol, host, port, path from a URI.
    102  * Modifies the input string in-place (like the real lws_parse_uri).     */
    103 int lws_parse_uri(char *p, const char **prot, const char **host,
    104                   int *port, const char **path) {
    105     if (!p || !*p) {
    106         if (prot)  *prot  = "";
    107         if (host)  *host  = "";
    108         if (port)  *port  = 0;
    109         if (path)  *path  = "";
    110         return -1;
    111     }
    112 
    113     /* Find protocol: "http://" or "https://" etc. */
    114     char *sep = strstr(p, "://");
    115     if (sep) {
    116         *sep = '\0';
    117         if (prot) *prot = p;
    118         p = sep + 3;
    119     } else {
    120         if (prot) *prot = "";
    121     }
    122 
    123     /* host[:port][/path] */
    124     if (host) *host = p;
    125 
    126     /* Find path separator */
    127     char *slash = strchr(p, '/');
    128     if (slash) {
    129         if (path) *path = slash + 1;
    130         *slash = '\0';
    131     } else {
    132         if (path) *path = "";
    133     }
    134 
    135     /* Find port in host part */
    136     char *colon = strchr(p, ':');
    137     if (colon) {
    138         *colon = '\0';
    139         if (port) *port = atoi(colon + 1);
    140     } else {
    141         if (port) *port = 0;
    142     }
    143 
    144     return 0;
    145 }
    146 
    147 /* ── HTTP response helpers — all no-ops for fuzzing ─────────────────── */
    148 int lws_return_http_status(struct lws *wsi, unsigned int code,
    149                             const char *html_body) { return 0; }
    150 int lws_add_http_header_status(struct lws *wsi, unsigned int code,
    151                                 unsigned char **p, unsigned char *end) { return 0; }
    152 int lws_add_http_header_content_length(struct lws *wsi, lws_filepos_t content_length,
    153                                         unsigned char **p, unsigned char *end) { return 0; }
    154 int lws_add_http_header_by_token(struct lws *wsi, enum lws_token_indexes h,
    155                                   const unsigned char *v, int len,
    156                                   unsigned char **p, unsigned char *end) { return 0; }
    157 int lws_add_http_header_by_name(struct lws *wsi, const unsigned char *n,
    158                                  const unsigned char *v, int len,
    159                                  unsigned char **p, unsigned char *end) { return 0; }
    160 int lws_finalize_http_header(struct lws *wsi, unsigned char **p,
    161                               unsigned char *end) { return 0; }
    162 int lws_finalize_write_http_header(struct lws *wsi, unsigned char *start,
    163                                     unsigned char **p, unsigned char *end) { return 0; }
    164 int lws_write(struct lws *wsi, unsigned char *buf, size_t len,
    165               enum lws_write_protocol protocol) { return (int)len; }
    166 int lws_callback_on_writable(struct lws *wsi) { return 0; }
    167 void lws_set_timeout(struct lws *wsi, enum pending_timeout reason, int secs) {}
    168 void lws_close_reason(struct lws *wsi, int status,
    169                        unsigned char *buf, size_t len) {}
    170 struct lws_context *lws_get_context(const struct lws *wsi) { return NULL; }
    171 int lws_is_final_fragment(struct lws *wsi) { return _fuzz_is_final_fragment; }
    172 size_t lws_remaining_packet_payload(struct lws *wsi) { return _fuzz_remaining_payload; }
    173 int lws_get_peer_simple(struct lws *wsi, char *name, size_t namelen) {
    174     if (name && namelen > 0) { strncpy(name, "127.0.0.1", namelen - 1); name[namelen-1] = '\0'; }
    175     return 0;
    176 }
    177 int lws_serve_http_file(struct lws *wsi, const char *file,
    178                          const char *content_type, const char *other_headers,
    179                          int other_headers_len) { return 0; }
    180 int lws_http_transaction_completed(struct lws *wsi) { return 0; }
    181 struct lws_context *lws_create_context(struct lws_context_creation_info *i) { return NULL; }
    182 void lws_context_destroy(struct lws_context *ctx) {}
    183 int lws_service(struct lws_context *ctx, int timeout_ms) { return 0; }
    184 void lws_cancel_service(struct lws_context *ctx) {}
    185 void *lws_wsi_user(struct lws *wsi) { return NULL; }
    186 struct lws *lws_get_network_wsi(struct lws *wsi) { return wsi; }
    187 int lws_get_peer_write_allowance(struct lws *wsi) { return -1; }
    188 int lws_write_http(struct lws *wsi, void *buf, size_t len) { return (int)len; }
    189 int lws_send_pipe_choked(struct lws *wsi) { return 0; }