Skip to content

Instantly share code, notes, and snippets.

@taviso taviso/fbmon.c
Last active Jul 22, 2019

Embed
What would you like to do?
fbmon bug
#include <stdio.h>
#include <stdint.h>
#include <string.h>
/*
$ gcc fbmon.c
$ ./a.out
*** stack smashing detected ***: <unknown> terminated
Aborted (core dumped)
Adapted from:
https://lgtm.com/projects/g/torvalds/linux/snapshot/56e7115abb329f63ffaec05e990c1a7199ddcd83/files/drivers/video/fbdev/core/fbmon.c?sort=name&dir=ASC&mode=heatmap#L1033
(Found by Nico, I just browsed his query results)
https://twitter.com/nicowaisman/status/1151927251690278912
Probably not a security bug (who plugs in a malicious monitor!), but seems like a real bug!
*/
#define DETAILED_TIMING_DESCRIPTION_SIZE 18
typedef uint8_t u8;
void fb_edid_add_monspecs(unsigned char *edid)
{
int num = 0, i;
u8 svd[64], edt[(128 - 4) / DETAILED_TIMING_DESCRIPTION_SIZE];
u8 pos = 4, svd_n = 0;
if (!edid)
return;
if (edid[0] != 0x2 ||
edid[2] < 4 || edid[2] > 128 - DETAILED_TIMING_DESCRIPTION_SIZE)
return;
while (pos < edid[2]) {
u8 len = edid[pos] & 0x1f, type = (edid[pos] >> 5) & 7;
if (type == 2) {
for (i = pos; i < pos + len; i++) {
u8 idx = edid[pos + i] & 0x7f;
svd[svd_n++] = idx;
}
} else if (type == 3 && len >= 3) {
/* Check Vendor Specific Data Block. For HDMI,
it is always 00-0C-03 for HDMI Licensing, LLC. */
}
pos += len + 1;
}
}
int main(int argc, char **argv)
{
unsigned char edid[512];
unsigned char *p;
// type = 2, len = 1
memset(edid, (2 << 5) | 1, sizeof edid);
edid[0] = 0x2; // magic
edid[1] = 0x0; // ignored
edid[3] = 0x0; // ignored
// size
edid[2] = 128 - DETAILED_TIMING_DESCRIPTION_SIZE;
// Find last len/data pair
p = &edid[edid[2] - 4 - 2];
// type = 2, len = 0x1f ..overruns buffer
*p++ = (2 << 5) | 0x1f;
memset(p, 'X', sizeof(edid) - (p - edid));
fb_edid_add_monspecs(edid);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.