commit:     d37ba903d8d0c9c3d7de8280b55229c23cebad18
Author:     Ulrich Müller <ulm <AT> gentoo <DOT> org>
AuthorDate: Tue Dec  8 16:56:52 2015 +0000
Commit:     Ulrich Müller <ulm <AT> gentoo <DOT> org>
CommitDate: Tue Dec  8 16:56:52 2015 +0000
URL:        https://gitweb.gentoo.org/dev/ulm.git/commit/?id=d37ba903

put.c: Avoid out of bounds stack read.

Fix the extract() function not to access unnecessary array elements;
this avoids an out-of-bounds read when called from btoe() or etob().
Change the insert() function to use similar logic as extract().

Bug: 567608

 patchsets/skey/1.1.5/14_all_extract-insert.patch | 84 ++++++++++++++++++++++++
 1 file changed, 84 insertions(+)

diff --git a/patchsets/skey/1.1.5/14_all_extract-insert.patch 
b/patchsets/skey/1.1.5/14_all_extract-insert.patch
new file mode 100644
index 0000000..62e3efc
--- /dev/null
+++ b/patchsets/skey/1.1.5/14_all_extract-insert.patch
@@ -0,0 +1,84 @@
+https://bugs.gentoo.org/567608
+Fix the extract() function not to access unnecessary array elements;
+this avoids an out-of-bounds read when called from btoe() or etob().
+Change the insert() function to use similar logic as extract().
+
+--- skey-1.1.5-orig/put.c
++++ skey-1.1.5/put.c
+@@ -2221,37 +2221,20 @@
+ 
+ static void insert(char *s, int x, int start, int length)
+ {
+-      unsigned char cl;
+-      unsigned char cc;
+-      unsigned char cr;
+       unsigned int y;
+-      int shift;
++      int end, i;
+ 
+       assert(length <= 11);
+       assert(start >= 0);
+       assert(length >= 0);
+       assert(start + length <= 66);
+ 
+-      shift = ((8 - ((start + length) % 8)) % 8);
+-      y = (int) x << shift;
+-      cl = (y >> 16) & 0xff;
+-      cc = (y >> 8) & 0xff;
+-      cr = y & 0xff;
+-      if (shift + length > 16) 
+-      {
+-              s[start / 8] |= cl;
+-              s[start / 8 + 1] |= cc;
+-              s[start / 8 + 2] |= cr;
+-      } 
+-      else if (shift + length > 8) 
+-      {
+-              s[start / 8] |= cc;
+-              s[start / 8 + 1] |= cr;
+-      } 
+-      else 
+-      {
+-              s[start / 8] |= cr;
+-      }
++      end = start + length - 1;
++      y = x << (7 - end % 8);
++      for (i = end / 8; i >= start / 8; i--) {
++              s[i] |= y & 0xff;
++              y >>= 8;
++      }
+ }
+ 
+ static void standard(char *word)
+@@ -2274,22 +2257,22 @@
+ /* Extract 'length' bits from the char array 's' starting with bit 'start' */
+ static unsigned int extract(char *s, int start, int length)
+ {
+-      unsigned char cl;
+-      unsigned char cc;
+-      unsigned char cr;
+       unsigned int x;
++      int end, i;
+ 
+       assert(length <= 11);
+       assert(start >= 0);
+       assert(length >= 0);
+       assert(start + length <= 66);
+ 
+-      cl = s[start / 8];
+-      cc = s[start / 8 + 1];
+-      cr = s[start / 8 + 2];
+-      x = ((int)(cl << 8 | cc) << 8 | cr);
+-      x = x >> (24 - (length + (start % 8)));
+-      x = (x & (0xffff >> (16 - length)));
++      end = start + length - 1;
++      x = 0;
++      for (i = start / 8; i <= end / 8; i++) {
++              x <<= 8;
++              x |= (unsigned char)s[i];
++      }
++      x >>= 7 - end % 8;
++      x &= (1 << length) - 1;
+ 
+       return x;
+ }

Reply via email to