/src/janus-gateway/fuzzers/rtp_fuzzer.c
Line | Count | Source (jump to first uncovered line) |
1 | | #include <stdint.h> |
2 | | #include <stddef.h> |
3 | | #include <stdlib.h> |
4 | | |
5 | | #include <glib.h> |
6 | | #include "../src/debug.h" |
7 | | #include "../src/utils.h" |
8 | | #include "../src/rtp.h" |
9 | | |
10 | | int janus_log_level = LOG_NONE; |
11 | | gboolean janus_log_timestamps = FALSE; |
12 | | gboolean janus_log_colors = FALSE; |
13 | | char *janus_log_global_prefix = NULL; |
14 | | int lock_debug = 0; |
15 | | |
16 | | /* This is to avoid linking with openSSL */ |
17 | 0 | int RAND_bytes(uint8_t *key, int len) { |
18 | 0 | return 0; |
19 | 0 | } |
20 | | |
21 | | /* Clone libsrtp srtp_validate_rtp_header */ |
22 | 1.30k | #define octets_in_rtp_header 12 |
23 | 289 | #define uint32s_in_rtp_header 3 |
24 | 306 | #define octets_in_rtp_extn_hdr 4 |
25 | | |
26 | 652 | static int srtp_validate_rtp_header(char *data, int pkt_octet_len) { |
27 | 652 | if (pkt_octet_len < octets_in_rtp_header) |
28 | 0 | return -1; |
29 | | |
30 | 652 | janus_rtp_header *hdr = (janus_rtp_header *)data; |
31 | | |
32 | | /* Check RTP header length */ |
33 | 652 | int rtp_header_len = octets_in_rtp_header + 4 * hdr->csrccount; |
34 | 652 | if (hdr->extension == 1) |
35 | 306 | rtp_header_len += octets_in_rtp_extn_hdr; |
36 | | |
37 | 652 | if (pkt_octet_len < rtp_header_len) |
38 | 23 | return -1; |
39 | | |
40 | | /* Verifing profile length. */ |
41 | 629 | if (hdr->extension == 1) { |
42 | 289 | janus_rtp_header_extension *xtn_hdr = |
43 | 289 | (janus_rtp_header_extension *)((uint32_t *)hdr + uint32s_in_rtp_header + |
44 | 289 | hdr->csrccount); |
45 | 289 | int profile_len = ntohs(xtn_hdr->length); |
46 | 289 | rtp_header_len += profile_len * 4; |
47 | | /* profile length counts the number of 32-bit words */ |
48 | 289 | if (pkt_octet_len < rtp_header_len) |
49 | 55 | return -1; |
50 | 289 | } |
51 | 574 | return 0; |
52 | 629 | } |
53 | | |
54 | 677 | int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { |
55 | | /* Sanity Checks */ |
56 | | /* Max UDP payload with MTU=1500 */ |
57 | 677 | if (size > 1472) return 0; |
58 | | /* libnice checks that a packet length is positive */ |
59 | 666 | if (size <= 0) return 0; |
60 | | /* Janus checks for a minimum packet length |
61 | | * and the RTP header type value */ |
62 | 666 | if (!janus_is_rtp((char *)data, size)) return 0; |
63 | | |
64 | 652 | char sdes_item[16]; |
65 | 652 | janus_rtp_header_extension_parse_rid((char *)data, size, 1, sdes_item, sizeof(sdes_item)); |
66 | 652 | janus_rtp_header_extension_parse_mid((char *)data, size, 1, sdes_item, sizeof(sdes_item)); |
67 | | |
68 | | /* Do same checks that libsrtp does */ |
69 | 652 | if (srtp_validate_rtp_header((char *)data, size) < 0) return 0; |
70 | | |
71 | | /* RTP extensions parsers */ |
72 | 574 | guint16 transport_seq_num; |
73 | 574 | gboolean c, f, r1, r0; |
74 | 574 | uint8_t dd[256]; |
75 | 574 | int sizedd = sizeof(dd); |
76 | 574 | janus_rtp_header_extension_parse_audio_level((char *)data, size, 1, NULL, NULL); |
77 | 574 | janus_rtp_header_extension_parse_playout_delay((char *)data, size, 1, NULL, NULL); |
78 | 574 | janus_rtp_header_extension_parse_transport_wide_cc((char *)data, size, 1, &transport_seq_num); |
79 | 574 | janus_rtp_header_extension_parse_abs_sent_time((char *)data, size, 1, NULL); |
80 | 574 | janus_rtp_header_extension_parse_video_orientation((char * )data, size, 1, &c, &f, &r1, &r0); |
81 | 574 | janus_rtp_header_extension_parse_dependency_desc((char *)data, size, 1, (uint8_t *)&dd, &sizedd); |
82 | | |
83 | | /* Extract codec payload */ |
84 | 574 | int plen = 0; |
85 | 574 | char *payload = janus_rtp_payload((char *)data, size, &plen); |
86 | 574 | if (!payload) return 0; |
87 | | /* Make a copy of payload */ |
88 | 567 | char copy_payload[plen]; |
89 | 567 | memcpy(copy_payload, payload, plen); |
90 | | |
91 | | /* H.264 targets */ |
92 | 567 | janus_h264_is_keyframe(payload, plen); |
93 | | |
94 | | /* VP8 targets */ |
95 | 567 | gboolean m = FALSE; |
96 | 567 | uint16_t picid = 0; |
97 | 567 | uint8_t tlzi = 0, tid = 0, ybit = 0, keyidx = 0; |
98 | 567 | janus_vp8_simulcast_context vp8_context; |
99 | 567 | memset(&vp8_context, 0, sizeof(janus_vp8_simulcast_context)); |
100 | 567 | janus_vp8_is_keyframe(payload, plen); |
101 | 567 | janus_vp8_parse_descriptor(payload, plen, &m, &picid, &tlzi, &tid, &ybit, &keyidx); |
102 | 567 | janus_vp8_simulcast_descriptor_update(copy_payload, plen, &vp8_context, TRUE); |
103 | | |
104 | | /* VP9 targets */ |
105 | 567 | int found = 0; |
106 | 567 | janus_vp9_svc_info info; |
107 | 567 | janus_vp9_is_keyframe(payload, plen); |
108 | 567 | janus_vp9_parse_svc(payload, plen, &found, &info); |
109 | | |
110 | | /* Free resources */ |
111 | | |
112 | 567 | return 0; |
113 | 574 | } |