From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-qt1-f179.google.com (mail-qt1-f179.google.com [209.85.160.179]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EFC513859C9 for ; Wed, 15 Apr 2026 20:54:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.160.179 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776286498; cv=none; b=QvyiQRD/PLekAdm+jFcLrw5pkVggfSvRmlqnI9gccdYPkIrrPv0m66cdm0UIxUe6UoJZPdAkr7x0MIws6FpXF3pRODBnitOHrkYZ4abozfm7x2YLiaKsJkHAMSqOtEhKKrqE8Ek0hbHSfAYICNXGrpeTHuKRkJoj/OkRVAXQN54= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776286498; c=relaxed/simple; bh=CIig0oQq5yHGW+pYesGTtuB+dPuvghH25hD6RPj7nUY=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=U/ZcdFt16U71bOVtVill/vp4VE8PlQDo9Fk8WZwS24OdRhiq7sGEBIjRBzhrYO2pF+4M7bSL4p16MfzP1z/5sm5rQKOOQfs7QbmrmrL8MZX1T/eX42xdrS3C9/2hlG/9wTRwHoFDaEObsNTRTKFQVv0NHTzHWf7Jwgnl0j9GV9M= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=rYvP6ToX; arc=none smtp.client-ip=209.85.160.179 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="rYvP6ToX" Received: by mail-qt1-f179.google.com with SMTP id d75a77b69052e-50dedb18ea0so34944121cf.3 for ; Wed, 15 Apr 2026 13:54:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1776286496; x=1776891296; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=5wI9Om12pRgMIyRltB1FE+/OLTEU+POmfWziZVV+KeU=; b=rYvP6ToXuc9Ym/knEVfkwS/dZ5c9HuVkuq3uIDElWdeVOrPTbGaT2MyWgk4ojqGYL4 AlqyqND2SHga5Gqeev9hAKZ9CO/0ANb4EKyYCus/QPl2G3elveF3uGHUYhsWIgkFBtWB kJbg+6G+j2jfkglq8R2W4lw1JSdHXYdKvk+a5ou3/qcwwZ1pfV0hjd3MkcyqVlF5c0Fl xjQSnV8lieAKrMcx1KEwHCw5Y8D1zebRrIyjkVs5KnO1Ys3D6v2Wn+t6BkFbwzT51cbn c7Evd+88RN0SMF8s8JJzBAxuZpgEwHOOb62MjGA/lJZ3x+xfRUageFVNQ5eHkgnWNf84 BKVA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1776286496; x=1776891296; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=5wI9Om12pRgMIyRltB1FE+/OLTEU+POmfWziZVV+KeU=; b=EF/lfcV4s/0xUzbbZI5O6s3rp25RxODEHpG3hdiqnmK10oRMuOPcMdfzI4Qfd192sZ T5BNRlWcjApCfo0JFPapUdoFUMbeE9c4FkJK9MELwqP1cNlo6Sy8PNgm9yjeV7L1YXtS 65yEtHbVyUKIvJq/wdTd712G4nfvIBde7AuvV+qpmrRuDJgekszEIz7HbSri617K6wke zt0MJ0q0L4jn5iMgJlhApUivg+FsJPaKfh6uIwLPqnxcz2IfEKeiyj7iQBez7A8W5nm9 bWjmuu+0xK6s3zcp87wHMZwLGkmFxasouoNxrjc27khWyRkSfytHqOvi2QUmKMC8a/0D 1htA== X-Forwarded-Encrypted: i=1; AFNElJ81xENKHgP6hqweozlrztS9IXVbk6qYwo3dL68E14Tp1upHVDF0ZAirYB2gZKyMl2f2eC1VCMT8gXoSGDs=@vger.kernel.org X-Gm-Message-State: AOJu0YwNmXOHLw4Mybo1x/i6tsuF7lexa6uWV/x0PopOF7bu0saw4L2l VJU2ECEXrbtSWVsrgEuFBNI0T3MQqGY5dN0Cp6CGLlR5qnUJE3hqYYA+ X-Gm-Gg: AeBDietFYMZr6Y+wpCyGiihSf81GKBNpq5Qff7bLVa7rv2IiHQhv/uhcBU0npwSgX66 3lXMFjlrPnQ+R7sMhVgYuIbTl5yLEaB1O7ntzw4QifnNKc8HxnjUjiwZN6vctbClXm/1UwahqVP NfINnwEB8J0vklEK51d2mFg/kXAJiU881RsgAlMUHhkz0FtkGol1E+LzQSNtpImXqC0RX8p3Xsy NOelBjo1c3bADn20/hft2dpxC5DV2lKMLCxVHejflj8c2v/Tl0fWS1dMEgRuW77ILZF25rcGgdl iMALR58Kt2PgiP9GfwO0vAzp1i9BdG4eW6FMtFa7bmrzdufwXd4FgJv9+rLKs26QhBEns49+ui+ jhmV7wC8c4GXFKau715aCN+/RK/IX/mhMYsIOkdFvgowcpOEChPJqf40Y0p+4BiU8qPi60CoNEY rksBNMxP77+tsfZ+YF67tHT8yYJS/bJTct+STFzm1JisSyKnEgRxzwG94= X-Received: by 2002:a05:622a:4009:b0:50d:66b6:1564 with SMTP id d75a77b69052e-50dd5bc5171mr357041541cf.14.1776286495729; Wed, 15 Apr 2026 13:54:55 -0700 (PDT) Received: from localhost.localdomain ([104.39.116.151]) by smtp.gmail.com with ESMTPSA id d75a77b69052e-50e1ad9663bsm26078281cf.4.2026.04.15.13.54.54 (version=TLS1_3 cipher=TLS_CHACHA20_POLY1305_SHA256 bits=256/256); Wed, 15 Apr 2026 13:54:55 -0700 (PDT) From: Yuho Choi To: Vinicius Costa Gomes , Vinod Koul Cc: Dave Jiang , Frank Li , dmaengine@vger.kernel.org, linux-kernel@vger.kernel.org, Yuho Choi Subject: [PATCH v1] dmaengine: idxd: fix double free of wq, engine, and group structs Date: Wed, 15 Apr 2026 16:54:52 -0400 Message-ID: <20260415205452.67155-1-dbgh9129@gmail.com> X-Mailer: git-send-email 2.50.1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit The release callbacks for wq, engine, and group devices (idxd_conf_wq_release, idxd_conf_engine_release, idxd_conf_group_release) each call kfree() on the enclosing struct. The setup error paths and cleanup functions also call kfree() explicitly after put_device(), producing a double free whenever put_device() drops the reference count to zero and fires the release. In the setup functions, device_initialize() is called before device_add(), so the reference count is exactly 1 at the error sites. put_device() unconditionally fires the release, which frees the struct; the subsequent explicit kfree() then operates on freed memory. For idxd_setup_wqs(), the wq release callback also owns opcap_bmap and wqcfg. The error unwind additionally freed those fields explicitly before calling put_device(), causing further double frees on both. Remove the redundant explicit kfree() calls from all setup error paths and cleanup functions for wq, engine, and group structs, delegating sole ownership of those allocations to the release callbacks. Fixes: 7c5dd23e57c1 ("dmaengine: idxd: fix wq conf_dev 'struct device' lifetime") Fixes: 75b911309060 ("dmaengine: idxd: fix engine conf_dev lifetime") Fixes: defe49f96012 ("dmaengine: idxd: fix group conf_dev lifetime") Signed-off-by: Yuho Choi --- drivers/dma/idxd/init.c | 36 +++++------------------------------- 1 file changed, 5 insertions(+), 31 deletions(-) diff --git a/drivers/dma/idxd/init.c b/drivers/dma/idxd/init.c index f1cfc7790d950..4b827a3297564 100644 --- a/drivers/dma/idxd/init.c +++ b/drivers/dma/idxd/init.c @@ -159,18 +159,12 @@ static void idxd_cleanup_interrupts(struct idxd_device *idxd) static void idxd_clean_wqs(struct idxd_device *idxd) { - struct idxd_wq *wq; struct device *conf_dev; int i; for (i = 0; i < idxd->max_wqs; i++) { - wq = idxd->wqs[i]; - if (idxd->hw.wq_cap.op_config) - bitmap_free(wq->opcap_bmap); - kfree(wq->wqcfg); - conf_dev = wq_confdev(wq); + conf_dev = wq_confdev(idxd->wqs[i]); put_device(conf_dev); - kfree(wq); } bitmap_free(idxd->wq_enable_map); kfree(idxd->wqs); @@ -212,7 +206,6 @@ static int idxd_setup_wqs(struct idxd_device *idxd) rc = dev_set_name(conf_dev, "wq%d.%d", idxd->id, wq->id); if (rc < 0) { put_device(conf_dev); - kfree(wq); goto err_unwind; } @@ -227,7 +220,6 @@ static int idxd_setup_wqs(struct idxd_device *idxd) wq->wqcfg = kzalloc_node(idxd->wqcfg_size, GFP_KERNEL, dev_to_node(dev)); if (!wq->wqcfg) { put_device(conf_dev); - kfree(wq); rc = -ENOMEM; goto err_unwind; } @@ -235,9 +227,7 @@ static int idxd_setup_wqs(struct idxd_device *idxd) if (idxd->hw.wq_cap.op_config) { wq->opcap_bmap = bitmap_zalloc(IDXD_MAX_OPCAP_BITS, GFP_KERNEL); if (!wq->opcap_bmap) { - kfree(wq->wqcfg); put_device(conf_dev); - kfree(wq); rc = -ENOMEM; goto err_unwind; } @@ -252,13 +242,8 @@ static int idxd_setup_wqs(struct idxd_device *idxd) err_unwind: while (--i >= 0) { - wq = idxd->wqs[i]; - if (idxd->hw.wq_cap.op_config) - bitmap_free(wq->opcap_bmap); - kfree(wq->wqcfg); - conf_dev = wq_confdev(wq); + conf_dev = wq_confdev(idxd->wqs[i]); put_device(conf_dev); - kfree(wq); } bitmap_free(idxd->wq_enable_map); @@ -270,15 +255,12 @@ static int idxd_setup_wqs(struct idxd_device *idxd) static void idxd_clean_engines(struct idxd_device *idxd) { - struct idxd_engine *engine; struct device *conf_dev; int i; for (i = 0; i < idxd->max_engines; i++) { - engine = idxd->engines[i]; - conf_dev = engine_confdev(engine); + conf_dev = engine_confdev(idxd->engines[i]); put_device(conf_dev); - kfree(engine); } kfree(idxd->engines); } @@ -313,7 +295,6 @@ static int idxd_setup_engines(struct idxd_device *idxd) rc = dev_set_name(conf_dev, "engine%d.%d", idxd->id, engine->id); if (rc < 0) { put_device(conf_dev); - kfree(engine); goto err; } @@ -324,10 +305,8 @@ static int idxd_setup_engines(struct idxd_device *idxd) err: while (--i >= 0) { - engine = idxd->engines[i]; - conf_dev = engine_confdev(engine); + conf_dev = engine_confdev(idxd->engines[i]); put_device(conf_dev); - kfree(engine); } kfree(idxd->engines); @@ -336,13 +315,10 @@ static int idxd_setup_engines(struct idxd_device *idxd) static void idxd_clean_groups(struct idxd_device *idxd) { - struct idxd_group *group; int i; for (i = 0; i < idxd->max_groups; i++) { - group = idxd->groups[i]; - put_device(group_confdev(group)); - kfree(group); + put_device(group_confdev(idxd->groups[i])); } kfree(idxd->groups); } @@ -377,7 +353,6 @@ static int idxd_setup_groups(struct idxd_device *idxd) rc = dev_set_name(conf_dev, "group%d.%d", idxd->id, group->id); if (rc < 0) { put_device(conf_dev); - kfree(group); goto err; } @@ -402,7 +377,6 @@ static int idxd_setup_groups(struct idxd_device *idxd) while (--i >= 0) { group = idxd->groups[i]; put_device(group_confdev(group)); - kfree(group); } kfree(idxd->groups); -- 2.50.1 (Apple Git-155)