From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 4BA604401B; Mon, 13 May 2024 17:37:52 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id BD8C64067A; Mon, 13 May 2024 17:37:51 +0200 (CEST) Received: from mail-pf1-f199.google.com (mail-pf1-f199.google.com [209.85.210.199]) by mails.dpdk.org (Postfix) with ESMTP id 1C3ED402CD for ; Mon, 13 May 2024 17:37:51 +0200 (CEST) Received: by mail-pf1-f199.google.com with SMTP id d2e1a72fcca58-6f474d00351so2579957b3a.3 for ; Mon, 13 May 2024 08:37:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=interfacemasters.com; s=google; t=1715614670; x=1716219470; darn=dpdk.org; h=to:subject:message-id:date:from:mime-version:from:to:cc:subject :date:message-id:reply-to; bh=KFhpF9RrJhGraUlz9uUvuhyhQdJiI+Rnwd+Hrioy9TA=; b=WdBXbBVWo66I7XyY5dMZEVpQ19BNlJxtOmtRw7H1qtvXkn+A9gOps2vUIL27mrwk4Z P/r1qotaN9+yNiiNPfZ+aENA3n9rergvws06h/1PEF1btC+f6ZWp7JnHuPDxf5wc1JYP 5p0zkih7KE1r9zMwUxYDkWUMpIVxMBOEcZLt0= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1715614670; x=1716219470; h=to:subject:message-id:date:from:mime-version:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=KFhpF9RrJhGraUlz9uUvuhyhQdJiI+Rnwd+Hrioy9TA=; b=nXWWzEHchm0+qKwy2ehKbDQ+YQWsrjrZIgdLxiGG8P0PrTlolG9zTaQj+yNS0kLPGH BNZkzOcFZ2DqqwdbMDo9RLUZzNrF2EbXTnjeSWQIZb0DuEEyQ9ua0B2COZgptnYSbRmQ LO0v3B/PhemK+L3NcWClHcjnX9dWpGFtKHj7mrqhh7I5VFidP3jOs/9R6quYcuyHWlQ2 WcQxDRGbJIq28dUAOrOz8bdylR9P3ZLmbFvPTcSFAKb4HqDCcAE8Xvp4LopJToGfyhDx OPTQJwvcgdbHrlh0AFx40Q5W6bPaARUjMlWTBEU7ZzR1cYwTLVeOrB84LDK8qV2GhQqZ +LeQ== X-Gm-Message-State: AOJu0Yy5i+a7oCduSX8WN6WCyr0lP2XXj+FIE160a46zdYmy4IYcBatn ITxe0gPa83xs/7gsuO/247R9rFcgwi0jfF8PSZID0b1HECrVAG4vOVuOpWjKJFY83aeQHGXxALY Wm2488RzTtmo84/Y1cCQ+7qrOXGm94pE6kbmYi9qPYWF64MXr X-Google-Smtp-Source: AGHT+IG/7fwzdxxB0OobvY741eV/BNwEm2kjkVCfZUwOjcNnRA2bV/CUGojZ4w0pQ7+97Xg8KusnIcAWk6NxSdsZloQ= X-Received: by 2002:a05:6a20:1592:b0:1af:597f:4970 with SMTP id adf61e73a8af0-1afde0d4c9bmr11219248637.24.1715614669777; Mon, 13 May 2024 08:37:49 -0700 (PDT) MIME-Version: 1.0 From: Oleksandr Nahnybida Date: Mon, 13 May 2024 18:37:38 +0300 Message-ID: Subject: rte_mempool_create/alloc_seg crash To: dev@dpdk.org Content-Type: multipart/alternative; boundary="000000000000f6ccf7061857aa29" X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org --000000000000f6ccf7061857aa29 Content-Type: text/plain; charset="UTF-8" Hi All, I have a crash inside of rte_mempool_create which happens when I allocate multiple big mem pools(multiple GB each), in particular first argument of function alloc_seg(LINUX) is null, I investigated a little bit and it seems like there is a bug inside of rte_fbarray_find_next_n_free. Inside of alloc_seg_walk rte_fbarray_find_next_n_free is used to find if the current memseg_arr has n (6 in my case) consecutive free pages, it does not in reality, but rte_fbarray_find_next_n_free returns that it does and we read out of bounds from memseg_arr which leads to null argument. Bug is in find_next_n function called from rte_fbarray_find_next_n_free, first = MASK_LEN_TO_IDX(start); first_mod = MASK_LEN_TO_MOD(start); ignore_msk = ~((1ULL << first_mod) - 1); // in my case first_mod is 0 and ignore_mask is all 1 last = MASK_LEN_TO_IDX(arr->len); last_mod = MASK_LEN_TO_MOD(arr->len); last_msk = ~(UINT64_MAX << last_mod); //arr->len is 32 (arr is memseg_arr) .....SKIP..... /* if we're looking for free spaces, invert the mask */ if (!used) // THIS IS TRUE cur_msk = ~cur_msk; /* combine current ignore mask with last index ignore mask */ if (msk_idx == last) // TRUE ignore_msk |= last_msk; // BUG HERE // Since ignore_mask is all 1, it just absorbs last_msk and in the end, last_msk doesn't matter, which then leads to an incorrect result because bits after 32 are treated as free space and not masked correctly by last_msk. /* if we have an ignore mask, ignore once */ if (ignore_msk) { cur_msk &= ignore_msk; ignore_msk = 0; // If there are multiple used_mask msk->n_masks this set to zero fixes the issue because when we get to BUG ignore_msk is already set to 0 and doesn't absosrb last_msk, but in my case, n_masks is 1. } I think ignore_msk |= last_msk; should be replaced by cur_msk &= last_msk; I tried this and dpdk doesn't crash anymore and seems to work fine, but I'd like someone else familiar with this code to take a look at this. Best Regards, Oleksandr --000000000000f6ccf7061857aa29 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Hi All,

