The 'tc' program stores speeds in 64bit integers (unit is bytes per second) and sizes in uints (unit is bytes). We use different units: kilobytes per second and kibibytes and therefore we can parse values larger than 'tc' can handle. Reject those values right away. And while at it, fix the schema which assumed speed values fit into uint. Resolves: https://issues.redhat.com/browse/RHEL-45200 Signed-off-by: Michal Privoznik <mprivozn@xxxxxxxxxx> --- src/conf/netdev_bandwidth_conf.c | 17 +++++++++++++++++ src/conf/schemas/networkcommon.rng | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/conf/netdev_bandwidth_conf.c b/src/conf/netdev_bandwidth_conf.c index 9faa46a27f..f3f0b2209a 100644 --- a/src/conf/netdev_bandwidth_conf.c +++ b/src/conf/netdev_bandwidth_conf.c @@ -24,6 +24,16 @@ #define VIR_FROM_THIS VIR_FROM_NONE +#define CHECK_LIMIT(val, limit, name) \ + do { \ + if ((val) > (limit)) { \ + virReportError(VIR_ERR_OVERFLOW, \ + _("value '%1$llu' is too big for '%2$s' parameter, maximum is '%3$llu'"), \ + val, name, (unsigned long long) limit); \ + return -1; \ + } \ + } while (0) + static int virNetDevBandwidthParseRate(xmlNodePtr node, virNetDevBandwidthRate *rate, @@ -50,6 +60,11 @@ virNetDevBandwidthParseRate(xmlNodePtr node, &rate->floor)) < 0) return -1; + CHECK_LIMIT(rate->average, 1ULL << 54, "average"); + CHECK_LIMIT(rate->peak, 1ULL << 54, "peak"); + CHECK_LIMIT(rate->burst, UINT_MAX >> 10, "burst"); + CHECK_LIMIT(rate->floor, 1ULL << 54, "floor"); + if (!rc_average && !rc_floor) { virReportError(VIR_ERR_XML_DETAIL, "%s", _("Missing mandatory average or floor attributes")); @@ -71,6 +86,8 @@ virNetDevBandwidthParseRate(xmlNodePtr node, return 0; } +#undef CHECK_LIMIT + /** * virNetDevBandwidthParse: * @bandwidth: parsed bandwidth diff --git a/src/conf/schemas/networkcommon.rng b/src/conf/schemas/networkcommon.rng index 6df6d43f54..2b3f902ffe 100644 --- a/src/conf/schemas/networkcommon.rng +++ b/src/conf/schemas/networkcommon.rng @@ -180,7 +180,7 @@ </define> <define name="speed"> - <data type="unsignedInt"> + <data type="unsignedLong"> <param name="pattern">[0-9]+</param> <param name="minInclusive">1</param> </data> -- 2.44.2