Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Out-of-bounds write, segfault, in pdf-lex.c:lex_string() #2

Open
carter-yagemann opened this issue Jun 24, 2021 · 1 comment
Open

Comments

@carter-yagemann
Copy link

PoC: poc.pdf

Steps to Reproduce

  1. Modify main.c to read the attached poc.pdf.

Debug:

$ gdb --args ./hdContents/build/hdContents
$ r
[----------------------------------registers-----------------------------------]
RAX: 0x78 ('x')
RBX: 0x5555556348e0 --> 0x2 
RCX: 0x78 ('x')
RDX: 0x5555556348c4 --> 0x6e650a3e3dfc5d74 
RSI: 0x5555556348e0 --> 0x2 
RDI: 0x555555626260 --> 0x0 
RBP: 0x555555626260 --> 0x0 
RSP: 0x7fffffffde20 --> 0x5555556349b8 ('(' <repeats 42 times>, "s\n/R   *      =         ")
RIP: 0x5555555c5318 (<pdf_lex+2968>:	mov    BYTE PTR [r15],al)
R8 : 0xffffffffa254c658 
R9 : 0x5555556449b8 --> 0x1011 
R10: 0x22 ('"')
R11: 0x20000 
R12: 0x555555634990 --> 0x1000000020000 
R13: 0x7ffff7ba1010 --> 0x0 
R14: 0x24 ('$')
R15: 0x5554f7b91010
EFLAGS: 0x10212 (carry parity ADJUST zero sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x5555555c530c <pdf_lex+2956>:	add    r15,0x1
   0x5555555c5310 <pdf_lex+2960>:	jmp    0x5555555c4bf2 <pdf_lex+1138>
   0x5555555c5315 <pdf_lex+2965>:	nop    DWORD PTR [rax]
=> 0x5555555c5318 <pdf_lex+2968>:	mov    BYTE PTR [r15],al
   0x5555555c531b <pdf_lex+2971>:	add    r15,0x1
   0x5555555c531f <pdf_lex+2975>:	jmp    0x5555555c4bf2 <pdf_lex+1138>
   0x5555555c5324 <pdf_lex+2980>:	nop    DWORD PTR [rax+0x0]
   0x5555555c5328 <pdf_lex+2984>:	mov    BYTE PTR [r15],0x28
[------------------------------------stack-------------------------------------]
0000| 0x7fffffffde20 --> 0x5555556349b8 ('(' <repeats 42 times>, "s\n/R   *      =         ")
0008| 0x7fffffffde28 --> 0x5555555a5483 (<pdf_new_name+419>:	add    rsp,0x18)
0016| 0x7fffffffde30 --> 0x0 
0024| 0x7fffffffde38 --> 0x555500020000 
0032| 0x7fffffffde40 --> 0x555555626260 --> 0x0 
0040| 0x7fffffffde48 --> 0x5555556034a4 --> 0xfffc3ddcfffc3ddc 
0048| 0x7fffffffde50 --> 0x555555601f56 --> 0x5249004d49004449 ('ID')
0056| 0x7fffffffde58 --> 0x555555626260 --> 0x0 
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
lex_string (lb=0x555555634990, f=0x5555556348e0, ctx=0x555555626260) at source/pdf/pdf-lex.c:411
411					*s++ = c;

Blame:

while (1)
{
if (s == e)
{
s += pdf_lexbuf_grow(ctx, lb);
e = lb->scratch + lb->size;
}
c = hd_read_byte(ctx, f);
switch (c)
{
case EOF:
goto end;
case '(':
bal++;
*s++ = c;
break;
case ')':
bal --;
if (bal == 0)
goto end;
*s++ = c;
break;
case '\\':
c = hd_read_byte(ctx, f);
switch (c)
{
case EOF:
goto end;
case 'n':
*s++ = '\n';
break;
case 'r':
*s++ = '\r';
break;
case 't':
*s++ = '\t';
break;
case 'b':
*s++ = '\b';
break;
case 'f':
*s++ = '\f';
break;
case '(':
*s++ = '(';
break;
case ')':
*s++ = ')';
break;
case '\\':
*s++ = '\\';
break;
case RANGE_0_7:
oct = c - '0';
c = hd_read_byte(ctx, f);
if (c >= '0' && c <= '7')
{
oct = oct * 8 + (c - '0');
c = hd_read_byte(ctx, f);
if (c >= '0' && c <= '7')
oct = oct * 8 + (c - '0');
else if (c != EOF)
hd_unread_byte(ctx, f);
}
else if (c != EOF)
hd_unread_byte(ctx, f);
*s++ = oct;
break;
case '\n':
break;
case '\r':
c = hd_read_byte(ctx, f);
if ((c != '\n') && (c != EOF))
hd_unread_byte(ctx, f);
break;
default:
*s++ = c;
}
break;
default:
*s++ = c;
break;
}
}

@LeftHandCold
Copy link
Owner

Thank you for your feedback, I will fix this bug.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants