diff options
author | Werner Koch <wk@gnupg.org> | 2015-02-11 10:27:57 +0100 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2015-02-11 10:28:25 +0100 |
commit | 2183683bd633818dd031b090b5530951de76f392 (patch) | |
tree | af283f4f329a140b76df6f7e83dce7ebb07aabb8 /scd | |
parent | gpg: Prevent an invalid memory read using a garbled keyring. (diff) | |
download | gnupg2-2183683bd633818dd031b090b5530951de76f392.tar.xz gnupg2-2183683bd633818dd031b090b5530951de76f392.zip |
Use inline functions to convert buffer data to scalars.
* common/host2net.h (buf16_to_ulong, buf16_to_uint): New.
(buf16_to_ushort, buf16_to_u16): New.
(buf32_to_size_t, buf32_to_ulong, buf32_to_uint, buf32_to_u32): New.
--
Commit 91b826a38880fd8a989318585eb502582636ddd8 was not enough to
avoid all sign extension on shift problems. Hanno Böck found a case
with an invalid read due to this problem. To fix that once and for
all almost all uses of "<< 24" and "<< 8" are changed by this patch to
use an inline function from host2net.h.
Signed-off-by: Werner Koch <wk@gnupg.org>
Diffstat (limited to 'scd')
-rw-r--r-- | scd/apdu.c | 40 | ||||
-rw-r--r-- | scd/app-nks.c | 3 | ||||
-rw-r--r-- | scd/app-openpgp.c | 3 | ||||
-rw-r--r-- | scd/ccid-driver.c | 2 |
4 files changed, 22 insertions, 26 deletions
diff --git a/scd/apdu.c b/scd/apdu.c index 4ec6b4d00..e5db4f096 100644 --- a/scd/apdu.c +++ b/scd/apdu.c @@ -59,6 +59,7 @@ #include "scdaemon.h" #include "exechelp.h" #endif /* GNUPG_MAJOR_VERSION != 1 */ +#include "host2net.h" #include "iso7816.h" #include "apdu.h" @@ -1047,15 +1048,14 @@ pcsc_get_status_wrapped (int slot, unsigned int *status) i? strerror (errno) : "premature EOF"); goto command_failed; } - len = (msgbuf[1] << 24) | (msgbuf[2] << 16) | (msgbuf[3] << 8 ) | msgbuf[4]; + len = buf_to_size_t (msgbuf+1); if (msgbuf[0] != 0x81 || len < 4) { log_error ("invalid response header from PC/SC received\n"); goto command_failed; } len -= 4; /* Already read the error code. */ - err = PCSC_ERR_MASK ((msgbuf[5] << 24) | (msgbuf[6] << 16) - | (msgbuf[7] << 8 ) | msgbuf[8]); + err = PCSC_ERR_MASK (buf32_to_ulong (msgbuf+5)); if (err) { log_error ("pcsc_status failed: %s (0x%lx)\n", @@ -1218,15 +1218,14 @@ pcsc_send_apdu_wrapped (int slot, unsigned char *apdu, size_t apdulen, i? strerror (errno) : "premature EOF"); goto command_failed; } - len = (msgbuf[1] << 24) | (msgbuf[2] << 16) | (msgbuf[3] << 8 ) | msgbuf[4]; + len = buf_to_size_t (msgbuf+1); if (msgbuf[0] != 0x81 || len < 4) { log_error ("invalid response header from PC/SC received\n"); goto command_failed; } len -= 4; /* Already read the error code. */ - err = PCSC_ERR_MASK ((msgbuf[5] << 24) | (msgbuf[6] << 16) - | (msgbuf[7] << 8 ) | msgbuf[8]); + err = PCSC_ERR_MASK (buf32_to_ulong (msgbuf+5)); if (err) { log_error ("pcsc_transmit failed: %s (0x%lx)\n", @@ -1359,15 +1358,14 @@ control_pcsc_wrapped (int slot, pcsc_dword_t ioctl_code, i? strerror (errno) : "premature EOF"); goto command_failed; } - len = (msgbuf[1] << 24) | (msgbuf[2] << 16) | (msgbuf[3] << 8 ) | msgbuf[4]; + len = buf32_to_size_t (msgbuf+1); if (msgbuf[0] != 0x81 || len < 4) { log_error ("invalid response header from PC/SC received\n"); goto command_failed; } len -= 4; /* Already read the error code. */ - err = PCSC_ERR_MASK ((msgbuf[5] << 24) | (msgbuf[6] << 16) - | (msgbuf[7] << 8 ) | msgbuf[8]); + err = PCSC_ERR_MASK (buf32_to_ulong (msgbuf+5)); if (err) { log_error ("pcsc_control failed: %s (0x%lx)\n", @@ -1497,15 +1495,14 @@ close_pcsc_reader_wrapped (int slot) i? strerror (errno) : "premature EOF"); goto command_failed; } - len = (msgbuf[1] << 24) | (msgbuf[2] << 16) | (msgbuf[3] << 8 ) | msgbuf[4]; + len = buf32_to_size_t (msgbuf+1); if (msgbuf[0] != 0x81 || len < 4) { log_error ("invalid response header from PC/SC received\n"); goto command_failed; } len -= 4; /* Already read the error code. */ - err = PCSC_ERR_MASK ((msgbuf[5] << 24) | (msgbuf[6] << 16) - | (msgbuf[7] << 8 ) | msgbuf[8]); + err = PCSC_ERR_MASK (buf32_to_ulong (msgbuf+5)); if (err) log_error ("pcsc_close failed: %s (0x%lx)\n", pcsc_error_string (err), err); @@ -1687,7 +1684,7 @@ reset_pcsc_reader_wrapped (int slot) i? strerror (errno) : "premature EOF"); goto command_failed; } - len = (msgbuf[1] << 24) | (msgbuf[2] << 16) | (msgbuf[3] << 8 ) | msgbuf[4]; + len = buf32_to_size_t (msgbuf+1); if (msgbuf[0] != 0x81 || len < 4) { log_error ("invalid response header from PC/SC received\n"); @@ -1701,8 +1698,7 @@ reset_pcsc_reader_wrapped (int slot) sw = SW_HOST_GENERAL_ERROR; goto command_failed; } - err = PCSC_ERR_MASK ((msgbuf[5] << 24) | (msgbuf[6] << 16) - | (msgbuf[7] << 8 ) | msgbuf[8]); + err = PCSC_ERR_MASK (buf32_to_ulong (msgbuf+5)); if (err) { log_error ("PC/SC RESET failed: %s (0x%lx)\n", @@ -1794,9 +1790,9 @@ pcsc_vendor_specific_init (int slot) if (l == 1) v = p[0]; else if (l == 2) - v = ((p[0] << 8) | p[1]); + v = buf16_to_uint (p); else if (l == 4) - v = ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]); + v = buf32_to_uint (p); if (code == FEATURE_VERIFY_PIN_DIRECT) reader_table[slot].pcsc.verify_ioctl = v; @@ -1855,9 +1851,9 @@ pcsc_vendor_specific_init (int slot) if (l == 1) v = p[0]; else if (l == 2) - v = ((p[1] << 8) | p[0]); + v = buf16_to_uint (p); else if (l == 4) - v = ((p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0]); + v = buf32_to_uint (p); if (tag == PCSCv2_PART10_PROPERTY_bMinPINSize) reader_table[slot].pcsc.pinmin = v; @@ -2151,7 +2147,7 @@ open_pcsc_reader_wrapped (const char *portstr) i? strerror (errno) : "premature EOF"); goto command_failed; } - len = (msgbuf[1] << 24) | (msgbuf[2] << 16) | (msgbuf[3] << 8 ) | msgbuf[4]; + len = buf32_to_size_t (msgbuf+1); if (msgbuf[0] != 0x81 || len < 4) { log_error ("invalid response header from PC/SC received\n"); @@ -2164,9 +2160,7 @@ open_pcsc_reader_wrapped (const char *portstr) (unsigned long)len); goto command_failed; } - err = PCSC_ERR_MASK ((msgbuf[5] << 24) | (msgbuf[6] << 16) - | (msgbuf[7] << 8 ) | msgbuf[8]); - + err = PCSC_ERR_MASK (buf32_to_ulong (msgbuf+5)); if (err) { log_error ("PC/SC OPEN failed: %s\n", pcsc_error_string (err)); diff --git a/scd/app-nks.c b/scd/app-nks.c index 19a33ed12..d0b96a906 100644 --- a/scd/app-nks.c +++ b/scd/app-nks.c @@ -56,6 +56,7 @@ #include "app-common.h" #include "tlv.h" #include "apdu.h" +#include "host2net.h" static char const aid_nks[] = { 0xD2, 0x76, 0x00, 0x00, 0x03, 0x01, 0x02 }; static char const aid_sigg[] = { 0xD2, 0x76, 0x00, 0x00, 0x66, 0x01 }; @@ -278,7 +279,7 @@ get_chv_status (app_t app, int sigg, int pwid) rc = -1; /* Error. */ else { - unsigned int sw = ((result[resultlen-2] << 8) | result[resultlen-1]); + unsigned int sw = buf16_to_uint (result+resultlen-2); if (sw == 0x6a88) rc = -2; /* No such PIN. */ diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index f68813bfd..6583fb278 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -67,6 +67,7 @@ #include "iso7816.h" #include "app-common.h" #include "tlv.h" +#include "host2net.h" /* A table describing the DOs of the card. */ @@ -876,7 +877,7 @@ send_fprtime_if_not_null (ctrl_t ctrl, const char *keyword, char numbuf1[50], numbuf2[50]; unsigned long value; - value = (stamp[0] << 24) | (stamp[1]<<16) | (stamp[2]<<8) | stamp[3]; + value = buf32_to_ulong (stamp); if (!value) return; sprintf (numbuf1, "%d", number); diff --git a/scd/ccid-driver.c b/scd/ccid-driver.c index fdfe1f510..1926f7115 100644 --- a/scd/ccid-driver.c +++ b/scd/ccid-driver.c @@ -290,7 +290,7 @@ static int send_escape_cmd (ccid_driver_t handle, const unsigned char *data, static unsigned int convert_le_u32 (const unsigned char *buf) { - return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24); + return buf[0] | (buf[1] << 8) | (buf[2] << 16) | ((unsigned int)buf[3] << 24); } |