We need to convert from little-endian before dong range checks on the
ibpkey port numbers, otherwise we would be checking a wrong value on
big-endian systems.

Fixes: 9fbb3112769a ("libsepol: Add ibpkey ocontext handling")
Signed-off-by: Ondrej Mosnacek <[email protected]>
---
 libsepol/src/policydb.c | 21 ++++++++++++++++-----
 1 file changed, 16 insertions(+), 5 deletions(-)

Changes in v2:
 - defer assignment to 16-bit struct fields to after the range check

diff --git a/libsepol/src/policydb.c b/libsepol/src/policydb.c
index a6d76ca3..db6765ba 100644
--- a/libsepol/src/policydb.c
+++ b/libsepol/src/policydb.c
@@ -2828,21 +2828,32 @@ static int ocontext_read_selinux(struct 
policydb_compat_info *info,
                                    (&c->context[1], p, fp))
                                        return -1;
                                break;
-                       case OCON_IBPKEY:
+                       case OCON_IBPKEY: {
+                               uint32_t pkey_lo, pkey_hi;
+
                                rc = next_entry(buf, fp, sizeof(uint32_t) * 4);
-                               if (rc < 0 || buf[2] > 0xffff || buf[3] > 
0xffff)
+                               if (rc < 0)
+                                       return -1;
+
+                               pkey_lo = le32_to_cpu(buf[2]);
+                               pkey_hi = le32_to_cpu(buf[3]);
+
+                               if (pkey_lo > UINT16_MAX || pkey_hi > 
UINT16_MAX)
                                        return -1;
 
+                               c->u.ibpkey.low_pkey  = pkey_lo;
+                               c->u.ibpkey.high_pkey = pkey_hi;
+
+                               /* we want c->u.ibpkey.subnet_prefix in network
+                                * (big-endian) order, just memcpy it */
                                memcpy(&c->u.ibpkey.subnet_prefix, buf,
                                       sizeof(c->u.ibpkey.subnet_prefix));
 
-                               c->u.ibpkey.low_pkey = le32_to_cpu(buf[2]);
-                               c->u.ibpkey.high_pkey = le32_to_cpu(buf[3]);
-
                                if (context_read_and_validate
                                    (&c->context[0], p, fp))
                                        return -1;
                                break;
+                       }
                        case OCON_IBENDPORT:
                                rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
                                if (rc < 0)
-- 
2.17.2

_______________________________________________
Selinux mailing list
[email protected]
To unsubscribe, send email to [email protected].
To get help, send an email containing "help" to [email protected].

Reply via email to