Coverage Report

Created: 2026-09-28 06:27

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/freeradius-server/src/fuzzer/fuzzer_json.c
Line
Count
Source
1
/*
2
 *   This program is free software; you can redistribute it and/or modify
3
 *   it under the terms of the GNU General Public License as published by
4
 *   the Free Software Foundation; either version 2 of the License, or
5
 *   (at your option) any later version.
6
 *
7
 *   This program is distributed in the hope that it will be useful,
8
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
 *   GNU General Public License for more details.
11
 *
12
 *   You should have received a copy of the GNU General Public License
13
 *   along with this program; if not, write to the Free Software
14
 *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
15
 */
16
17
/**
18
 * $Id: 3281402f3d8d7b4ed480616e9425d0f6bf064eb7 $
19
 *
20
 * @file src/bin/fuzzer_json.c
21
 * @brief Functions to fuzz json
22
 * */
23
RCSID("$Id: 3281402f3d8d7b4ed480616e9425d0f6bf064eb7 $")
24
25
#include <freeradius-devel/build.h>
26
#include <freeradius-devel/util/talloc.h>
27
28
DIAG_OFF(documentation)
29
DIAG_OFF(deprecated)
30
31
#include <stdint.h>
32
#include <stddef.h>
33
#include <stdlib.h>
34
#include <string.h>
35
#include <stdbool.h>
36
#include <sys/types.h>
37
#include <json-c/json.h>
38
39
/* Forward declarations for FreeRADIUS types to avoid header complexity */
40
typedef struct fr_jpath_node_s fr_jpath_node_t;
41
42
/* External declarations for functions */
43
extern ssize_t fr_jpath_parse(void *ctx, fr_jpath_node_t **head, 
44
            char const *in, size_t inlen);
45
46
int LLVMFuzzerInitialize(int *argc, char ***argv);
47
int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len);
48
49
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
50
3.14k
{
51
3.14k
  void *ctx = NULL;
52
3.14k
  size_t split_point;
53
54
  /* Need at least 2 bytes */
55
3.14k
  if (size < 2) {
56
1
    return 0;
57
1
  }
58
59
  /* Limit input size to prevent timeouts */
60
3.14k
  if (size > 8192) {
61
18
    return 0;
62
18
  }
63
64
  /* Initialize talloc context */
65
3.12k
  ctx = talloc_init("fuzzer_json");
66
3.12k
  if (!ctx) {
67
0
    return 0;
68
0
  }
69
70
  /*
71
   *  Use first byte to determine split between JSON and jpath
72
   */
73
3.12k
  split_point = (data[0] * size) / 256;
74
3.12k
  if (split_point >= size - 1) {
75
36
    split_point = size / 2;
76
36
  }
77
78
  /*
79
   *  JSON string to parse with json-c
80
   */
81
3.12k
  if (split_point > 1) {
82
2.44k
    char *str = NULL;
83
2.44k
    json_object *json_obj = NULL;
84
85
2.44k
    str = talloc_strndup(ctx, (const char *)(data + 1), split_point - 1);
86
2.44k
    if (str) {
87
2.44k
      json_obj = json_tokener_parse(str);
88
2.44k
      if (json_obj) {
89
430
        json_object_put(json_obj);
90
430
        json_obj = NULL;
91
430
      }
92
2.44k
    }
93
2.44k
  }
94
95
  /*
96
   *  jpath expression string to parse with FreeRADIUS
97
   */
98
3.12k
  if (split_point < size - 1) {
99
3.12k
    size_t len = size - split_point - 1;
100
3.12k
    char *str = NULL;
101
3.12k
    fr_jpath_node_t *jpath_head = NULL;
102
103
3.12k
    if (len > 0) {
104
3.12k
      str = talloc_strndup(ctx,
105
3.12k
               (const char *)(data + split_point + 1), 
106
3.12k
               len);
107
3.12k
    }
108
        
109
3.12k
    if (str) {
110
      /*
111
       *  the strdup functions stop at the first 0.  So we need to pass the actual
112
       *  length of "str", and not the input "len".
113
       *
114
       *  Since the json code also stops at the first NUL, character, there's no benefit
115
       *  to passing any more than that.
116
       */
117
3.12k
      (void) fr_jpath_parse(ctx, &jpath_head, str, talloc_strlen(str));
118
3.12k
    }
119
3.12k
  }
120
121
  talloc_free(ctx);
122
3.12k
  return 0;
123
3.12k
}