[PATCH] alloca: fix subtraction of two alloca pointers

Kris Van Hees <[email protected]>
Newsgroups dev.linux.lists.dtrace
Message-ID <SJ0PR10MB567210C6329527665030B8D5C205A@SJ0PR10MB5672.namprd10.prod.outlook.com>
The subtraction of two alloca pointers should not be receiving the
ALLOCA taint because it is an integer value (of type ptrdiff_t).

Signed-off-by: Kris Van Hees <[email protected]>
---
 libdtrace/dt_parser.c                         |  8 ++++-
 test/unittest/funcs/alloca/tst.alloca-arith.d | 29 +++++++++++++++++++
 test/unittest/funcs/alloca/tst.alloca-funcs.d |  3 +-
 test/unittest/funcs/alloca/tst.alloca-funcs.r |  3 +-
 4 files changed, 40 insertions(+), 3 deletions(-)
 create mode 100644 test/unittest/funcs/alloca/tst.alloca-arith.d

diff --git a/libdtrace/dt_parser.c b/libdtrace/dt_parser.c
index 65baa2603..006b4b6e1 100644
--- a/libdtrace/dt_parser.c
+++ b/libdtrace/dt_parser.c
@@ -3618,7 +3618,13 @@ dt_cook_op2(dt_node_t *dnp, uint_t idflags)
 
 		dt_node_type_assign(dnp, ctfp, type);
 		dt_node_attr_assign(dnp, dt_attr_min(lp->dn_attr, rp->dn_attr));
-		dt_node_prop_alloca(dnp, lp, rp);
+
+		/*
+		 * Only propagate ALLOCA taint if this is not a subtraction of
+		 * two pointers.
+		 */
+		if (!lp_is_ptr || !rp_is_ptr)
+			dt_node_prop_alloca(dnp, lp, rp);
 
 		if (xflags)
 			dnp->dn_flags |= xflags;
diff --git a/test/unittest/funcs/alloca/tst.alloca-arith.d b/test/unittest/funcs/alloca/tst.alloca-arith.d
new file mode 100644
index 000000000..6a7bc3354
--- /dev/null
+++ b/test/unittest/funcs/alloca/tst.alloca-arith.d
@@ -0,0 +1,29 @@
+/*
+ * Oracle Linux DTrace.
+ * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
+ * Licensed under the Universal Permissive License v 1.0 as shown at
+ * http://oss.oracle.com/licenses/upl.
+ */
+
+/*
+ * ASSERTION: Subtracting alloca pointers yields a plain integer value.
+ *
+ * SECTION: Actions and Subroutines/alloca()
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+	x = (char *)alloca(1);
+	x = (char *)alloca(10);
+	y = (char *)alloca(1);
+	z = y - x;
+	z /= 8;
+	exit(z == 2 ? 0 : 1);
+}
+
+ERROR
+{
+	exit(1);
+}
diff --git a/test/unittest/funcs/alloca/tst.alloca-funcs.d b/test/unittest/funcs/alloca/tst.alloca-funcs.d
index abeaa0463..a716d27d5 100644
--- a/test/unittest/funcs/alloca/tst.alloca-funcs.d
+++ b/test/unittest/funcs/alloca/tst.alloca-funcs.d
@@ -21,13 +21,14 @@
 
 BEGIN
 {
+	base = (char *)alloca(0);
 	x = (char *) alloca(8);
 	x[0] = 'a';
 	x[1] = '/';
 	x[2] = 'b';
 	x[3] = 0;
 	printf("%s\n", stringof(x));
-	trace(x);
+	printf("%x\n", x - base);
 }
 
 BEGIN
diff --git a/test/unittest/funcs/alloca/tst.alloca-funcs.r b/test/unittest/funcs/alloca/tst.alloca-funcs.r
index 7a618a62a..96708b76a 100644
--- a/test/unittest/funcs/alloca/tst.alloca-funcs.r
+++ b/test/unittest/funcs/alloca/tst.alloca-funcs.r
@@ -1,2 +1,3 @@
 a/b
-8b11/b/b3a/b//baba
+0
+b11/b/b3a/b//baba
-- 
2.45.2
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.