diff options
author | Nick Clifton <nickc@redhat.com> | 2013-01-03 15:47:44 +0000 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2013-01-03 15:47:44 +0000 |
commit | 3ac12341d45931e06b4d68b6983d0128ee4fc110 (patch) | |
tree | 58cc09e03b58789409f7ceb7e5eb7924ffcb344d /bfd/elflink.c | |
parent | 5813901312c6f50e83ab185cef24fa822d0d628e (diff) | |
download | binutils-redhat-3ac12341d45931e06b4d68b6983d0128ee4fc110.tar.gz |
* elflink.c (get_value): Prevent the use of an undefined shift
operation. Add sanity checks.
Diffstat (limited to 'bfd/elflink.c')
-rw-r--r-- | bfd/elflink.c | 42 |
1 files changed, 30 insertions, 12 deletions
diff --git a/bfd/elflink.c b/bfd/elflink.c index 661b2eb196..6d80109c47 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -1,6 +1,6 @@ /* ELF linking support for BFD. Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, - 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 + 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc. This file is part of BFD, the Binary File Descriptor library. @@ -7917,31 +7917,49 @@ get_value (bfd_vma size, bfd *input_bfd, bfd_byte *location) { + int shift; bfd_vma x = 0; + /* Sanity checks. */ + BFD_ASSERT (chunksz <= sizeof (x) + && size >= chunksz + && chunksz != 0 + && (size % chunksz) == 0 + && input_bfd != NULL + && location != NULL); + + if (chunksz == sizeof (x)) + { + BFD_ASSERT (size == chunksz); + + /* Make sure that we do not perform an undefined shift operation. + We know that size == chunksz so there will only be one iteration + of the loop below. */ + shift = 0; + } + else + shift = 8 * chunksz; + for (; size; size -= chunksz, location += chunksz) { switch (chunksz) { - default: - case 0: - abort (); case 1: - x = (x << (8 * chunksz)) | bfd_get_8 (input_bfd, location); + x = (x << shift) | bfd_get_8 (input_bfd, location); break; case 2: - x = (x << (8 * chunksz)) | bfd_get_16 (input_bfd, location); + x = (x << shift) | bfd_get_16 (input_bfd, location); break; case 4: - x = (x << (8 * chunksz)) | bfd_get_32 (input_bfd, location); + x = (x << shift) | bfd_get_32 (input_bfd, location); break; - case 8: #ifdef BFD64 - x = (x << (8 * chunksz)) | bfd_get_64 (input_bfd, location); -#else - abort (); -#endif + case 8: + x = (x << shift) | bfd_get_64 (input_bfd, location); break; +#endif + default: + abort (); } } return x; |