lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [day] [month] [year] [list]
Message-ID: <20251210173848.30786-1-ansuelsmth@gmail.com>
Date: Wed, 10 Dec 2025 18:38:41 +0100
From: Christian Marangi <ansuelsmth@...il.com>
To: Andy Shevchenko <andriy.shevchenko@...ux.intel.com>,
	Christian Marangi <ansuelsmth@...il.com>,
	Andrew Morton <akpm@...ux-foundation.org>,
	linux-kernel@...r.kernel.org
Cc: Ilpo Järvinen <ilpo.jarvinen@...ux.intel.com>
Subject: [PATCH v3] resource: add WARN_ON_ONCE for resource_size() and document misusage

Commit 900730dc4705 ("wifi: ath: Use
of_reserved_mem_region_to_resource() for "memory-region"") uncovered a
fragility in the usage of the resource_size() helper that might result
in its misusage as a way to check for initialization of a passed resource
descriptor.

In the referenced commit, resource_size() is wrongly assumed to return
0 when a resource descriptor is init to all zero while in reality it
would return 1.

This is caused by the fact that resource_size() calculates the size
with the following logic:

	end - start + 1

that with an all zero resource descriptor:

	0 - 0 + 1

returns 1.

One reason the BUG in the reference commit might have been introduced
is a logic error in the actual usage of resource_size().

Historically, it was assumed that resource_size() was ALWAYS
used AFTER APIs filled the data of the resource descriptor (or in case of
any error from such APIs, resource descriptor set to an invalid state).

But lack of comments on what should be the proper usage of
resource_size() might have introduced some confusion in the specific
case of passing a resource descriptor initialized to all zeros.

As described in the example, using resource_size() for a resource
descriptor that has zero start and end yields to resource size of 1
(this is correct and necessary behavior!) which may be confusing to
some callers.

Hence it's ALWAYS wrong to initialize (and use) a resource descriptor
to all zero following the usual pattern:

	struct resource res = {};

The correct way to initialize an "uninitialized" resource descriptor would
be to use the DEFINE_RES macro that correctly set the start and end
resource descriptior values.

To catch any possible misusage of resource_size() helper, emit a WARN if
we detect the passed resource descriptor have zeroed flags. This would
signal the resource descriptor is not correctly initialized and will
probably result in resource_size() returning unexpected sizes.

Also add kernel doc to resource_size() that in conjunction of WARN
should prevent from now on any possible misusage of this helper and
permit to catch and fix any possible BUG caused by this logic confusion.

Link: https://lore.kernel.org/all/20251207215359.28895-1-ansuelsmth@gmail.com/T/#m990492684913c5a158ff0e5fc90697d8ad95351b
Suggested-by: Ilpo Järvinen <ilpo.jarvinen@...ux.intel.com>
Signed-off-by: Christian Marangi <ansuelsmth@...il.com>
---
Changes v3:
- More wording fixup
- Use asm/bug.h

Changes v2:
- Improve commit description
- Improve kdoc
- Add bug.h include

 include/linux/ioport.h | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/include/linux/ioport.h b/include/linux/ioport.h
index e8b2d6aa4013..d3e837eb8760 100644
--- a/include/linux/ioport.h
+++ b/include/linux/ioport.h
@@ -14,6 +14,9 @@
 #include <linux/compiler.h>
 #include <linux/minmax.h>
 #include <linux/types.h>
+
+#include <asm/bug.h>
+
 /*
  * Resources are tree-like, allowing
  * nesting etc..
@@ -286,8 +289,30 @@ static inline void resource_set_range(struct resource *res,
 	resource_set_size(res, size);
 }
 
+/**
+ * resource_size - Get the size of the resource
+ * @res: Resource descriptor
+ *
+ * Calculated size is derived from @res end and start values following
+ * the logic:
+ *
+ *	end - start + 1
+ *
+ * The caller MUST ensure @res is properly initialized.
+ *
+ * Do NOT use resource_size() as a proxy for checking validity of @res or
+ * for checking if @res is in a resource tree (use flags checks or call
+ * resource_assigned() instead).
+ *
+ * Passing a @res descriptor with zeroed flags will produce a WARN
+ * signaling a misusage of this helper and probably a BUG in the user of
+ * this helper.
+ *
+ * Return: size of the resource.
+ */
 static inline resource_size_t resource_size(const struct resource *res)
 {
+	WARN_ON_ONCE(!res->flags);
 	return res->end - res->start + 1;
 }
 static inline unsigned long resource_type(const struct resource *res)
-- 
2.51.0


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