/*
* CVE-2026-31885 PoC - FreeRDP MS-ADPCM/IMA-ADPCM Out-of-Bounds Read
* This is a demonstration of the vulnerability in FreeRDP audio decoding.
* Attackers can craft malicious RDP packets with invalid predictor/step_index values.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// Simulated MS-ADPCM decoder with vulnerability
void ms_adpcm_decode_vulnerable(unsigned char* input, int input_len,
int16_t* output, int output_len) {
int predictor = 0;
int step_index = 0;
int delta = 0;
// Vulnerable: No bounds checking on predictor and step_index
predictor = input[0]; // Attacker controlled
step_index = input[1]; // Attacker controlled
// Coefficient tables (should check bounds before access)
static const int16_t coeff1[] = {256, 512, 0, 192, 240, 460, 392};
static const int16_t coeff2[] = {0, -256, 0, 64, 0, -208, -232};
// Out-of-bounds access occurs here when predictor > 6
int16_t pred1 = coeff1[predictor]; // OOB read if predictor >= 7
int16_t pred2 = coeff2[predictor]; // OOB read if predictor >= 7
// Step table (should check bounds before access)
static const int step_table[] = {
7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31,
34, 37, 41, 45, 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130
};
// OOB read occurs here when step_index >= 32
int step = step_table[step_index]; // OOB read if step_index >= 32
printf("Predictor: %d, Step Index: %d, Step: %d\n", predictor, step_index, step);
}
// Fixed version with bounds checking
void ms_adpcm_decode_fixed(unsigned char* input, int input_len,
int16_t* output, int output_len) {
int predictor = 0;
int step_index = 0;
predictor = input[0];
step_index = input[1];
// Fixed: Add bounds checking
if (predictor >= 7) {
printf("Error: Invalid predictor value %d\n", predictor);
return;
}
if (step_index >= 32) {
printf("Error: Invalid step_index value %d\n", step_index);
return;
}
// Now safe to access arrays
static const int16_t coeff1[] = {256, 512, 0, 192, 240, 460, 392};
static const int16_t coeff2[] = {0, -256, 0, 64, 0, -208, -232};
static const int step_table[] = {
7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31,
34, 37, 41, 45, 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130
};
int16_t pred1 = coeff1[predictor];
int16_t pred2 = coeff2[predictor];
int step = step_table[step_index];
printf("Safe - Predictor: %d, Step Index: %d, Step: %d\n", predictor, step_index, step);
}
int main() {
unsigned char malicious_input[] = {10, 50}; // Invalid values
int16_t output[100];
printf("Testing vulnerable version:\n");
ms_adpcm_decode_vulnerable(malicious_input, 2, output, 100);
printf("\nTesting fixed version:\n");
ms_adpcm_decode_fixed(malicious_input, 2, output, 100);
return 0;
}