Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0d88cce3 authored by qctecmdr Service's avatar qctecmdr Service Committed by Gerrit - the friendly Code Review server
Browse files

Merge "defconfig: Enable full reference count validation"

parents d7664ec0 45f4a9a5
Loading
Loading
Loading
Loading
+9 −0
Original line number Original line Diff line number Diff line
@@ -1027,4 +1027,13 @@ config REFCOUNT_FULL
	  against various use-after-free conditions that can be used in
	  against various use-after-free conditions that can be used in
	  security flaw exploits.
	  security flaw exploits.


config PANIC_ON_REFCOUNT_ERROR
	bool "Kernel panic on refcount error detection"
	depends on REFCOUNT_FULL
	help
	  If enabled, the kernel will panic when the refcount library
	  has detected any type of error (e.g. potential use-after-free
	  or potential memory-leaks) with an object associated with that
	  reference counter.

source "kernel/gcov/Kconfig"
source "kernel/gcov/Kconfig"
+1 −0
Original line number Original line Diff line number Diff line
@@ -43,6 +43,7 @@ CONFIG_SLAB_FREELIST_RANDOM=y
CONFIG_SLAB_FREELIST_HARDENED=y
CONFIG_SLAB_FREELIST_HARDENED=y
CONFIG_PROFILING=y
CONFIG_PROFILING=y
CONFIG_CC_STACKPROTECTOR_STRONG=y
CONFIG_CC_STACKPROTECTOR_STRONG=y
CONFIG_REFCOUNT_FULL=y
CONFIG_MODULES=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y
+2 −0
Original line number Original line Diff line number Diff line
@@ -43,6 +43,8 @@ CONFIG_SLAB_FREELIST_RANDOM=y
CONFIG_SLAB_FREELIST_HARDENED=y
CONFIG_SLAB_FREELIST_HARDENED=y
CONFIG_PROFILING=y
CONFIG_PROFILING=y
CONFIG_CC_STACKPROTECTOR_STRONG=y
CONFIG_CC_STACKPROTECTOR_STRONG=y
CONFIG_REFCOUNT_FULL=y
CONFIG_PANIC_ON_REFCOUNT_ERROR=y
CONFIG_MODULES=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y
+26 −7
Original line number Original line Diff line number Diff line
@@ -38,6 +38,18 @@
#include <linux/refcount.h>
#include <linux/refcount.h>
#include <linux/bug.h>
#include <linux/bug.h>


#ifdef CONFIG_PANIC_ON_REFCOUNT_ERROR
#define REFCOUNT_WARN_ONCE(cond, msg) \
do { \
	if (cond) { \
		printk(msg); \
		BUG(); \
	} \
} while (0)
#else
#define REFCOUNT_WARN_ONCE(cond, msg) WARN_ONCE(cond, msg)
#endif /* CONFIG_PANIC_ON_REFCOUNT_ERROR */

#ifdef CONFIG_REFCOUNT_FULL
#ifdef CONFIG_REFCOUNT_FULL


/**
/**
@@ -75,7 +87,8 @@ bool refcount_add_not_zero(unsigned int i, refcount_t *r)


	} while (!atomic_try_cmpxchg_relaxed(&r->refs, &val, new));
	} while (!atomic_try_cmpxchg_relaxed(&r->refs, &val, new));


	WARN_ONCE(new == UINT_MAX, "refcount_t: saturated; leaking memory.\n");
	REFCOUNT_WARN_ONCE(new == UINT_MAX,
			   "refcount_t: saturated; leaking memory.\n");


	return true;
	return true;
}
}
@@ -99,7 +112,8 @@ EXPORT_SYMBOL(refcount_add_not_zero);
 */
 */
void refcount_add(unsigned int i, refcount_t *r)
void refcount_add(unsigned int i, refcount_t *r)
{
{
	WARN_ONCE(!refcount_add_not_zero(i, r), "refcount_t: addition on 0; use-after-free.\n");
	REFCOUNT_WARN_ONCE(!refcount_add_not_zero(i, r),
			   "refcount_t: addition on 0; use-after-free.\n");
}
}
EXPORT_SYMBOL(refcount_add);
EXPORT_SYMBOL(refcount_add);


@@ -130,7 +144,8 @@ bool refcount_inc_not_zero(refcount_t *r)


	} while (!atomic_try_cmpxchg_relaxed(&r->refs, &val, new));
	} while (!atomic_try_cmpxchg_relaxed(&r->refs, &val, new));


	WARN_ONCE(new == UINT_MAX, "refcount_t: saturated; leaking memory.\n");
	REFCOUNT_WARN_ONCE(new == UINT_MAX,
			   "refcount_t: saturated; leaking memory.\n");


	return true;
	return true;
}
}
@@ -150,7 +165,8 @@ EXPORT_SYMBOL(refcount_inc_not_zero);
 */
 */
void refcount_inc(refcount_t *r)
void refcount_inc(refcount_t *r)
{
{
	WARN_ONCE(!refcount_inc_not_zero(r), "refcount_t: increment on 0; use-after-free.\n");
	REFCOUNT_WARN_ONCE(!refcount_inc_not_zero(r),
			   "refcount_t: increment on 0; use-after-free.\n");
}
}
EXPORT_SYMBOL(refcount_inc);
EXPORT_SYMBOL(refcount_inc);


@@ -184,7 +200,8 @@ bool refcount_sub_and_test(unsigned int i, refcount_t *r)


		new = val - i;
		new = val - i;
		if (new > val) {
		if (new > val) {
			WARN_ONCE(new > val, "refcount_t: underflow; use-after-free.\n");
			REFCOUNT_WARN_ONCE(new > val,
				"refcount_t: underflow; use-after-free.\n");
			return false;
			return false;
		}
		}


@@ -225,7 +242,8 @@ EXPORT_SYMBOL(refcount_dec_and_test);
 */
 */
void refcount_dec(refcount_t *r)
void refcount_dec(refcount_t *r)
{
{
	WARN_ONCE(refcount_dec_and_test(r), "refcount_t: decrement hit 0; leaking memory.\n");
	REFCOUNT_WARN_ONCE(refcount_dec_and_test(r),
			   "refcount_t: decrement hit 0; leaking memory.\n");
}
}
EXPORT_SYMBOL(refcount_dec);
EXPORT_SYMBOL(refcount_dec);
#endif /* CONFIG_REFCOUNT_FULL */
#endif /* CONFIG_REFCOUNT_FULL */
@@ -278,7 +296,8 @@ bool refcount_dec_not_one(refcount_t *r)


		new = val - 1;
		new = val - 1;
		if (new > val) {
		if (new > val) {
			WARN_ONCE(new > val, "refcount_t: underflow; use-after-free.\n");
			REFCOUNT_WARN_ONCE(new > val,
				"refcount_t: underflow; use-after-free.\n");
			return true;
			return true;
		}
		}