Message ID | 1426116072-8003-1-git-send-email-abrodkin@synopsys.com |
---|---|
State | Accepted |
Commit | 8ee422cffbfd3e2a16265fe6680a8dde2f5e58fe |
Headers | show |
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@synopsys.com> > Cc: Vineet Gupta <vgupta@synopsys.com> > Cc: Waldemar Brodkorb <wbx@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. Rich
On March 14, 2015 4:06:03 PM GMT+01:00, Rich Felker <dalias@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@synopsys.com> >> Cc: Vineet Gupta <vgupta@synopsys.com> >> Cc: Waldemar Brodkorb <wbx@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.
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; + /* Layout in buf: * char *alias[MAXTOKENS] = {address, name, aliases...} * char **h_addr_list[1] = {*in[6]_addr, NULL}
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@synopsys.com> Cc: Vineet Gupta <vgupta@synopsys.com> Cc: Waldemar Brodkorb <wbx@openadk.org> --- libc/inet/resolv.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)