]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
msg/async/dpdk: Fix the overflow while parsing dpdk coremask 32173/head
authorChunsong Feng <fengchunsong@huawei.com>
Fri, 29 Nov 2019 05:00:34 +0000 (13:00 +0800)
committerluo rixin <luorixin@huawei.com>
Thu, 19 Dec 2019 00:59:04 +0000 (08:59 +0800)
coremask supports up to 256 bits in DPDK19.05, using stoull in
dpdk::eal:init limits coremask up to 64 bits. Parse coremask by hex
character from low to high.

Fixes: https://tracker.ceph.com/issues/43044
Signed-off-by: Hu Ye <yehu5@huawei.com>
Signed-off-by: Chunsong Feng <fengchunsong@huawei.com>
Signed-off-by: luo rixin <luorixin@huawei.com>
src/msg/async/dpdk/dpdk_rte.cc

index 9f9d343b51a2d12b6df9a70552d416bbdcabc199..96cf896f82356c27c47041ca3a503599fdc1375a 100644 (file)
@@ -45,6 +45,36 @@ namespace dpdk {
     return std::bitset<CHAR_BIT * sizeof(n)>{n}.count();
   }
 
+  static int hex2bitcount(unsigned char c)
+  {
+    int val;
+
+    if (isdigit(c))
+      val = c - '0';
+    else if (isupper(c))
+      val = c - 'A' + 10;
+    else
+      val = c - 'a' + 10;
+    return bitcount(val);
+  }
+
+  static int coremask_bitcount(const char *buf)
+  {
+    int count = 0;
+
+    if (buf[0] == '0' && 
+        ((buf[1] == 'x') || (buf[1] == 'X')))
+      buf += 2;
+
+    for (int i = 0; buf[i] != '\0'; i++) {
+      char c = buf[i];
+      if (isxdigit(c) == 0)
+        return -EINVAL;
+      count += hex2bitcount(c);
+    }
+    return count;
+  }
+
   int eal::init(CephContext *c)
   {
     if (initialized) {
@@ -52,11 +82,12 @@ namespace dpdk {
     }
 
     bool done = false;
-    auto num = std::stoull(c->_conf.get_val<std::string>("ms_dpdk_coremask"),
-                           nullptr, 16);
-    unsigned int coremaskbit = bitcount(num);
+    auto coremask = c->_conf.get_val<std::string>("ms_dpdk_coremask");
+    int coremaskbit = coremask_bitcount(coremask.c_str());
 
-    ceph_assert(coremaskbit > c->_conf->ms_async_op_threads);
+    if (coremaskbit <= 0
+        || static_cast<uint64_t>(coremaskbit) < c->_conf->ms_async_op_threads)
+      return -EINVAL;
 
     t = std::thread([&]() {
       // TODO: Inherit these from the app parameters - "opts"