DF-4710 / dbg4.c
/* * dbg4.c — deliberate demonstration of the missing SND_CHN_MAX guard in * feed_eq_init (feeder_eq.c:362): the real, unmodified feeder_eq.c compiled * in userland; a >8-channel format flows unchecked into info->channels while * the tone state arrays are [SND_CHN_MAX=8] (feeder_eq.c:109-115). * Build at -O0 for deterministic field placement. */ #include "eqshim.h" #include "feeder_eq.c" static uint32_t src_remaining, src_pattern = 4, src_partial; static uint32_t prng_state = 1; static uint32_t prng(void){prng_state^=prng_state<<13;prng_state^=prng_state>>17;prng_state^=prng_state<<5;return prng_state;} static void fill_pattern(uint8_t *b, uint32_t n){uint32_t i;int32_t v;for(i=0;i+4<=n;i+=4){v=(int32_t)prng();memcpy(b+i,&v,4);}for(;i<n;i++)b[i]=(uint8_t)prng();} uint32_t eqshim_source_feed(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b, uint32_t count, void *src){uint32_t g=count;(void)f;(void)c;(void)src;if(g>src_remaining)g=src_remaining;fill_pattern(b,g);src_remaining-=g;return g;} int eqshim_set(struct pcm_feeder *f,int w,int v){return feed_eq_set(f,w,v);} int main(int argc, char **argv) { struct pcm_feeder f; struct pcm_feederdesc d; struct feed_eq_info *info; uint32_t ch = argc > 1 ? (uint32_t)atoi(argv[1]) : 16; memset(&f,0,sizeof(f)); memset(&d,0,sizeof(d)); d.type = FEEDER_EQ; d.in = d.out = SND_FORMAT(AFMT_S16_LE, ch, 0); f.desc = &d; int r = feed_eq_init(&f); info = f.data; printf("init=%d channels=%u align=%u treble.gain=%d bass.gain=%d\n", r, info->channels, info->align, info->treble.gain, info->bass.gain); uint8_t *buf = malloc(65536); int tg0 = info->treble.gain; src_remaining = 16384; uint32_t got = feed_eq_feed(&f, NULL, buf, 16384, NULL); kfree_canary_check(info, sizeof(*info)); printf("got=%u treble.gain=%d (was %d) bass.gain=%d canary=%d(%s)\n", got, info->treble.gain, tg0, info->bass.gain, eqshim_canary_hit, eqshim_canary_where); return 0; } |