mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-08 14:20:07 +00:00
resolv: Fix a few unaligned accesses to fields in HEADER
After refactoring the alloca usage in 40c0add7d4
("resolve: Remove
__res_context_query alloca usage") a few unaligned accesses to HEADER
fields surfaced. These unaligned accesses led to problems when running
the resolv test suite on sparc32-linux (leon) as many tests failed due to
SIGBUS crashes.
The issue(s) occured during T_QUERY_A_AND_AAAA queries as the second query
now can start on an unaligned address (previously it was explicitly aligned).
With this patch the unaligned accesses are now fixed by using the
UHEADER instead to ensure the fields are accessed with byte
loads/stores.
The patch has been verfied by running the resolv test suite on sparc32
and x86_64.
Signed-off-by: Ludwig Rydberg <ludwig.rydberg@gaisler.com>
Signed-off-by: Andreas Larsson <andreas@gaisler.com>
Reviewed-by: Florian Weimer <fweimer@redhat.com>
This commit is contained in:
parent
4753e92868
commit
fc039ce850
@ -100,7 +100,7 @@ __res_context_mkquery (struct resolv_context *ctx, int op, const char *dname,
|
|||||||
int class, int type, const unsigned char *data,
|
int class, int type, const unsigned char *data,
|
||||||
unsigned char *buf, int buflen)
|
unsigned char *buf, int buflen)
|
||||||
{
|
{
|
||||||
HEADER *hp;
|
UHEADER *hp;
|
||||||
unsigned char *cp;
|
unsigned char *cp;
|
||||||
int n;
|
int n;
|
||||||
unsigned char *dnptrs[20], **dpp, **lastdnptr;
|
unsigned char *dnptrs[20], **dpp, **lastdnptr;
|
||||||
@ -112,7 +112,7 @@ __res_context_mkquery (struct resolv_context *ctx, int op, const char *dname,
|
|||||||
if ((buf == NULL) || (buflen < HFIXEDSZ))
|
if ((buf == NULL) || (buflen < HFIXEDSZ))
|
||||||
return -1;
|
return -1;
|
||||||
memset (buf, 0, HFIXEDSZ);
|
memset (buf, 0, HFIXEDSZ);
|
||||||
hp = (HEADER *) buf;
|
hp = (UHEADER *) buf;
|
||||||
/* We randomize the IDs every time. The old code just incremented
|
/* We randomize the IDs every time. The old code just incremented
|
||||||
by one after the initial randomization which still predictable if
|
by one after the initial randomization which still predictable if
|
||||||
the application does multiple requests. */
|
the application does multiple requests. */
|
||||||
@ -250,7 +250,7 @@ __res_nopt (struct resolv_context *ctx,
|
|||||||
int n0, unsigned char *buf, int buflen, int anslen)
|
int n0, unsigned char *buf, int buflen, int anslen)
|
||||||
{
|
{
|
||||||
uint16_t flags = 0;
|
uint16_t flags = 0;
|
||||||
HEADER *hp = (HEADER *) buf;
|
UHEADER *hp = (UHEADER *) buf;
|
||||||
unsigned char *cp = buf + n0;
|
unsigned char *cp = buf + n0;
|
||||||
unsigned char *ep = buf + buflen;
|
unsigned char *ep = buf + buflen;
|
||||||
|
|
||||||
|
@ -95,14 +95,14 @@ __libc_res_queriesmatch (const unsigned char *buf1, const unsigned char *eom1,
|
|||||||
|
|
||||||
/* Only header section present in replies to dynamic update
|
/* Only header section present in replies to dynamic update
|
||||||
packets. */
|
packets. */
|
||||||
if ((((HEADER *) buf1)->opcode == ns_o_update) &&
|
if ((((UHEADER *) buf1)->opcode == ns_o_update) &&
|
||||||
(((HEADER *) buf2)->opcode == ns_o_update))
|
(((UHEADER *) buf2)->opcode == ns_o_update))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
/* Note that we initially do not convert QDCOUNT to the host byte
|
/* Note that we initially do not convert QDCOUNT to the host byte
|
||||||
order. We can compare it with the second buffer's QDCOUNT
|
order. We can compare it with the second buffer's QDCOUNT
|
||||||
value without doing this. */
|
value without doing this. */
|
||||||
int qdcount = ((HEADER *) buf1)->qdcount;
|
int qdcount = ((UHEADER *) buf1)->qdcount;
|
||||||
if (qdcount != ((UHEADER *) buf2)->qdcount)
|
if (qdcount != ((UHEADER *) buf2)->qdcount)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user