diff options
author | Nick Clifton <nickc@redhat.com> | 2013-01-03 15:47:46 +0000 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2013-01-03 15:47:46 +0000 |
commit | 9b239e0e1fe535c1dd6aa6b7e7087cc50fb173ab (patch) | |
tree | b04d6f45083b212922037b171d671ad87f1e54a5 /bfd | |
parent | 50da2f25309df4445e736121024dc41dfe750995 (diff) | |
download | gdb-9b239e0e1fe535c1dd6aa6b7e7087cc50fb173ab.zip gdb-9b239e0e1fe535c1dd6aa6b7e7087cc50fb173ab.tar.gz gdb-9b239e0e1fe535c1dd6aa6b7e7087cc50fb173ab.tar.bz2 |
* elflink.c (get_value): Prevent the use of an undefined shift
operation. Add sanity checks.
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 6 | ||||
-rw-r--r-- | bfd/elflink.c | 42 |
2 files changed, 36 insertions, 12 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 88dfe1b..a643721 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,9 @@ +2013-01-03 Nickolai Zeldovich <nickolai@csail.mit.edu> + Nick Clifton <nickc@redhat.com> + + * elflink.c (get_value): Prevent the use of an undefined shift + operation. Add sanity checks. + 2013-01-02 Kaushik Phatak <kaushik.phatak@kpitcummins.com> * config.bfd (cr16*-*-uclinux*): New target support. diff --git a/bfd/elflink.c b/bfd/elflink.c index 661b2eb..6d80109 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; |