summaryrefslogtreecommitdiffstats
path: root/scd
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2015-02-11 10:27:57 +0100
committerWerner Koch <wk@gnupg.org>2015-02-11 10:28:25 +0100
commit2183683bd633818dd031b090b5530951de76f392 (patch)
treeaf283f4f329a140b76df6f7e83dce7ebb07aabb8 /scd
parentgpg: Prevent an invalid memory read using a garbled keyring. (diff)
downloadgnupg2-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.c40
-rw-r--r--scd/app-nks.c3
-rw-r--r--scd/app-openpgp.c3
-rw-r--r--scd/ccid-driver.c2
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);
}