diff mbox series

[v2] libsepol: fix endianity in ibpkey range checks

Message ID 20181018074957.24080-1-omosnace@redhat.com (mailing list archive)
State Not Applicable
Headers show
Series [v2] libsepol: fix endianity in ibpkey range checks | expand

Commit Message

Ondrej Mosnacek Oct. 18, 2018, 7:49 a.m. UTC
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 <omosnace@redhat.com>
---
 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

Comments

William Roberts Oct. 18, 2018, 4:15 p.m. UTC | #1
On Thu, Oct 18, 2018 at 12:50 AM Ondrej Mosnacek <omosnace@redhat.com> wrote:
>
> 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 <omosnace@redhat.com>
> ---
>  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
>

Acked-by: William Roberts william.c.roberts@intel.com
diff mbox series

Patch

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)