We open a fresh score table if the result pointer is not NULL,
indicating that we are called from com_ls() (with -a=p/foo) rather
than from com_select(). However, if an error occurs afterwards, we
call score_close() unconditionally. This is wrong in the result ==
NULL case (com_select()) because it closes the global score table
which is expected to stay open.
The result is a UAF, which is diagnosed by valgrind as follows:
==4767== Invalid read of size 4
==4767== at 0x408C51E: osl_add_and_get_row (osl.c:1216)
==4767== by 0x408CA99: osl_add_row (osl.c:1348)
==4767== by 0x8060648: score_add (score.c:116)
==4767== by 0x805F08C: add_to_score_table (mood.c:451)
==4767== by 0x805FA3E: mood_load (mood.c:650)
==4767== by 0x8057ECF: activate_mood_or_playlist (afs.c:447)
==4767== by 0x8059637: com_select_callback (afs.c:1005)
Fixes: 2d2637cb4c9ab76fea6bc336b9af88fd00bf5e08
}
return pi->length;
close_score_table:
- score_close(pi->score_table);
+ if (result)
+ score_close(pi->score_table);
free(pi);
err:
PARA_NOTICE_LOG("unable to load playlist %s\n", name);