I have a crash inside of rt= e_mempool_create which happens when I allocate multiple big mem pools(multi= ple GB each), in particular first argument of function alloc_seg(LINUX) is = null, I investigated a little bit and it seems like there is a bug inside o= f=C2=A0rte_fbarray_find_next_n_free.=C2=A0

Inside = of alloc_seg_walk=C2=A0rte_fbarray_find_next_n_free is used to find if the = current memseg_arr has n (6 in my case) consecutive free pages, it does not= in reality, but rte_fbarray_find_next_n_free returns that it does and we r= ead out of bounds from memseg_arr which leads to null argument.
<= br>
Bug is in find_next_n function called from=C2=A0rte_fbarray_f= ind_next_n_free,=C2=A0
=C2=A0
=C2=A0first =3D MASK_= LEN_TO_IDX(start);
first_mod =3D MASK_LEN_TO_MOD(start);
ignore_msk= =3D ~((1ULL << first_mod) - 1); // in my case first_mod is 0 and ign= ore_mask is all 1

=C2=A0last =3D MASK_LEN_TO_I= DX(arr->len);
last_mod =3D MASK_LEN_TO_MOD(arr->len);
last_ms= k =3D ~(UINT64_MAX << last_mod); //arr->len is 32 (arr is memseg_a= rr)

.....SKIP.....

= /* if we're looking for free spaces, invert the mask */
if (!used)= // THIS IS TRUE
cur_msk =3D ~cur_msk;

/* combine current ig= nore mask with last index ignore mask */
if (msk_idx =3D=3D last) // T= RUE
ignore_msk |=3D last_msk;=C2=A0 // BUG HERE
=C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0// Since igno= re_mask is all 1, it just absorbs last_msk and in the end, last_msk doesn&#= 39;t matter, which then leads to an incorrect result because bits after 32 = are treated as free space and not masked correctly by last_msk.=C2=A0
=


/* if we have an ignore mask, ignore once */
= if (ignore_msk) {
cur_msk &=3D ignore_msk;
ignore_msk =3D = 0; // If there are multiple used_mask=C2=A0msk->n_masks this set to zero= fixes the issue because when we get to BUG ignore_msk is already set to 0 = and doesn't absosrb=C2=A0last_msk, but in my case, n_masks is 1.
}=

I think=C2=A0 ignore_msk |=3D last_msk;=C2=A0= should be replaced by cur_msk &=3D last_msk; I tried this and dpdk doe= sn't crash anymore and seems to work=C2=A0fine, but I'd like someon= e else familiar with this code to take a look at this.=C2=A0

=
Best Regards,
Oleksandr

--000000000000f6ccf7061857aa29--