File opensc-fixed-out-of-bounds-writes.patch of Package opensc.29262
From 360e95d45ac4123255a4c796db96337f332160ad Mon Sep 17 00:00:00 2001
From: Frank Morgner <frankmorgner@gmail.com>
Date: Fri, 25 May 2018 23:34:14 +0200
Subject: [PATCH] fixed out of bounds writes
Thanks to Eric Sesterhenn from X41 D-SEC GmbH
for reporting the problems.
---
src/libopensc/card-cac.c | 2 +-
src/libopensc/card-epass2003.c | 3 ++-
src/libopensc/card-muscle.c | 7 +++++--
src/libopensc/card-tcos.c | 6 +++---
src/libopensc/pkcs15-esteid.c | 2 +-
src/libopensc/pkcs15-gemsafeV1.c | 2 +-
src/libopensc/pkcs15-sc-hsm.c | 14 ++++++++------
src/libopensc/sc.c | 2 +-
src/tools/cryptoflex-tool.c | 5 +++--
src/tools/egk-tool.c | 2 +-
src/tools/util.c | 5 +++--
11 files changed, 29 insertions(+), 21 deletions(-)
Index: opensc-0.13.0/src/libopensc/card-epass2003.c
===================================================================
--- opensc-0.13.0.orig/src/libopensc/card-epass2003.c
+++ opensc-0.13.0/src/libopensc/card-epass2003.c
@@ -800,7 +800,7 @@ decrypt_response(unsigned char *in, size
while (0x80 != plaintext[in_len - 2] && (in_len - 2 > 0))
in_len--;
- if (2 == in_len)
+ if (2 == in_len || *out_len < in_len - 2)
return -1;
memcpy(out, plaintext, in_len - 2);
@@ -820,6 +820,7 @@ epass2003_sm_unwrap_apdu(struct sc_card
r = sc_check_sw(card, sm->sw1, sm->sw2);
if (r == SC_SUCCESS) {
if (g_sm) {
+ len = plain->resplen;
if (0 != decrypt_response(sm->resp, sm->resplen, plain->resp, &len))
return SC_ERROR_CARD_CMD_FAILED;
}
Index: opensc-0.13.0/src/libopensc/card-muscle.c
===================================================================
--- opensc-0.13.0.orig/src/libopensc/card-muscle.c
+++ opensc-0.13.0/src/libopensc/card-muscle.c
@@ -505,7 +505,9 @@ static int muscle_list_files(sc_card_t *
mscfs_check_cache(priv->fs);
for(x = 0; x < fs->cache.size; x++) {
- u8* oid= fs->cache.array[x].objectId.id;
+ u8* oid = fs->cache.array[x].objectId.id;
+ if (bufLen < 2)
+ break;
sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL,
"FILE: %02X%02X%02X%02X\n",
oid[0],oid[1],oid[2],oid[3]);
@@ -514,7 +516,8 @@ static int muscle_list_files(sc_card_t *
buf[1] = oid[3];
if(buf[0] == 0x00 && buf[1] == 0x00) continue; /* No directories/null names outside of root */
buf += 2;
- count+=2;
+ count += 2;
+ bufLen -= 2;
}
}
return count;
Index: opensc-0.13.0/src/libopensc/card-tcos.c
===================================================================
--- opensc-0.13.0.orig/src/libopensc/card-tcos.c
+++ opensc-0.13.0/src/libopensc/card-tcos.c
@@ -405,7 +405,7 @@ static int tcos_select_file(sc_card_t *c
file->path = *in_path;
for(i=2; i+1<apdu.resplen && i+1+apdu.resp[i+1]<apdu.resplen; i+=2+apdu.resp[i+1]){
- int j, len=apdu.resp[i+1];
+ size_t j, len=apdu.resp[i+1];
unsigned char type=apdu.resp[i], *d=apdu.resp+i+2;
switch (type) {
@@ -429,8 +429,8 @@ static int tcos_select_file(sc_card_t *c
file->id = (d[0]<<8) | d[1];
break;
case 0x84:
- memcpy(file->name, d, len);
- file->namelen = len;
+ file->namelen = MIN(sizeof file->name, len);
+ memcpy(file->name, d, file->namelen);
break;
case 0x86:
sc_file_set_sec_attr(file, d, len);
Index: opensc-0.13.0/src/libopensc/pkcs15-esteid.c
===================================================================
--- opensc-0.13.0.orig/src/libopensc/pkcs15-esteid.c
+++ opensc-0.13.0/src/libopensc/pkcs15-esteid.c
@@ -78,7 +78,7 @@ sc_pkcs15emu_esteid_init (sc_pkcs15_card
/* read the serial (document number) */
r = sc_read_record (card, SC_ESTEID_PD_DOCUMENT_NR, buff, sizeof(buff), SC_RECORD_BY_REC_NR);
SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "read document number failed");
- buff[r] = '\0';
+ buff[MIN((size_t) r, (sizeof buff)-1)] = '\0';
set_string (&p15card->tokeninfo->serial_number, (const char *) buff);
p15card->tokeninfo->flags = SC_PKCS15_TOKEN_PRN_GENERATION
Index: opensc-0.13.0/src/libopensc/pkcs15-gemsafeV1.c
===================================================================
--- opensc-0.13.0.orig/src/libopensc/pkcs15-gemsafeV1.c
+++ opensc-0.13.0/src/libopensc/pkcs15-gemsafeV1.c
@@ -62,6 +62,8 @@ typedef struct cdata_st {
int obj_flags;
} cdata;
+const unsigned int gemsafe_cert_max = 12;
+
const cdata gemsafe_cert[] = {
{"DS certificate", 0, "3F0016000004","45", SC_PKCS15_CO_FLAG_MODIFIABLE},
{NULL, 0, NULL, 0, 0}
@@ -161,7 +163,7 @@ static int gemsafe_get_cert_len(sc_card_
* the key_ref in the opensc.conf with flag = n.
*/
ind = 2; /* skip length */
- while (ibuf[ind] == 0x01) {
+ while (ibuf[ind] == 0x01 && i < gemsafe_cert_max) {
if (ibuf[ind+1] == 0xFE) {
*key_ref = ibuf[ind+4];
sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Using key_ref %d found at offset %d\n",
Index: opensc-0.13.0/src/libopensc/sc.c
===================================================================
--- opensc-0.13.0.orig/src/libopensc/sc.c
+++ opensc-0.13.0/src/libopensc/sc.c
@@ -573,7 +573,7 @@ int sc_file_set_sec_attr(sc_file_t *file
u8 *tmp;
assert(sc_file_valid(file));
- if (sec_attr == NULL) {
+ if (sec_attr == NULL || sec_attr_len) {
if (file->sec_attr != NULL)
free(file->sec_attr);
file->sec_attr = NULL;
Index: opensc-0.13.0/src/tools/cryptoflex-tool.c
===================================================================
--- opensc-0.13.0.orig/src/tools/cryptoflex-tool.c
+++ opensc-0.13.0/src/tools/cryptoflex-tool.c
@@ -27,6 +27,7 @@
#include <openssl/err.h>
#include "libopensc/pkcs15.h"
+#include "libopensc/internal.h"
#include "common/compat_strlcpy.h"
#include "util.h"
@@ -315,7 +316,7 @@ static int read_public_key(RSA *rsa)
fprintf(stderr, "Unable to select public key file: %s\n", sc_strerror(r));
return 2;
}
- bufsize = file->size;
+ bufsize = MIN(file->size, sizeof buf);
sc_file_free(file);
r = sc_read_binary(card, 0, buf, bufsize, 0);
if (r < 0) {
@@ -366,7 +367,7 @@ static int read_private_key(RSA *rsa)
e = sc_file_get_acl_entry(file, SC_AC_OP_READ);
if (e == NULL || e->method == SC_AC_NEVER)
return 10;
- bufsize = file->size;
+ bufsize = MIN(file->size, sizeof buf);
sc_file_free(file);
r = sc_read_binary(card, 0, buf, bufsize, 0);
if (r < 0) {
Index: opensc-0.13.0/src/tools/util.c
===================================================================
--- opensc-0.13.0.orig/src/tools/util.c
+++ opensc-0.13.0/src/tools/util.c
@@ -311,10 +311,11 @@ const char * util_acl_to_str(const sc_ac
strcpy(buf, "????");
break;
}
- strcat(line, buf);
- strcat(line, " ");
+ strncat(line, buf, sizeof line);
+ strncat(line, " ", sizeof line);
e = e->next;
}
+ line[(sizeof line)-1] = '\0'; /* make sure it's NUL terminated */
line[strlen(line)-1] = 0; /* get rid of trailing space */
return line;
}