as_user_ptr() is intended to be used where an arbitrary integer e.g. an
error code is stored in a __user ptr.
The current implementation can be somewhat confusing in that it looks
like it can be used as direct replacement for u64_to_user_ptr e.g. in
PCuABI, where u64 addresses in the kernel-user interface are being
replaced with capability containing types such as __kernel_uintptr_t.
Currently, passing a valid capability e.g. a __kernel_uintptr_t,
__uintcap_t or user_uintptr_t etc to as_user_ptr() will result in a cast
to (void __user *) and a valid capability/pointer that can be
dereferenced. This is contrary to the code comment and intended usage
for as_user_ptr().
Add a cast to (u64) before the cast to (void __user *)(user_uintptr_t)
to make clearer the intended usage. This also always results in a null
capability that cannot be dereferenced.
Signed-off-by: Zachary Leaf <zachary.leaf(a)arm.com>
---
rendered version:
https://git.morello-project.org/zdleaf/linux/-/blob/docs/as_user_ptr_v3/Doc…
Documentation/core-api/user_ptr.rst | 16 +++++++++++++---
include/linux/user_ptr.h | 6 +++---
2 files changed, 16 insertions(+), 6 deletions(-)
diff --git a/Documentation/core-api/user_ptr.rst b/Documentation/core-api/user_ptr.rst
index 21e02d4bd11b..197bb198ede7 100644
--- a/Documentation/core-api/user_ptr.rst
+++ b/Documentation/core-api/user_ptr.rst
@@ -31,7 +31,8 @@ errors are likely to occur in PCuABI if it is omitted.
In certain situations, it is more convenient to represent user pointers
as integers. The type ``user_uintptr_t`` must be used for that purpose.
It is **the only integer type** that may be directly cast to and from a
-user pointer, for instance ``user_uintptr_t u = (user_uintptr_t)uptr``.
+user pointer, for instance ``user_uintptr_t uint = (user_uintptr_t)uptr``
+or ``void __user *uptr = (void __user *)uint``.
Note that ``(u)intptr_t`` is the recommended type to represent kernel
pointers, but it cannot represent user pointers.
@@ -106,6 +107,13 @@ Each function covers a particular category of input integer:
- Integer of any type: ``as_user_ptr()``
- ``u64`` (deprecated): ``u64_to_user_ptr()``
+Note: ``as_user_ptr()`` nullifies any capability and is not a
+replacement for most uses of ``u64_to_user_ptr()``. To convert an
+integer representation of a user pointer i.e. ``user_uintptr_t`` back to
+pointer type, a simple cast such as ``(void __user *)`` is sufficient.
+See `Representing user pointers`_ and notes for ``as_user_ptr()`` and
+``u64_to_user_ptr()`` below.
+
These functions are available in ``<linux/user_ptr.h>``, except
``compat_ptr()`` (``<linux/compat.h>``).
@@ -142,8 +150,10 @@ derived from in the PCuABI case.
| | | ``compat_*`` struct | | |
+------------------------------+--------------------+------------------------+-----------------------------------+------------------------------------------------------+
| ``as_user_ptr()`` | Arbitrary integer | Error code | Null capability | This is a pure representation change, as suggested |
-| | | | | by the ``as_`` prefix. The resulting pointer cannot |
-| | | | | be dereferenced. |
+| | | | | by the ``as_`` prefix. Returns up to 64 bits of an |
+| | | | | arbitrary integer represented as a user pointer. The |
+| | | | | result is not a valid pointer and cannot be |
+| | | | | dereferenced. |
+------------------------------+--------------------+------------------------+-----------------------------------+------------------------------------------------------+
| ``u64_to_user_ptr()`` | ``u64`` integer | [Deprecated] | Null capability | Legacy function, new callers should not be added. |
| | | | | Existing callers should move to either |
diff --git a/include/linux/user_ptr.h b/include/linux/user_ptr.h
index 0942b58cfb6a..516024f3fead 100644
--- a/include/linux/user_ptr.h
+++ b/include/linux/user_ptr.h
@@ -12,10 +12,10 @@
* as_user_ptr - convert an arbitrary integer value to a user pointer
* @x: the integer value to convert
*
- * Returns @x represented as a user pointer. The result is not a valid pointer
- * and shall not be dereferenced.
+ * Returns up to 64 bits of @x represented as a user pointer. The result is
+ * not a valid pointer and shall not be dereferenced.
*/
-#define as_user_ptr(x) ((void __user *)(user_uintptr_t)(x))
+#define as_user_ptr(x) ((void __user *)(user_uintptr_t)(u64)(x))
/* Same semantics as as_user_ptr(), but also requires x to be of a given type */
#define as_user_ptr_strict(type, x) ( \
--
2.34.1
as_user_ptr() is intended to be used where an arbitrary integer e.g. an
error code is stored in a __user ptr.
The current implementation can be somewhat confusing in that it looks
like it can be used as direct replacement for u64_to_user_ptr e.g. in
PCuABI, where u64 addresses in the kernel-user interface are being
replaced with capability containing types such as __kernel_uintptr_t.
Currently, passing a valid capability e.g. a __kernel_uintptr_t,
__uintcap_t or user_uintptr_t etc to as_user_ptr() will result in a cast
to (void __user *) and a valid capability/pointer that can be
dereferenced. This is contrary to the code comment and intended usage
for as_user_ptr().
Add a cast to (u64) before the cast to (void __user *)(user_uintptr_t)
to make clearer the intended usage. This also always results in a null
capability that cannot be dereferenced.
Signed-off-by: Zachary Leaf <zachary.leaf(a)arm.com>
---
rendered version:
https://git.morello-project.org/zdleaf/linux/-/blob/dev/as_user_ptr/Documen…
Documentation/core-api/user_ptr.rst | 22 +++++++++++++++++-----
include/linux/user_ptr.h | 6 +++---
2 files changed, 20 insertions(+), 8 deletions(-)
diff --git a/Documentation/core-api/user_ptr.rst b/Documentation/core-api/user_ptr.rst
index 21e02d4bd11b..b4b9afe88095 100644
--- a/Documentation/core-api/user_ptr.rst
+++ b/Documentation/core-api/user_ptr.rst
@@ -31,7 +31,8 @@ errors are likely to occur in PCuABI if it is omitted.
In certain situations, it is more convenient to represent user pointers
as integers. The type ``user_uintptr_t`` must be used for that purpose.
It is **the only integer type** that may be directly cast to and from a
-user pointer, for instance ``user_uintptr_t u = (user_uintptr_t)uptr``.
+user pointer, for instance ``user_uintptr_t uint = (user_uintptr_t)uptr``
+or ``void __user *uptr = (void __user *)uint``.
Note that ``(u)intptr_t`` is the recommended type to represent kernel
pointers, but it cannot represent user pointers.
@@ -106,6 +107,13 @@ Each function covers a particular category of input integer:
- Integer of any type: ``as_user_ptr()``
- ``u64`` (deprecated): ``u64_to_user_ptr()``
+Note: ``as_user_ptr()`` nullifies any capability and is not a
+replacement for all uses of ``u64_to_user_ptr()``. To convert an integer
+representation of a user pointer i.e. user_uintptr_t back to pointer
+type, a simple cast such as ``(void __user *)`` is sufficient. See
+`Representing user pointers`_ and notes for ``as_user_ptr()`` and
+``u64_to_user_ptr()`` below.
+
These functions are available in ``<linux/user_ptr.h>``, except
``compat_ptr()`` (``<linux/compat.h>``).
@@ -142,16 +150,20 @@ derived from in the PCuABI case.
| | | ``compat_*`` struct | | |
+------------------------------+--------------------+------------------------+-----------------------------------+------------------------------------------------------+
| ``as_user_ptr()`` | Arbitrary integer | Error code | Null capability | This is a pure representation change, as suggested |
-| | | | | by the ``as_`` prefix. The resulting pointer cannot |
-| | | | | be dereferenced. |
+| | | | | by the ``as_`` prefix. Returns up to 64 bits of an |
+| | | | | arbitrary integer represented as a user pointer. The |
+| | | | | result is not a valid pointer and cannot be |
+| | | | | dereferenced. |
+------------------------------+--------------------+------------------------+-----------------------------------+------------------------------------------------------+
| ``u64_to_user_ptr()`` | ``u64`` integer | [Deprecated] | Null capability | Legacy function, new callers should not be added. |
| | | | | Existing callers should move to either |
| | | | | ``as_user_ptr()`` if the user pointer is not used to |
| | | | | access memory, or ``uaddr_to_user_ptr()`` if the |
| | | | | input is an address and the user pointer is |
-| | | | | dereferenced (or ideally removed if the uapi can be |
-| | | | | changed appropriately). |
+| | | | | dereferenced (or ideally replace u64 with a |
+| | | | | capability containing type such as |
+| | | | | ``__kernel_uintptr_t`` if the uapi can be changed |
+| | | | | appropriately). |
+------------------------------+--------------------+------------------------+-----------------------------------+------------------------------------------------------+
diff --git a/include/linux/user_ptr.h b/include/linux/user_ptr.h
index 0942b58cfb6a..516024f3fead 100644
--- a/include/linux/user_ptr.h
+++ b/include/linux/user_ptr.h
@@ -12,10 +12,10 @@
* as_user_ptr - convert an arbitrary integer value to a user pointer
* @x: the integer value to convert
*
- * Returns @x represented as a user pointer. The result is not a valid pointer
- * and shall not be dereferenced.
+ * Returns up to 64 bits of @x represented as a user pointer. The result is
+ * not a valid pointer and shall not be dereferenced.
*/
-#define as_user_ptr(x) ((void __user *)(user_uintptr_t)(x))
+#define as_user_ptr(x) ((void __user *)(user_uintptr_t)(u64)(x))
/* Same semantics as as_user_ptr(), but also requires x to be of a given type */
#define as_user_ptr_strict(type, x) ( \
--
2.34.1
Commit 01b2a5217173 ("tracing: Add ioctl() to force ring buffer waiters
to wake up") added a callback to unlocked_ioctl, however in PCuABI the
function signature of file_operations->unlocked_ioctl in
include/linux/fs.h has been changed to take a user_uintptr_t arg as the
third param.
Update the signature of tracing_buffers_ioctl to avoid compilation
errors as below when tracing is enabled.
kernel/trace/trace.c:8396:20: error: incompatible function pointer types
initializing 'long (*)(struct file *, unsigned int, user_uintptr_t)'
(aka 'long (*)(struct file *, unsigned int, unsigned __intcap)') with an
expression of type 'long (struct file *, unsigned int, unsigned long)'
[-Werror,-Wincompatible-function-pointer-types]
Reported-by: Teo Couprie Diaz <teo.coupriediaz(a)arm.com>
Signed-off-by: Zachary Leaf <zachary.leaf(a)arm.com>
---
note: this patch is for incoming rebase from 5.18->6.1
kernel/trace/trace.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 5cfc95a52bc3..3ad1db4c4a3e 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -8367,7 +8367,7 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos,
}
/* An ioctl call with cmd 0 to the ring buffer file will wake up all waiters */
-static long tracing_buffers_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+static long tracing_buffers_ioctl(struct file *file, unsigned int cmd, user_uintptr_t arg)
{
struct ftrace_buffer_info *info = file->private_data;
struct trace_iterator *iter = &info->iter;
--
2.34.1
This rebases the patch on kernel 6.1 and slightly reworks it.
Indeed, it removes some defines that are now consolidated in the generic
compat header, and now takes advantage that COMPAT_MINSIGSTKSZ is defined
in linux/compat.h if it is not already.
Teo Couprie Diaz (2):
arm64: compat: Remove defines now in asm-generic
compat: update compat defines to 64-bits
arch/arm64/include/asm/compat.h | 6 ++----
include/asm-generic/compat.h | 10 ++++++++++
2 files changed, 12 insertions(+), 4 deletions(-)
--
2.25.1
Hi All,
This series are modifications in kselftests required to compile
with alpha version of Morello Gnu toochain recently released [1].
The whole series can also be found here [2].
Thanks,
Amit Daniel
[1]: https://developer.arm.com/downloads/-/arm-gnu-toolchain-for-morello-downloa…
[2]: git@git.morello-project.org:amitdaniel/linux.git gcc_kselftests_support_v1
Amit Daniel Kachhap (4):
kselftests/arm64: morello: Fix the operand mismatch error
kselftests/arm64: morello: Define uintcap_t if not defined
kselftests/arm64: morello: Initialize the dynamic relocations
kselftests/arm64: morello: Enable Gcc toolchain support
.../testing/selftests/arm64/morello/Makefile | 12 +-
.../selftests/arm64/morello/bootstrap.c | 4 +-
.../selftests/arm64/morello/freestanding.c | 7 +
.../selftests/arm64/morello/freestanding.h | 3 +
.../arm64/morello/freestanding_init_globals.c | 149 +++++++++++++++++-
.../arm64/morello/freestanding_start.S | 5 +-
6 files changed, 166 insertions(+), 14 deletions(-)
--
2.25.1