Skip to content

Commit 23ccf3c

Browse files
Kevin Backhouse via RTmichaelni
Kevin Backhouse via RT
authored andcommitted
avcodec/htmlsubtitles: Fixes denial of service due to use of sscanf in inner loop for tag scaning
Fixes: [Semmle Security Reports #19438] Fixes: dos_sscanf1.mkv Signed-off-by: Michael Niedermayer <michael@niedermayer.cc> (cherry picked from commit 1f00c97) Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
1 parent abdbbe8 commit 23ccf3c

File tree

1 file changed

+29
-1
lines changed

1 file changed

+29
-1
lines changed

Diff for: libavcodec/htmlsubtitles.c

+29-1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,34 @@ static void rstrip_spaces_buf(AVBPrint *buf)
5151
buf->str[--buf->len] = 0;
5252
}
5353

54+
/*
55+
* Fast code for scanning the rest of a tag. Functionally equivalent to
56+
* this sscanf call:
57+
*
58+
* sscanf(in, "%127[^<>]>%n", buffer, lenp) == 2
59+
*/
60+
static int scantag(const char* in, char* buffer, int* lenp) {
61+
int len;
62+
63+
for (len = 0; len < 128; len++) {
64+
const char c = *in++;
65+
switch (c) {
66+
case '\0':
67+
return 0;
68+
case '<':
69+
return 0;
70+
case '>':
71+
buffer[len] = '\0';
72+
*lenp = len+1;
73+
return 1;
74+
default:
75+
break;
76+
}
77+
buffer[len] = c;
78+
}
79+
return 0;
80+
}
81+
5482
int ff_htmlmarkup_to_ass(void *log_ctx, AVBPrint *dst, const char *in)
5583
{
5684
char *param, buffer[128], tmp[128];
@@ -102,7 +130,7 @@ int ff_htmlmarkup_to_ass(void *log_ctx, AVBPrint *dst, const char *in)
102130
case '<':
103131
tag_close = in[1] == '/';
104132
len = 0;
105-
if (sscanf(in+tag_close+1, "%127[^<>]>%n", buffer, &len) >= 1 && len > 0) {
133+
if (scantag(in+tag_close+1, buffer, &len) && len > 0) {
106134
const char *tagname = buffer;
107135
while (*tagname == ' ')
108136
tagname++;

0 commit comments

Comments
 (0)