[PATCH] resolv: fix unaligned tmp buffer corner-case
Bernhard Reutner-Fischer
rep.dot.nop at gmail.com
Sat Mar 14 19:47:38 UTC 2015
On March 14, 2015 4:06:03 PM GMT+01:00, Rich Felker <dalias at libc.org> wrote:
>On Thu, Mar 12, 2015 at 02:21:12AM +0300, Alexey Brodkin wrote:
>> On execution of "inet/gethost_r-align" test I noticed failure due
>> to unaligned access (instaed of 4-byte aligned 1-byte aligned
>> address was attempted to be accessed).
>>
>> Further investigation confirmed this nice and helpful test failure.
>> Following commit removed usage of ALIGN_BUFFER_OFFSET on entry to
>> __read_etc_hosts_r():
>>
>http://git.uclibc.org/uClibc/commit/?id=f65e66078b9f4d2d7f0fc336dee36e78fc467c0f
>>
>> So indeed if target architecture doesn't allow unaligned access
>> and provided tmp buffer is not word aligned (and we will deal with
>pointers
>> which means word-sized data units), then CPU will fail during
>execution.
>>
>> In case of ARC we'll see "Unaligned access" exception like this:
>> --->8---
>> # potentially unexpected fatal signal 7.
>> Path: /root/uClibc/test/inet/gethost_r-align
>> CPU: 0 PID: 5514 Comm: gethost_r-align Not tainted 3.13.11 #2
>> task: 8f42a580 ti: 8f40e000 task.ti: 8f40e000
>>
>> [ECR ]: 0x00230400 => Misaligned r/w from 0x5fdab341
>> [EFA ]: 0x5fdab341
>> [BLINK ]: 0x20032a18
>> [ERET ]: 0x20032a3c
>> @off 0x12a3c in [/lib/libuClibc-0.9.34-git.so]
>> VMA: 0x20020000 to 0x20062000
>> [STAT32]: 0x00000086 : U E2 E1
>> BTA: 0x20046014 SP: 0x5fdab260 FP: 0x00000000
>> LPS: 0x20046064 LPE: 0x20046068 LPC: 0x00000000
>> r00: 0x5fdab341 r01: 0x00000005 r02: 0x00000015
>> r03: 0x00000000 r04: 0x5fdab358 r05: 0x00000000
>> r06: 0x0a0a0a00 r07: 0x00000000 r08: 0x0000003f
>> r09: 0x20067050 r10: 0x00000000 r11: 0x00000014
>> r12: 0x00000001 r13: 0x00000000 r14: 0x20060660
>> r15: 0x20060661 r16: 0x00000006 r17: 0x5fdab371
>> r18: 0x00000018 r19: 0x5fdab2b4 r20: 0x00020000
>> r21: 0x00000000 r22: 0x00029068 r23: 0x5fdab371
>> r24: 0x00010000 r25: 0x00000000
>> --->8---
>>
>> To fix this problem we'll re-introduce tmp buffer force alignment
>> before config parser invocation.
>>
>> Signed-off-by: Alexey Brodkin <abrodkin at synopsys.com>
>> Cc: Vineet Gupta <vgupta at synopsys.com>
>> Cc: Waldemar Brodkorb <wbx at openadk.org>
>> ---
>> libc/inet/resolv.c | 8 +++++++-
>> 1 file changed, 7 insertions(+), 1 deletion(-)
>>
>> diff --git a/libc/inet/resolv.c b/libc/inet/resolv.c
>> index cfc1eee..7c678ce 100644
>> --- a/libc/inet/resolv.c
>> +++ b/libc/inet/resolv.c
>> @@ -1614,7 +1614,7 @@ int __read_etc_hosts_r(
>> sizeof(struct in_addr)
>> #endif
>> ;
>> - int ret = HOST_NOT_FOUND;
>> + int i, ret = HOST_NOT_FOUND;
>>
>> *h_errnop = NETDB_INTERNAL;
>> if (buflen < aliaslen
>> @@ -1626,6 +1626,12 @@ int __read_etc_hosts_r(
>> *result = NULL;
>> return errno;
>> }
>> +
>> + /* make sure pointer is aligned */
>> + i = ALIGN_BUFFER_OFFSET(buf);
>> + buf += i;
>> + buflen -= i;
>
>Is this safe against the possibility of buflen<i? Otherwise you're
>introducing a serious overflow.
The lines below read:
*h_errnop = NETDB_INTERNAL;
if (buflen < aliaslen || (buflen - aliaslen) < BUFSZ + 1)
return ERANGE;
So ISTM it should be OK.
More information about the uClibc
mailing list