summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--patchsets/skey/1.1.5/14_all_extract-insert.patch84
1 files changed, 84 insertions, 0 deletions
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;
+ }