lynxis lazus has uploaded this change for review. ( 
https://gerrit.osmocom.org/c/libosmocore/+/43178?usp=email )


Change subject: sim/class_tables: add a size attribute
......................................................................

sim/class_tables: add a size attribute

osim_determine_apdu_case() doesn't know the size of the APDU,
this may result in reading invalid data outside the APDU.

Warning: this is an API breakage!

Instead adding a second function osim_determine_apdu_case_size()
could allow it. However because the class_tables.h also defines
the internal struct with the helper functions, which in turn has the same 
problem.

Change-Id: Iee50063399a0c3b29594e737f44aaa125fd06a2e
---
M include/osmocom/sim/class_tables.h
M src/sim/class_tables.c
M tests/sim/sim_test.c
3 files changed, 30 insertions(+), 16 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/78/43178/1

diff --git a/include/osmocom/sim/class_tables.h 
b/include/osmocom/sim/class_tables.h
index ec9ec49..2c7c206 100644
--- a/include/osmocom/sim/class_tables.h
+++ b/include/osmocom/sim/class_tables.h
@@ -20,7 +20,7 @@
 struct osim_cla_ins_case {
        uint8_t cla;
        uint8_t cla_mask;
-       int (*helper)(const struct osim_cla_ins_case *cic, const uint8_t *hdr);
+       int (*helper)(const struct osim_cla_ins_case *cic, const uint8_t *apdu, 
size_t apdu_size);
        const uint8_t *ins_tbl;
 };

@@ -36,4 +36,4 @@
 extern const struct osim_cla_ins_card_profile osim_uicc_sim_cic_profile;

 int osim_determine_apdu_case(const struct osim_cla_ins_card_profile *prof,
-                            const uint8_t *hdr);
+                            const uint8_t *apdu, size_t apdu_size);
diff --git a/src/sim/class_tables.c b/src/sim/class_tables.c
index 7500fc5..0a792c6 100644
--- a/src/sim/class_tables.c
+++ b/src/sim/class_tables.c
@@ -16,6 +16,7 @@
  */

 #include <stdint.h>
+#include <errno.h>
 #include <osmocom/core/utils.h>
 #include <osmocom/sim/class_tables.h>

@@ -139,13 +140,16 @@
 };

 static int uicc046_cla_ins_helper(const struct osim_cla_ins_case *cic,
-                                 const uint8_t *hdr)
+                                 const uint8_t *hdr, size_t hdr_size)
 {
-       uint8_t ins = hdr[1];
-       uint8_t p1 = hdr[2];
-       uint8_t p2 = hdr[3];
-       uint8_t p2_cmd;
+       uint8_t ins, p1, p2, p2_cmd;

+       if (hdr_size < 4)
+               return -EINVAL;
+
+       ins = hdr[1];
+       p1 = hdr[2];
+       p2 = hdr[3];
        switch (ins) {
        case 0x73:      /* MANAGE SECURE CHANNEL */
                if (p1 == 0x00)         /* Retrieve UICC Endpoints */
@@ -182,12 +186,16 @@
 }

 static int gp_cla_ins_helper(const struct osim_cla_ins_case *cic,
-                                 const uint8_t *hdr)
+                                 const uint8_t *hdr, size_t hdr_size)
 {
-       uint8_t ins = hdr[1];
-       uint8_t p1 = hdr[2];
-       uint8_t p3 = hdr[4];
+       uint8_t ins, p1, p3;

+       if (hdr_size < 5)
+               return -EINVAL;
+
+       ins = hdr[1];
+       p1 = hdr[2];
+       p3 = hdr[4];
        switch (ins) {
        case 0xE2:      /* STORE DATA */
                switch (p1 & 0x01) {
@@ -394,13 +402,17 @@
 };

 int osim_determine_apdu_case(const struct osim_cla_ins_card_profile *prof,
-                            const uint8_t *hdr)
+                            const uint8_t *apdu, size_t apdu_len)
 {
-       uint8_t cla = hdr[0];
-       uint8_t ins = hdr[1];
+       uint8_t cla, ins;
        int i;
        int rc;

+       if (apdu_len < 4)
+               return -EINVAL;
+
+       cla = apdu[0];
+       ins = apdu[1];
        for (i = 0; i < prof->cic_arr_size; i++) {
                const struct osim_cla_ins_case *cic = &prof->cic_arr[i];
                if ((cla & cic->cla_mask) != cic->cla)
@@ -408,7 +420,8 @@
                rc = cic->ins_tbl[ins];
                switch (rc) {
                case 0x80:
-                       return cic->helper(cic, hdr);
+                       /* the length of the hdr is unknown */
+                       return cic->helper(cic, apdu, apdu_len);
                case 0x00:
                        /* continue with further cic, rather than abort
                         * now */
diff --git a/tests/sim/sim_test.c b/tests/sim/sim_test.c
index ab5d2be..801c559 100644
--- a/tests/sim/sim_test.c
+++ b/tests/sim/sim_test.c
@@ -19,6 +19,7 @@
 #include <string.h>

 #include <osmocom/sim/sim.h>
+#include <osmocom/core/utils.h>
 #include <osmocom/sim/class_tables.h>

 const uint8_t sim_sel_mf[] = { 0xA0, 0xA4, 0x00, 0x00, 0x02, 0x3F, 0x00 };
@@ -35,7 +36,7 @@
 #define APDU_CASE_ASSERT(x, y)                         \
        do {                                            \
                printf("Testing " #x "\n");             \
-               int rc = osim_determine_apdu_case(&osim_uicc_sim_cic_profile, 
x);       \
+               int rc = osim_determine_apdu_case(&osim_uicc_sim_cic_profile, 
x, ARRAY_SIZE(x));        \
                if (rc != y)                                                    
\
                        printf("%d (actual) != %d (intended)\n", rc, y);        
\
                OSMO_ASSERT(rc == y);                                           
\

--
To view, visit https://gerrit.osmocom.org/c/libosmocore/+/43178?usp=email
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings?usp=email

Gerrit-MessageType: newchange
Gerrit-Project: libosmocore
Gerrit-Branch: master
Gerrit-Change-Id: Iee50063399a0c3b29594e737f44aaa125fd06a2e
Gerrit-Change-Number: 43178
Gerrit-PatchSet: 1
Gerrit-Owner: lynxis lazus <[email protected]>

Reply via email to