All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 00/12] Fix LKDTM for PPC64/IA64/PARISC
@ 2021-10-17 12:38 ` Christophe Leroy
  0 siblings, 0 replies; 99+ messages in thread
From: Christophe Leroy @ 2021-10-17 12:38 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Andrew Morton, James E.J. Bottomley, Helge Deller, Arnd Bergmann,
	Kees Cook, Greg Kroah-Hartman
  Cc: Christophe Leroy, linux-kernel, linuxppc-dev, linux-ia64,
	linux-parisc, linux-arch, linux-mm

PPC64/IA64/PARISC have function descriptors. LKDTM doesn't work
on those three architectures because LKDTM messes up function
descriptors with functions.

This series does some cleanup in the three architectures and
refactors function descriptors so that it can then easily use it
in a generic way in LKDTM.

Patch 8 is not absolutely necessary but it is a good trivial cleanup.

Changes in v3:
- Addressed received comments
- Swapped some of the powerpc patches to keep func_descr_t renamed as struct func_desc and remove 'struct ppc64_opd_entry'
- Changed HAVE_FUNCTION_DESCRIPTORS macro to a config item CONFIG_HAVE_FUNCTION_DESCRIPTORS
- Dropped patch 11 ("Fix lkdtm_EXEC_RODATA()")

Changes in v2:
- Addressed received comments
- Moved dereference_[kernel]_function_descriptor() out of line
- Added patches to remove func_descr_t and func_desc_t in powerpc
- Using func_desc_t instead of funct_descr_t
- Renamed HAVE_DEREFERENCE_FUNCTION_DESCRIPTOR to HAVE_FUNCTION_DESCRIPTORS
- Added a new lkdtm test to check protection of function descriptors

Christophe Leroy (12):
  powerpc: Move and rename func_descr_t
  powerpc: Use 'struct func_desc' instead of 'struct ppc64_opd_entry'
  powerpc: Remove 'struct ppc64_opd_entry'
  powerpc: Prepare func_desc_t for refactorisation
  ia64: Rename 'ip' to 'addr' in 'struct fdesc'
  asm-generic: Define CONFIG_HAVE_FUNCTION_DESCRIPTORS
  asm-generic: Define 'func_desc_t' to commonly describe function
    descriptors
  asm-generic: Refactor dereference_[kernel]_function_descriptor()
  lkdtm: Force do_nothing() out of line
  lkdtm: Really write into kernel text in WRITE_KERN
  lkdtm: Fix execute_[user]_location()
  lkdtm: Add a test for function descriptors protection

 arch/Kconfig                             |  3 +
 arch/ia64/Kconfig                        |  1 +
 arch/ia64/include/asm/elf.h              |  2 +-
 arch/ia64/include/asm/sections.h         | 24 +-------
 arch/ia64/kernel/module.c                |  6 +-
 arch/parisc/Kconfig                      |  1 +
 arch/parisc/include/asm/sections.h       | 16 ++----
 arch/parisc/kernel/process.c             | 21 -------
 arch/powerpc/Kconfig                     |  1 +
 arch/powerpc/include/asm/code-patching.h |  2 +-
 arch/powerpc/include/asm/elf.h           |  6 ++
 arch/powerpc/include/asm/sections.h      | 29 ++--------
 arch/powerpc/include/asm/types.h         |  6 --
 arch/powerpc/include/uapi/asm/elf.h      |  8 ---
 arch/powerpc/kernel/module_64.c          | 38 +++++--------
 arch/powerpc/kernel/ptrace/ptrace.c      |  6 ++
 arch/powerpc/kernel/signal_64.c          |  8 +--
 drivers/misc/lkdtm/core.c                |  1 +
 drivers/misc/lkdtm/lkdtm.h               |  1 +
 drivers/misc/lkdtm/perms.c               | 71 +++++++++++++++++++-----
 include/asm-generic/sections.h           | 13 ++++-
 include/linux/kallsyms.h                 |  2 +-
 kernel/extable.c                         | 23 +++++++-
 23 files changed, 146 insertions(+), 143 deletions(-)

-- 
2.31.1


^ permalink raw reply	[flat|nested] 99+ messages in thread

* [PATCH v3 00/12] Fix LKDTM for PPC64/IA64/PARISC
@ 2021-10-17 12:38 ` Christophe Leroy
  0 siblings, 0 replies; 99+ messages in thread
From: Christophe Leroy @ 2021-10-17 12:38 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Andrew Morton, James E.J. Bottomley, Helge Deller, Arnd Bergmann,
	Kees Cook, Greg Kroah-Hartman
  Cc: linux-arch, linux-ia64, linux-parisc, linux-kernel, linux-mm,
	linuxppc-dev

PPC64/IA64/PARISC have function descriptors. LKDTM doesn't work
on those three architectures because LKDTM messes up function
descriptors with functions.

This series does some cleanup in the three architectures and
refactors function descriptors so that it can then easily use it
in a generic way in LKDTM.

Patch 8 is not absolutely necessary but it is a good trivial cleanup.

Changes in v3:
- Addressed received comments
- Swapped some of the powerpc patches to keep func_descr_t renamed as struct func_desc and remove 'struct ppc64_opd_entry'
- Changed HAVE_FUNCTION_DESCRIPTORS macro to a config item CONFIG_HAVE_FUNCTION_DESCRIPTORS
- Dropped patch 11 ("Fix lkdtm_EXEC_RODATA()")

Changes in v2:
- Addressed received comments
- Moved dereference_[kernel]_function_descriptor() out of line
- Added patches to remove func_descr_t and func_desc_t in powerpc
- Using func_desc_t instead of funct_descr_t
- Renamed HAVE_DEREFERENCE_FUNCTION_DESCRIPTOR to HAVE_FUNCTION_DESCRIPTORS
- Added a new lkdtm test to check protection of function descriptors

Christophe Leroy (12):
  powerpc: Move and rename func_descr_t
  powerpc: Use 'struct func_desc' instead of 'struct ppc64_opd_entry'
  powerpc: Remove 'struct ppc64_opd_entry'
  powerpc: Prepare func_desc_t for refactorisation
  ia64: Rename 'ip' to 'addr' in 'struct fdesc'
  asm-generic: Define CONFIG_HAVE_FUNCTION_DESCRIPTORS
  asm-generic: Define 'func_desc_t' to commonly describe function
    descriptors
  asm-generic: Refactor dereference_[kernel]_function_descriptor()
  lkdtm: Force do_nothing() out of line
  lkdtm: Really write into kernel text in WRITE_KERN
  lkdtm: Fix execute_[user]_location()
  lkdtm: Add a test for function descriptors protection

 arch/Kconfig                             |  3 +
 arch/ia64/Kconfig                        |  1 +
 arch/ia64/include/asm/elf.h              |  2 +-
 arch/ia64/include/asm/sections.h         | 24 +-------
 arch/ia64/kernel/module.c                |  6 +-
 arch/parisc/Kconfig                      |  1 +
 arch/parisc/include/asm/sections.h       | 16 ++----
 arch/parisc/kernel/process.c             | 21 -------
 arch/powerpc/Kconfig                     |  1 +
 arch/powerpc/include/asm/code-patching.h |  2 +-
 arch/powerpc/include/asm/elf.h           |  6 ++
 arch/powerpc/include/asm/sections.h      | 29 ++--------
 arch/powerpc/include/asm/types.h         |  6 --
 arch/powerpc/include/uapi/asm/elf.h      |  8 ---
 arch/powerpc/kernel/module_64.c          | 38 +++++--------
 arch/powerpc/kernel/ptrace/ptrace.c      |  6 ++
 arch/powerpc/kernel/signal_64.c          |  8 +--
 drivers/misc/lkdtm/core.c                |  1 +
 drivers/misc/lkdtm/lkdtm.h               |  1 +
 drivers/misc/lkdtm/perms.c               | 71 +++++++++++++++++++-----
 include/asm-generic/sections.h           | 13 ++++-
 include/linux/kallsyms.h                 |  2 +-
 kernel/extable.c                         | 23 +++++++-
 23 files changed, 146 insertions(+), 143 deletions(-)

-- 
2.31.1


^ permalink raw reply	[flat|nested] 99+ messages in thread

* [PATCH v3 00/12] Fix LKDTM for PPC64/IA64/PARISC
@ 2021-10-17 12:38 ` Christophe Leroy
  0 siblings, 0 replies; 99+ messages in thread
From: Christophe Leroy @ 2021-10-17 12:38 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Andrew Morton, James E.J. Bottomley, Helge Deller, Arnd Bergmann,
	Kees Cook, Greg Kroah-Hartman
  Cc: Christophe Leroy, linux-kernel, linuxppc-dev, linux-ia64,
	linux-parisc, linux-arch, linux-mm

PPC64/IA64/PARISC have function descriptors. LKDTM doesn't work
on those three architectures because LKDTM messes up function
descriptors with functions.

This series does some cleanup in the three architectures and
refactors function descriptors so that it can then easily use it
in a generic way in LKDTM.

Patch 8 is not absolutely necessary but it is a good trivial cleanup.

Changes in v3:
- Addressed received comments
- Swapped some of the powerpc patches to keep func_descr_t renamed as struct func_desc and remove 'struct ppc64_opd_entry'
- Changed HAVE_FUNCTION_DESCRIPTORS macro to a config item CONFIG_HAVE_FUNCTION_DESCRIPTORS
- Dropped patch 11 ("Fix lkdtm_EXEC_RODATA()")

Changes in v2:
- Addressed received comments
- Moved dereference_[kernel]_function_descriptor() out of line
- Added patches to remove func_descr_t and func_desc_t in powerpc
- Using func_desc_t instead of funct_descr_t
- Renamed HAVE_DEREFERENCE_FUNCTION_DESCRIPTOR to HAVE_FUNCTION_DESCRIPTORS
- Added a new lkdtm test to check protection of function descriptors

Christophe Leroy (12):
  powerpc: Move and rename func_descr_t
  powerpc: Use 'struct func_desc' instead of 'struct ppc64_opd_entry'
  powerpc: Remove 'struct ppc64_opd_entry'
  powerpc: Prepare func_desc_t for refactorisation
  ia64: Rename 'ip' to 'addr' in 'struct fdesc'
  asm-generic: Define CONFIG_HAVE_FUNCTION_DESCRIPTORS
  asm-generic: Define 'func_desc_t' to commonly describe function
    descriptors
  asm-generic: Refactor dereference_[kernel]_function_descriptor()
  lkdtm: Force do_nothing() out of line
  lkdtm: Really write into kernel text in WRITE_KERN
  lkdtm: Fix execute_[user]_location()
  lkdtm: Add a test for function descriptors protection

 arch/Kconfig                             |  3 +
 arch/ia64/Kconfig                        |  1 +
 arch/ia64/include/asm/elf.h              |  2 +-
 arch/ia64/include/asm/sections.h         | 24 +-------
 arch/ia64/kernel/module.c                |  6 +-
 arch/parisc/Kconfig                      |  1 +
 arch/parisc/include/asm/sections.h       | 16 ++----
 arch/parisc/kernel/process.c             | 21 -------
 arch/powerpc/Kconfig                     |  1 +
 arch/powerpc/include/asm/code-patching.h |  2 +-
 arch/powerpc/include/asm/elf.h           |  6 ++
 arch/powerpc/include/asm/sections.h      | 29 ++--------
 arch/powerpc/include/asm/types.h         |  6 --
 arch/powerpc/include/uapi/asm/elf.h      |  8 ---
 arch/powerpc/kernel/module_64.c          | 38 +++++--------
 arch/powerpc/kernel/ptrace/ptrace.c      |  6 ++
 arch/powerpc/kernel/signal_64.c          |  8 +--
 drivers/misc/lkdtm/core.c                |  1 +
 drivers/misc/lkdtm/lkdtm.h               |  1 +
 drivers/misc/lkdtm/perms.c               | 71 +++++++++++++++++++-----
 include/asm-generic/sections.h           | 13 ++++-
 include/linux/kallsyms.h                 |  2 +-
 kernel/extable.c                         | 23 +++++++-
 23 files changed, 146 insertions(+), 143 deletions(-)

-- 
2.31.1

^ permalink raw reply	[flat|nested] 99+ messages in thread

* [PATCH v3 01/12] powerpc: Move and rename func_descr_t
  2021-10-17 12:38 ` Christophe Leroy
  (?)
@ 2021-10-17 12:38   ` Christophe Leroy
  -1 siblings, 0 replies; 99+ messages in thread
From: Christophe Leroy @ 2021-10-17 12:38 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Andrew Morton, James E.J. Bottomley, Helge Deller, Arnd Bergmann,
	Kees Cook, Greg Kroah-Hartman
  Cc: Christophe Leroy, linux-kernel, linuxppc-dev, linux-ia64,
	linux-parisc, linux-arch, linux-mm

There are three architectures with function descriptors, try to
have common names for the address they contain in order to
refactor some functions into generic functions later.

powerpc has 'entry'
ia64 has 'ip'
parisc has 'addr'

Vote for 'addr' and update 'func_descr_t' accordingly.

Move it in asm/elf.h to have it at the same place on all
three architectures, remove the typedef which hides its real
type, and change it to a smoother name 'struct func_desc'.

Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
 arch/powerpc/include/asm/code-patching.h | 2 +-
 arch/powerpc/include/asm/elf.h           | 6 ++++++
 arch/powerpc/include/asm/types.h         | 6 ------
 arch/powerpc/kernel/signal_64.c          | 8 ++++----
 4 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/arch/powerpc/include/asm/code-patching.h b/arch/powerpc/include/asm/code-patching.h
index 4ba834599c4d..c6e805976e6f 100644
--- a/arch/powerpc/include/asm/code-patching.h
+++ b/arch/powerpc/include/asm/code-patching.h
@@ -110,7 +110,7 @@ static inline unsigned long ppc_function_entry(void *func)
 	 * function's descriptor. The first entry in the descriptor is the
 	 * address of the function text.
 	 */
-	return ((func_descr_t *)func)->entry;
+	return ((struct func_desc *)func)->addr;
 #else
 	return (unsigned long)func;
 #endif
diff --git a/arch/powerpc/include/asm/elf.h b/arch/powerpc/include/asm/elf.h
index b8425e3cfd81..971589a21bc0 100644
--- a/arch/powerpc/include/asm/elf.h
+++ b/arch/powerpc/include/asm/elf.h
@@ -176,4 +176,10 @@ do {									\
 /* Relocate the kernel image to @final_address */
 void relocate(unsigned long final_address);
 
+struct func_desc {
+	unsigned long addr;
+	unsigned long toc;
+	unsigned long env;
+};
+
 #endif /* _ASM_POWERPC_ELF_H */
diff --git a/arch/powerpc/include/asm/types.h b/arch/powerpc/include/asm/types.h
index f1630c553efe..97da77bc48c9 100644
--- a/arch/powerpc/include/asm/types.h
+++ b/arch/powerpc/include/asm/types.h
@@ -23,12 +23,6 @@
 
 typedef __vector128 vector128;
 
-typedef struct {
-	unsigned long entry;
-	unsigned long toc;
-	unsigned long env;
-} func_descr_t;
-
 #endif /* __ASSEMBLY__ */
 
 #endif /* _ASM_POWERPC_TYPES_H */
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c
index 1831bba0582e..36537d7d5191 100644
--- a/arch/powerpc/kernel/signal_64.c
+++ b/arch/powerpc/kernel/signal_64.c
@@ -933,11 +933,11 @@ int handle_rt_signal64(struct ksignal *ksig, sigset_t *set,
 		 * descriptor is the entry address of signal and the second
 		 * entry is the TOC value we need to use.
 		 */
-		func_descr_t __user *funct_desc_ptr =
-			(func_descr_t __user *) ksig->ka.sa.sa_handler;
+		struct func_desc __user *ptr =
+			(struct func_desc __user *)ksig->ka.sa.sa_handler;
 
-		err |= get_user(regs->ctr, &funct_desc_ptr->entry);
-		err |= get_user(regs->gpr[2], &funct_desc_ptr->toc);
+		err |= get_user(regs->ctr, &ptr->addr);
+		err |= get_user(regs->gpr[2], &ptr->toc);
 	}
 
 	/* enter the signal handler in native-endian mode */
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 99+ messages in thread

* [PATCH v3 01/12] powerpc: Move and rename func_descr_t
@ 2021-10-17 12:38   ` Christophe Leroy
  0 siblings, 0 replies; 99+ messages in thread
From: Christophe Leroy @ 2021-10-17 12:38 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Andrew Morton, James E.J. Bottomley, Helge Deller, Arnd Bergmann,
	Kees Cook, Greg Kroah-Hartman
  Cc: linux-arch, linux-ia64, linux-parisc, linux-kernel, linux-mm,
	linuxppc-dev

There are three architectures with function descriptors, try to
have common names for the address they contain in order to
refactor some functions into generic functions later.

powerpc has 'entry'
ia64 has 'ip'
parisc has 'addr'

Vote for 'addr' and update 'func_descr_t' accordingly.

Move it in asm/elf.h to have it at the same place on all
three architectures, remove the typedef which hides its real
type, and change it to a smoother name 'struct func_desc'.

Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
 arch/powerpc/include/asm/code-patching.h | 2 +-
 arch/powerpc/include/asm/elf.h           | 6 ++++++
 arch/powerpc/include/asm/types.h         | 6 ------
 arch/powerpc/kernel/signal_64.c          | 8 ++++----
 4 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/arch/powerpc/include/asm/code-patching.h b/arch/powerpc/include/asm/code-patching.h
index 4ba834599c4d..c6e805976e6f 100644
--- a/arch/powerpc/include/asm/code-patching.h
+++ b/arch/powerpc/include/asm/code-patching.h
@@ -110,7 +110,7 @@ static inline unsigned long ppc_function_entry(void *func)
 	 * function's descriptor. The first entry in the descriptor is the
 	 * address of the function text.
 	 */
-	return ((func_descr_t *)func)->entry;
+	return ((struct func_desc *)func)->addr;
 #else
 	return (unsigned long)func;
 #endif
diff --git a/arch/powerpc/include/asm/elf.h b/arch/powerpc/include/asm/elf.h
index b8425e3cfd81..971589a21bc0 100644
--- a/arch/powerpc/include/asm/elf.h
+++ b/arch/powerpc/include/asm/elf.h
@@ -176,4 +176,10 @@ do {									\
 /* Relocate the kernel image to @final_address */
 void relocate(unsigned long final_address);
 
+struct func_desc {
+	unsigned long addr;
+	unsigned long toc;
+	unsigned long env;
+};
+
 #endif /* _ASM_POWERPC_ELF_H */
diff --git a/arch/powerpc/include/asm/types.h b/arch/powerpc/include/asm/types.h
index f1630c553efe..97da77bc48c9 100644
--- a/arch/powerpc/include/asm/types.h
+++ b/arch/powerpc/include/asm/types.h
@@ -23,12 +23,6 @@
 
 typedef __vector128 vector128;
 
-typedef struct {
-	unsigned long entry;
-	unsigned long toc;
-	unsigned long env;
-} func_descr_t;
-
 #endif /* __ASSEMBLY__ */
 
 #endif /* _ASM_POWERPC_TYPES_H */
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c
index 1831bba0582e..36537d7d5191 100644
--- a/arch/powerpc/kernel/signal_64.c
+++ b/arch/powerpc/kernel/signal_64.c
@@ -933,11 +933,11 @@ int handle_rt_signal64(struct ksignal *ksig, sigset_t *set,
 		 * descriptor is the entry address of signal and the second
 		 * entry is the TOC value we need to use.
 		 */
-		func_descr_t __user *funct_desc_ptr =
-			(func_descr_t __user *) ksig->ka.sa.sa_handler;
+		struct func_desc __user *ptr =
+			(struct func_desc __user *)ksig->ka.sa.sa_handler;
 
-		err |= get_user(regs->ctr, &funct_desc_ptr->entry);
-		err |= get_user(regs->gpr[2], &funct_desc_ptr->toc);
+		err |= get_user(regs->ctr, &ptr->addr);
+		err |= get_user(regs->gpr[2], &ptr->toc);
 	}
 
 	/* enter the signal handler in native-endian mode */
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 99+ messages in thread

* [PATCH v3 01/12] powerpc: Move and rename func_descr_t
@ 2021-10-17 12:38   ` Christophe Leroy
  0 siblings, 0 replies; 99+ messages in thread
From: Christophe Leroy @ 2021-10-17 12:38 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Andrew Morton, James E.J. Bottomley, Helge Deller, Arnd Bergmann,
	Kees Cook, Greg Kroah-Hartman
  Cc: Christophe Leroy, linux-kernel, linuxppc-dev, linux-ia64,
	linux-parisc, linux-arch, linux-mm

There are three architectures with function descriptors, try to
have common names for the address they contain in order to
refactor some functions into generic functions later.

powerpc has 'entry'
ia64 has 'ip'
parisc has 'addr'

Vote for 'addr' and update 'func_descr_t' accordingly.

Move it in asm/elf.h to have it at the same place on all
three architectures, remove the typedef which hides its real
type, and change it to a smoother name 'struct func_desc'.

Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
 arch/powerpc/include/asm/code-patching.h | 2 +-
 arch/powerpc/include/asm/elf.h           | 6 ++++++
 arch/powerpc/include/asm/types.h         | 6 ------
 arch/powerpc/kernel/signal_64.c          | 8 ++++----
 4 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/arch/powerpc/include/asm/code-patching.h b/arch/powerpc/include/asm/code-patching.h
index 4ba834599c4d..c6e805976e6f 100644
--- a/arch/powerpc/include/asm/code-patching.h
+++ b/arch/powerpc/include/asm/code-patching.h
@@ -110,7 +110,7 @@ static inline unsigned long ppc_function_entry(void *func)
 	 * function's descriptor. The first entry in the descriptor is the
 	 * address of the function text.
 	 */
-	return ((func_descr_t *)func)->entry;
+	return ((struct func_desc *)func)->addr;
 #else
 	return (unsigned long)func;
 #endif
diff --git a/arch/powerpc/include/asm/elf.h b/arch/powerpc/include/asm/elf.h
index b8425e3cfd81..971589a21bc0 100644
--- a/arch/powerpc/include/asm/elf.h
+++ b/arch/powerpc/include/asm/elf.h
@@ -176,4 +176,10 @@ do {									\
 /* Relocate the kernel image to @final_address */
 void relocate(unsigned long final_address);
 
+struct func_desc {
+	unsigned long addr;
+	unsigned long toc;
+	unsigned long env;
+};
+
 #endif /* _ASM_POWERPC_ELF_H */
diff --git a/arch/powerpc/include/asm/types.h b/arch/powerpc/include/asm/types.h
index f1630c553efe..97da77bc48c9 100644
--- a/arch/powerpc/include/asm/types.h
+++ b/arch/powerpc/include/asm/types.h
@@ -23,12 +23,6 @@
 
 typedef __vector128 vector128;
 
-typedef struct {
-	unsigned long entry;
-	unsigned long toc;
-	unsigned long env;
-} func_descr_t;
-
 #endif /* __ASSEMBLY__ */
 
 #endif /* _ASM_POWERPC_TYPES_H */
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c
index 1831bba0582e..36537d7d5191 100644
--- a/arch/powerpc/kernel/signal_64.c
+++ b/arch/powerpc/kernel/signal_64.c
@@ -933,11 +933,11 @@ int handle_rt_signal64(struct ksignal *ksig, sigset_t *set,
 		 * descriptor is the entry address of signal and the second
 		 * entry is the TOC value we need to use.
 		 */
-		func_descr_t __user *funct_desc_ptr -			(func_descr_t __user *) ksig->ka.sa.sa_handler;
+		struct func_desc __user *ptr +			(struct func_desc __user *)ksig->ka.sa.sa_handler;
 
-		err |= get_user(regs->ctr, &funct_desc_ptr->entry);
-		err |= get_user(regs->gpr[2], &funct_desc_ptr->toc);
+		err |= get_user(regs->ctr, &ptr->addr);
+		err |= get_user(regs->gpr[2], &ptr->toc);
 	}
 
 	/* enter the signal handler in native-endian mode */
-- 
2.31.1

^ permalink raw reply related	[flat|nested] 99+ messages in thread

* [PATCH v3 02/12] powerpc: Use 'struct func_desc' instead of 'struct ppc64_opd_entry'
  2021-10-17 12:38 ` Christophe Leroy
  (?)
@ 2021-10-17 12:38   ` Christophe Leroy
  -1 siblings, 0 replies; 99+ messages in thread
From: Christophe Leroy @ 2021-10-17 12:38 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Andrew Morton, James E.J. Bottomley, Helge Deller, Arnd Bergmann,
	Kees Cook, Greg Kroah-Hartman
  Cc: Christophe Leroy, linux-kernel, linuxppc-dev, linux-ia64,
	linux-parisc, linux-arch, linux-mm, Daniel Axtens,
	Nicholas Piggin

'struct ppc64_opd_entry' is somehow redundant with 'struct func_desc',
the later is more correct/complete as it includes the third
field which is unused.

So use 'struct func_desc' instead of 'struct ppc64_opd_entry'

Reviewed-by: Kees Cook <keescook@chromium.org>
Reviewed-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
 arch/powerpc/include/asm/sections.h |  4 ++--
 arch/powerpc/kernel/module_64.c     | 10 +++++-----
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/arch/powerpc/include/asm/sections.h b/arch/powerpc/include/asm/sections.h
index 6e4af4492a14..abd2e5213197 100644
--- a/arch/powerpc/include/asm/sections.h
+++ b/arch/powerpc/include/asm/sections.h
@@ -74,10 +74,10 @@ static inline int overlaps_kernel_text(unsigned long start, unsigned long end)
 #undef dereference_function_descriptor
 static inline void *dereference_function_descriptor(void *ptr)
 {
-	struct ppc64_opd_entry *desc = ptr;
+	struct func_desc *desc = ptr;
 	void *p;
 
-	if (!get_kernel_nofault(p, (void *)&desc->funcaddr))
+	if (!get_kernel_nofault(p, (void *)&desc->addr))
 		ptr = p;
 	return ptr;
 }
diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c
index 6baa676e7cb6..a89da0ee25e2 100644
--- a/arch/powerpc/kernel/module_64.c
+++ b/arch/powerpc/kernel/module_64.c
@@ -64,19 +64,19 @@ static unsigned int local_entry_offset(const Elf64_Sym *sym)
 #else
 
 /* An address is address of the OPD entry, which contains address of fn. */
-typedef struct ppc64_opd_entry func_desc_t;
+typedef struct func_desc func_desc_t;
 
 static func_desc_t func_desc(unsigned long addr)
 {
-	return *(struct ppc64_opd_entry *)addr;
+	return *(struct func_desc *)addr;
 }
 static unsigned long func_addr(unsigned long addr)
 {
-	return func_desc(addr).funcaddr;
+	return func_desc(addr).addr;
 }
 static unsigned long stub_func_addr(func_desc_t func)
 {
-	return func.funcaddr;
+	return func.addr;
 }
 static unsigned int local_entry_offset(const Elf64_Sym *sym)
 {
@@ -187,7 +187,7 @@ static int relacmp(const void *_x, const void *_y)
 static unsigned long get_stubs_size(const Elf64_Ehdr *hdr,
 				    const Elf64_Shdr *sechdrs)
 {
-	/* One extra reloc so it's always 0-funcaddr terminated */
+	/* One extra reloc so it's always 0-addr terminated */
 	unsigned long relocs = 1;
 	unsigned i;
 
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 99+ messages in thread

* [PATCH v3 02/12] powerpc: Use 'struct func_desc' instead of 'struct ppc64_opd_entry'
@ 2021-10-17 12:38   ` Christophe Leroy
  0 siblings, 0 replies; 99+ messages in thread
From: Christophe Leroy @ 2021-10-17 12:38 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Andrew Morton, James E.J. Bottomley, Helge Deller, Arnd Bergmann,
	Kees Cook, Greg Kroah-Hartman
  Cc: linux-arch, linux-ia64, linux-parisc, linux-kernel, linux-mm,
	Nicholas Piggin, linuxppc-dev, Daniel Axtens

'struct ppc64_opd_entry' is somehow redundant with 'struct func_desc',
the later is more correct/complete as it includes the third
field which is unused.

So use 'struct func_desc' instead of 'struct ppc64_opd_entry'

Reviewed-by: Kees Cook <keescook@chromium.org>
Reviewed-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
 arch/powerpc/include/asm/sections.h |  4 ++--
 arch/powerpc/kernel/module_64.c     | 10 +++++-----
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/arch/powerpc/include/asm/sections.h b/arch/powerpc/include/asm/sections.h
index 6e4af4492a14..abd2e5213197 100644
--- a/arch/powerpc/include/asm/sections.h
+++ b/arch/powerpc/include/asm/sections.h
@@ -74,10 +74,10 @@ static inline int overlaps_kernel_text(unsigned long start, unsigned long end)
 #undef dereference_function_descriptor
 static inline void *dereference_function_descriptor(void *ptr)
 {
-	struct ppc64_opd_entry *desc = ptr;
+	struct func_desc *desc = ptr;
 	void *p;
 
-	if (!get_kernel_nofault(p, (void *)&desc->funcaddr))
+	if (!get_kernel_nofault(p, (void *)&desc->addr))
 		ptr = p;
 	return ptr;
 }
diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c
index 6baa676e7cb6..a89da0ee25e2 100644
--- a/arch/powerpc/kernel/module_64.c
+++ b/arch/powerpc/kernel/module_64.c
@@ -64,19 +64,19 @@ static unsigned int local_entry_offset(const Elf64_Sym *sym)
 #else
 
 /* An address is address of the OPD entry, which contains address of fn. */
-typedef struct ppc64_opd_entry func_desc_t;
+typedef struct func_desc func_desc_t;
 
 static func_desc_t func_desc(unsigned long addr)
 {
-	return *(struct ppc64_opd_entry *)addr;
+	return *(struct func_desc *)addr;
 }
 static unsigned long func_addr(unsigned long addr)
 {
-	return func_desc(addr).funcaddr;
+	return func_desc(addr).addr;
 }
 static unsigned long stub_func_addr(func_desc_t func)
 {
-	return func.funcaddr;
+	return func.addr;
 }
 static unsigned int local_entry_offset(const Elf64_Sym *sym)
 {
@@ -187,7 +187,7 @@ static int relacmp(const void *_x, const void *_y)
 static unsigned long get_stubs_size(const Elf64_Ehdr *hdr,
 				    const Elf64_Shdr *sechdrs)
 {
-	/* One extra reloc so it's always 0-funcaddr terminated */
+	/* One extra reloc so it's always 0-addr terminated */
 	unsigned long relocs = 1;
 	unsigned i;
 
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 99+ messages in thread

* [PATCH v3 02/12] powerpc: Use 'struct func_desc' instead of 'struct ppc64_opd_entry'
@ 2021-10-17 12:38   ` Christophe Leroy
  0 siblings, 0 replies; 99+ messages in thread
From: Christophe Leroy @ 2021-10-17 12:38 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Andrew Morton, James E.J. Bottomley, Helge Deller, Arnd Bergmann,
	Kees Cook, Greg Kroah-Hartman
  Cc: Christophe Leroy, linux-kernel, linuxppc-dev, linux-ia64,
	linux-parisc, linux-arch, linux-mm, Daniel Axtens,
	Nicholas Piggin

'struct ppc64_opd_entry' is somehow redundant with 'struct func_desc',
the later is more correct/complete as it includes the third
field which is unused.

So use 'struct func_desc' instead of 'struct ppc64_opd_entry'

Reviewed-by: Kees Cook <keescook@chromium.org>
Reviewed-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
 arch/powerpc/include/asm/sections.h |  4 ++--
 arch/powerpc/kernel/module_64.c     | 10 +++++-----
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/arch/powerpc/include/asm/sections.h b/arch/powerpc/include/asm/sections.h
index 6e4af4492a14..abd2e5213197 100644
--- a/arch/powerpc/include/asm/sections.h
+++ b/arch/powerpc/include/asm/sections.h
@@ -74,10 +74,10 @@ static inline int overlaps_kernel_text(unsigned long start, unsigned long end)
 #undef dereference_function_descriptor
 static inline void *dereference_function_descriptor(void *ptr)
 {
-	struct ppc64_opd_entry *desc = ptr;
+	struct func_desc *desc = ptr;
 	void *p;
 
-	if (!get_kernel_nofault(p, (void *)&desc->funcaddr))
+	if (!get_kernel_nofault(p, (void *)&desc->addr))
 		ptr = p;
 	return ptr;
 }
diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c
index 6baa676e7cb6..a89da0ee25e2 100644
--- a/arch/powerpc/kernel/module_64.c
+++ b/arch/powerpc/kernel/module_64.c
@@ -64,19 +64,19 @@ static unsigned int local_entry_offset(const Elf64_Sym *sym)
 #else
 
 /* An address is address of the OPD entry, which contains address of fn. */
-typedef struct ppc64_opd_entry func_desc_t;
+typedef struct func_desc func_desc_t;
 
 static func_desc_t func_desc(unsigned long addr)
 {
-	return *(struct ppc64_opd_entry *)addr;
+	return *(struct func_desc *)addr;
 }
 static unsigned long func_addr(unsigned long addr)
 {
-	return func_desc(addr).funcaddr;
+	return func_desc(addr).addr;
 }
 static unsigned long stub_func_addr(func_desc_t func)
 {
-	return func.funcaddr;
+	return func.addr;
 }
 static unsigned int local_entry_offset(const Elf64_Sym *sym)
 {
@@ -187,7 +187,7 @@ static int relacmp(const void *_x, const void *_y)
 static unsigned long get_stubs_size(const Elf64_Ehdr *hdr,
 				    const Elf64_Shdr *sechdrs)
 {
-	/* One extra reloc so it's always 0-funcaddr terminated */
+	/* One extra reloc so it's always 0-addr terminated */
 	unsigned long relocs = 1;
 	unsigned i;
 
-- 
2.31.1

^ permalink raw reply related	[flat|nested] 99+ messages in thread

* [PATCH v3 03/12] powerpc: Remove 'struct ppc64_opd_entry'
  2021-10-17 12:38 ` Christophe Leroy
  (?)
@ 2021-10-17 12:38   ` Christophe Leroy
  -1 siblings, 0 replies; 99+ messages in thread
From: Christophe Leroy @ 2021-10-17 12:38 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Andrew Morton, James E.J. Bottomley, Helge Deller, Arnd Bergmann,
	Kees Cook, Greg Kroah-Hartman
  Cc: Christophe Leroy, linux-kernel, linuxppc-dev, linux-ia64,
	linux-parisc, linux-arch, linux-mm, Nicholas Piggin

'struct ppc64_opd_entry' doesn't belong to uapi/asm/elf.h

It was initially in module_64.c and commit 2d291e902791 ("Fix compile
failure with non modular builds") moved it into asm/elf.h

But it was by mistake added outside of __KERNEL__ section,
therefore commit c3617f72036c ("UAPI: (Scripted) Disintegrate
arch/powerpc/include/asm") moved it to uapi/asm/elf.h

Now that it is not used anymore by the kernel, remove it.

Reviewed-by: Kees Cook <keescook@chromium.org>
Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
 arch/powerpc/include/uapi/asm/elf.h | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/arch/powerpc/include/uapi/asm/elf.h b/arch/powerpc/include/uapi/asm/elf.h
index 860c59291bfc..308857123a08 100644
--- a/arch/powerpc/include/uapi/asm/elf.h
+++ b/arch/powerpc/include/uapi/asm/elf.h
@@ -289,12 +289,4 @@ typedef elf_fpreg_t elf_vsrreghalf_t32[ELF_NVSRHALFREG];
 /* Keep this the last entry.  */
 #define R_PPC64_NUM		253
 
-/* There's actually a third entry here, but it's unused */
-struct ppc64_opd_entry
-{
-	unsigned long funcaddr;
-	unsigned long r2;
-};
-
-
 #endif /* _UAPI_ASM_POWERPC_ELF_H */
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 99+ messages in thread

* [PATCH v3 03/12] powerpc: Remove 'struct ppc64_opd_entry'
@ 2021-10-17 12:38   ` Christophe Leroy
  0 siblings, 0 replies; 99+ messages in thread
From: Christophe Leroy @ 2021-10-17 12:38 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Andrew Morton, James E.J. Bottomley, Helge Deller, Arnd Bergmann,
	Kees Cook, Greg Kroah-Hartman
  Cc: linux-arch, linux-ia64, linux-parisc, linux-kernel, linux-mm,
	Nicholas Piggin, linuxppc-dev

'struct ppc64_opd_entry' doesn't belong to uapi/asm/elf.h

It was initially in module_64.c and commit 2d291e902791 ("Fix compile
failure with non modular builds") moved it into asm/elf.h

But it was by mistake added outside of __KERNEL__ section,
therefore commit c3617f72036c ("UAPI: (Scripted) Disintegrate
arch/powerpc/include/asm") moved it to uapi/asm/elf.h

Now that it is not used anymore by the kernel, remove it.

Reviewed-by: Kees Cook <keescook@chromium.org>
Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
 arch/powerpc/include/uapi/asm/elf.h | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/arch/powerpc/include/uapi/asm/elf.h b/arch/powerpc/include/uapi/asm/elf.h
index 860c59291bfc..308857123a08 100644
--- a/arch/powerpc/include/uapi/asm/elf.h
+++ b/arch/powerpc/include/uapi/asm/elf.h
@@ -289,12 +289,4 @@ typedef elf_fpreg_t elf_vsrreghalf_t32[ELF_NVSRHALFREG];
 /* Keep this the last entry.  */
 #define R_PPC64_NUM		253
 
-/* There's actually a third entry here, but it's unused */
-struct ppc64_opd_entry
-{
-	unsigned long funcaddr;
-	unsigned long r2;
-};
-
-
 #endif /* _UAPI_ASM_POWERPC_ELF_H */
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 99+ messages in thread

* [PATCH v3 03/12] powerpc: Remove 'struct ppc64_opd_entry'
@ 2021-10-17 12:38   ` Christophe Leroy
  0 siblings, 0 replies; 99+ messages in thread
From: Christophe Leroy @ 2021-10-17 12:38 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Andrew Morton, James E.J. Bottomley, Helge Deller, Arnd Bergmann,
	Kees Cook, Greg Kroah-Hartman
  Cc: Christophe Leroy, linux-kernel, linuxppc-dev, linux-ia64,
	linux-parisc, linux-arch, linux-mm, Nicholas Piggin

'struct ppc64_opd_entry' doesn't belong to uapi/asm/elf.h

It was initially in module_64.c and commit 2d291e902791 ("Fix compile
failure with non modular builds") moved it into asm/elf.h

But it was by mistake added outside of __KERNEL__ section,
therefore commit c3617f72036c ("UAPI: (Scripted) Disintegrate
arch/powerpc/include/asm") moved it to uapi/asm/elf.h

Now that it is not used anymore by the kernel, remove it.

Reviewed-by: Kees Cook <keescook@chromium.org>
Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
 arch/powerpc/include/uapi/asm/elf.h | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/arch/powerpc/include/uapi/asm/elf.h b/arch/powerpc/include/uapi/asm/elf.h
index 860c59291bfc..308857123a08 100644
--- a/arch/powerpc/include/uapi/asm/elf.h
+++ b/arch/powerpc/include/uapi/asm/elf.h
@@ -289,12 +289,4 @@ typedef elf_fpreg_t elf_vsrreghalf_t32[ELF_NVSRHALFREG];
 /* Keep this the last entry.  */
 #define R_PPC64_NUM		253
 
-/* There's actually a third entry here, but it's unused */
-struct ppc64_opd_entry
-{
-	unsigned long funcaddr;
-	unsigned long r2;
-};
-
-
 #endif /* _UAPI_ASM_POWERPC_ELF_H */
-- 
2.31.1

^ permalink raw reply related	[flat|nested] 99+ messages in thread

* [PATCH v3 04/12] powerpc: Prepare func_desc_t for refactorisation
  2021-10-17 12:38 ` Christophe Leroy
  (?)
@ 2021-10-17 12:38   ` Christophe Leroy
  -1 siblings, 0 replies; 99+ messages in thread
From: Christophe Leroy @ 2021-10-17 12:38 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Andrew Morton, James E.J. Bottomley, Helge Deller, Arnd Bergmann,
	Kees Cook, Greg Kroah-Hartman
  Cc: Christophe Leroy, linux-kernel, linuxppc-dev, linux-ia64,
	linux-parisc, linux-arch, linux-mm

In preparation of making func_desc_t generic, change the ELFv2
version to a struct containing 'addr' element.

This allows using single helpers common to ELFv1 and ELFv2.

Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
 arch/powerpc/kernel/module_64.c | 32 ++++++++++++++------------------
 1 file changed, 14 insertions(+), 18 deletions(-)

diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c
index a89da0ee25e2..b687ef88c4c4 100644
--- a/arch/powerpc/kernel/module_64.c
+++ b/arch/powerpc/kernel/module_64.c
@@ -33,19 +33,13 @@
 #ifdef PPC64_ELF_ABI_v2
 
 /* An address is simply the address of the function. */
-typedef unsigned long func_desc_t;
+typedef struct {
+	unsigned long addr;
+} func_desc_t;
 
 static func_desc_t func_desc(unsigned long addr)
 {
-	return addr;
-}
-static unsigned long func_addr(unsigned long addr)
-{
-	return addr;
-}
-static unsigned long stub_func_addr(func_desc_t func)
-{
-	return func;
+	return (func_desc_t){addr};
 }
 
 /* PowerPC64 specific values for the Elf64_Sym st_other field.  */
@@ -70,14 +64,6 @@ static func_desc_t func_desc(unsigned long addr)
 {
 	return *(struct func_desc *)addr;
 }
-static unsigned long func_addr(unsigned long addr)
-{
-	return func_desc(addr).addr;
-}
-static unsigned long stub_func_addr(func_desc_t func)
-{
-	return func.addr;
-}
 static unsigned int local_entry_offset(const Elf64_Sym *sym)
 {
 	return 0;
@@ -93,6 +79,16 @@ void *dereference_module_function_descriptor(struct module *mod, void *ptr)
 }
 #endif
 
+static unsigned long func_addr(unsigned long addr)
+{
+	return func_desc(addr).addr;
+}
+
+static unsigned long stub_func_addr(func_desc_t func)
+{
+	return func.addr;
+}
+
 #define STUB_MAGIC 0x73747562 /* stub */
 
 /* Like PPC32, we need little trampolines to do > 24-bit jumps (into
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 99+ messages in thread

* [PATCH v3 04/12] powerpc: Prepare func_desc_t for refactorisation
@ 2021-10-17 12:38   ` Christophe Leroy
  0 siblings, 0 replies; 99+ messages in thread
From: Christophe Leroy @ 2021-10-17 12:38 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Andrew Morton, James E.J. Bottomley, Helge Deller, Arnd Bergmann,
	Kees Cook, Greg Kroah-Hartman
  Cc: linux-arch, linux-ia64, linux-parisc, linux-kernel, linux-mm,
	linuxppc-dev

In preparation of making func_desc_t generic, change the ELFv2
version to a struct containing 'addr' element.

This allows using single helpers common to ELFv1 and ELFv2.

Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
 arch/powerpc/kernel/module_64.c | 32 ++++++++++++++------------------
 1 file changed, 14 insertions(+), 18 deletions(-)

diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c
index a89da0ee25e2..b687ef88c4c4 100644
--- a/arch/powerpc/kernel/module_64.c
+++ b/arch/powerpc/kernel/module_64.c
@@ -33,19 +33,13 @@
 #ifdef PPC64_ELF_ABI_v2
 
 /* An address is simply the address of the function. */
-typedef unsigned long func_desc_t;
+typedef struct {
+	unsigned long addr;
+} func_desc_t;
 
 static func_desc_t func_desc(unsigned long addr)
 {
-	return addr;
-}
-static unsigned long func_addr(unsigned long addr)
-{
-	return addr;
-}
-static unsigned long stub_func_addr(func_desc_t func)
-{
-	return func;
+	return (func_desc_t){addr};
 }
 
 /* PowerPC64 specific values for the Elf64_Sym st_other field.  */
@@ -70,14 +64,6 @@ static func_desc_t func_desc(unsigned long addr)
 {
 	return *(struct func_desc *)addr;
 }
-static unsigned long func_addr(unsigned long addr)
-{
-	return func_desc(addr).addr;
-}
-static unsigned long stub_func_addr(func_desc_t func)
-{
-	return func.addr;
-}
 static unsigned int local_entry_offset(const Elf64_Sym *sym)
 {
 	return 0;
@@ -93,6 +79,16 @@ void *dereference_module_function_descriptor(struct module *mod, void *ptr)
 }
 #endif
 
+static unsigned long func_addr(unsigned long addr)
+{
+	return func_desc(addr).addr;
+}
+
+static unsigned long stub_func_addr(func_desc_t func)
+{
+	return func.addr;
+}
+
 #define STUB_MAGIC 0x73747562 /* stub */
 
 /* Like PPC32, we need little trampolines to do > 24-bit jumps (into
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 99+ messages in thread

* [PATCH v3 04/12] powerpc: Prepare func_desc_t for refactorisation
@ 2021-10-17 12:38   ` Christophe Leroy
  0 siblings, 0 replies; 99+ messages in thread
From: Christophe Leroy @ 2021-10-17 12:38 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Andrew Morton, James E.J. Bottomley, Helge Deller, Arnd Bergmann,
	Kees Cook, Greg Kroah-Hartman
  Cc: Christophe Leroy, linux-kernel, linuxppc-dev, linux-ia64,
	linux-parisc, linux-arch, linux-mm

In preparation of making func_desc_t generic, change the ELFv2
version to a struct containing 'addr' element.

This allows using single helpers common to ELFv1 and ELFv2.

Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
 arch/powerpc/kernel/module_64.c | 32 ++++++++++++++------------------
 1 file changed, 14 insertions(+), 18 deletions(-)

diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c
index a89da0ee25e2..b687ef88c4c4 100644
--- a/arch/powerpc/kernel/module_64.c
+++ b/arch/powerpc/kernel/module_64.c
@@ -33,19 +33,13 @@
 #ifdef PPC64_ELF_ABI_v2
 
 /* An address is simply the address of the function. */
-typedef unsigned long func_desc_t;
+typedef struct {
+	unsigned long addr;
+} func_desc_t;
 
 static func_desc_t func_desc(unsigned long addr)
 {
-	return addr;
-}
-static unsigned long func_addr(unsigned long addr)
-{
-	return addr;
-}
-static unsigned long stub_func_addr(func_desc_t func)
-{
-	return func;
+	return (func_desc_t){addr};
 }
 
 /* PowerPC64 specific values for the Elf64_Sym st_other field.  */
@@ -70,14 +64,6 @@ static func_desc_t func_desc(unsigned long addr)
 {
 	return *(struct func_desc *)addr;
 }
-static unsigned long func_addr(unsigned long addr)
-{
-	return func_desc(addr).addr;
-}
-static unsigned long stub_func_addr(func_desc_t func)
-{
-	return func.addr;
-}
 static unsigned int local_entry_offset(const Elf64_Sym *sym)
 {
 	return 0;
@@ -93,6 +79,16 @@ void *dereference_module_function_descriptor(struct module *mod, void *ptr)
 }
 #endif
 
+static unsigned long func_addr(unsigned long addr)
+{
+	return func_desc(addr).addr;
+}
+
+static unsigned long stub_func_addr(func_desc_t func)
+{
+	return func.addr;
+}
+
 #define STUB_MAGIC 0x73747562 /* stub */
 
 /* Like PPC32, we need little trampolines to do > 24-bit jumps (into
-- 
2.31.1

^ permalink raw reply related	[flat|nested] 99+ messages in thread

* [PATCH v3 05/12] ia64: Rename 'ip' to 'addr' in 'struct fdesc'
  2021-10-17 12:38 ` Christophe Leroy
  (?)
@ 2021-10-17 12:38   ` Christophe Leroy
  -1 siblings, 0 replies; 99+ messages in thread
From: Christophe Leroy @ 2021-10-17 12:38 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Andrew Morton, James E.J. Bottomley, Helge Deller, Arnd Bergmann,
	Kees Cook, Greg Kroah-Hartman
  Cc: Christophe Leroy, linux-kernel, linuxppc-dev, linux-ia64,
	linux-parisc, linux-arch, linux-mm

There are three architectures with function descriptors, try to
have common names for the address they contain in order to
refactor some functions into generic functions later.

powerpc has 'entry'
ia64 has 'ip'
parisc has 'addr'

Vote for 'addr' and update 'struct fdesc' accordingly.

Reviewed-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
 arch/ia64/include/asm/elf.h      | 2 +-
 arch/ia64/include/asm/sections.h | 2 +-
 arch/ia64/kernel/module.c        | 6 +++---
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/arch/ia64/include/asm/elf.h b/arch/ia64/include/asm/elf.h
index 6629301a2620..2ef5f9966ad1 100644
--- a/arch/ia64/include/asm/elf.h
+++ b/arch/ia64/include/asm/elf.h
@@ -226,7 +226,7 @@ struct got_entry {
  * Layout of the Function Descriptor
  */
 struct fdesc {
-	uint64_t ip;
+	uint64_t addr;
 	uint64_t gp;
 };
 
diff --git a/arch/ia64/include/asm/sections.h b/arch/ia64/include/asm/sections.h
index 3a033d2008b3..35f24e52149a 100644
--- a/arch/ia64/include/asm/sections.h
+++ b/arch/ia64/include/asm/sections.h
@@ -35,7 +35,7 @@ static inline void *dereference_function_descriptor(void *ptr)
 	struct fdesc *desc = ptr;
 	void *p;
 
-	if (!get_kernel_nofault(p, (void *)&desc->ip))
+	if (!get_kernel_nofault(p, (void *)&desc->addr))
 		ptr = p;
 	return ptr;
 }
diff --git a/arch/ia64/kernel/module.c b/arch/ia64/kernel/module.c
index 2cba53c1da82..4f6400cbf79e 100644
--- a/arch/ia64/kernel/module.c
+++ b/arch/ia64/kernel/module.c
@@ -602,15 +602,15 @@ get_fdesc (struct module *mod, uint64_t value, int *okp)
 		return value;
 
 	/* Look for existing function descriptor. */
-	while (fdesc->ip) {
-		if (fdesc->ip == value)
+	while (fdesc->addr) {
+		if (fdesc->addr == value)
 			return (uint64_t)fdesc;
 		if ((uint64_t) ++fdesc >= mod->arch.opd->sh_addr + mod->arch.opd->sh_size)
 			BUG();
 	}
 
 	/* Create new one */
-	fdesc->ip = value;
+	fdesc->addr = value;
 	fdesc->gp = mod->arch.gp;
 	return (uint64_t) fdesc;
 }
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 99+ messages in thread

* [PATCH v3 05/12] ia64: Rename 'ip' to 'addr' in 'struct fdesc'
@ 2021-10-17 12:38   ` Christophe Leroy
  0 siblings, 0 replies; 99+ messages in thread
From: Christophe Leroy @ 2021-10-17 12:38 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Andrew Morton, James E.J. Bottomley, Helge Deller, Arnd Bergmann,
	Kees Cook, Greg Kroah-Hartman
  Cc: linux-arch, linux-ia64, linux-parisc, linux-kernel, linux-mm,
	linuxppc-dev

There are three architectures with function descriptors, try to
have common names for the address they contain in order to
refactor some functions into generic functions later.

powerpc has 'entry'
ia64 has 'ip'
parisc has 'addr'

Vote for 'addr' and update 'struct fdesc' accordingly.

Reviewed-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
 arch/ia64/include/asm/elf.h      | 2 +-
 arch/ia64/include/asm/sections.h | 2 +-
 arch/ia64/kernel/module.c        | 6 +++---
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/arch/ia64/include/asm/elf.h b/arch/ia64/include/asm/elf.h
index 6629301a2620..2ef5f9966ad1 100644
--- a/arch/ia64/include/asm/elf.h
+++ b/arch/ia64/include/asm/elf.h
@@ -226,7 +226,7 @@ struct got_entry {
  * Layout of the Function Descriptor
  */
 struct fdesc {
-	uint64_t ip;
+	uint64_t addr;
 	uint64_t gp;
 };
 
diff --git a/arch/ia64/include/asm/sections.h b/arch/ia64/include/asm/sections.h
index 3a033d2008b3..35f24e52149a 100644
--- a/arch/ia64/include/asm/sections.h
+++ b/arch/ia64/include/asm/sections.h
@@ -35,7 +35,7 @@ static inline void *dereference_function_descriptor(void *ptr)
 	struct fdesc *desc = ptr;
 	void *p;
 
-	if (!get_kernel_nofault(p, (void *)&desc->ip))
+	if (!get_kernel_nofault(p, (void *)&desc->addr))
 		ptr = p;
 	return ptr;
 }
diff --git a/arch/ia64/kernel/module.c b/arch/ia64/kernel/module.c
index 2cba53c1da82..4f6400cbf79e 100644
--- a/arch/ia64/kernel/module.c
+++ b/arch/ia64/kernel/module.c
@@ -602,15 +602,15 @@ get_fdesc (struct module *mod, uint64_t value, int *okp)
 		return value;
 
 	/* Look for existing function descriptor. */
-	while (fdesc->ip) {
-		if (fdesc->ip == value)
+	while (fdesc->addr) {
+		if (fdesc->addr == value)
 			return (uint64_t)fdesc;
 		if ((uint64_t) ++fdesc >= mod->arch.opd->sh_addr + mod->arch.opd->sh_size)
 			BUG();
 	}
 
 	/* Create new one */
-	fdesc->ip = value;
+	fdesc->addr = value;
 	fdesc->gp = mod->arch.gp;
 	return (uint64_t) fdesc;
 }
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 99+ messages in thread

* [PATCH v3 05/12] ia64: Rename 'ip' to 'addr' in 'struct fdesc'
@ 2021-10-17 12:38   ` Christophe Leroy
  0 siblings, 0 replies; 99+ messages in thread
From: Christophe Leroy @ 2021-10-17 12:38 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Andrew Morton, James E.J. Bottomley, Helge Deller, Arnd Bergmann,
	Kees Cook, Greg Kroah-Hartman
  Cc: Christophe Leroy, linux-kernel, linuxppc-dev, linux-ia64,
	linux-parisc, linux-arch, linux-mm

There are three architectures with function descriptors, try to
have common names for the address they contain in order to
refactor some functions into generic functions later.

powerpc has 'entry'
ia64 has 'ip'
parisc has 'addr'

Vote for 'addr' and update 'struct fdesc' accordingly.

Reviewed-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
 arch/ia64/include/asm/elf.h      | 2 +-
 arch/ia64/include/asm/sections.h | 2 +-
 arch/ia64/kernel/module.c        | 6 +++---
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/arch/ia64/include/asm/elf.h b/arch/ia64/include/asm/elf.h
index 6629301a2620..2ef5f9966ad1 100644
--- a/arch/ia64/include/asm/elf.h
+++ b/arch/ia64/include/asm/elf.h
@@ -226,7 +226,7 @@ struct got_entry {
  * Layout of the Function Descriptor
  */
 struct fdesc {
-	uint64_t ip;
+	uint64_t addr;
 	uint64_t gp;
 };
 
diff --git a/arch/ia64/include/asm/sections.h b/arch/ia64/include/asm/sections.h
index 3a033d2008b3..35f24e52149a 100644
--- a/arch/ia64/include/asm/sections.h
+++ b/arch/ia64/include/asm/sections.h
@@ -35,7 +35,7 @@ static inline void *dereference_function_descriptor(void *ptr)
 	struct fdesc *desc = ptr;
 	void *p;
 
-	if (!get_kernel_nofault(p, (void *)&desc->ip))
+	if (!get_kernel_nofault(p, (void *)&desc->addr))
 		ptr = p;
 	return ptr;
 }
diff --git a/arch/ia64/kernel/module.c b/arch/ia64/kernel/module.c
index 2cba53c1da82..4f6400cbf79e 100644
--- a/arch/ia64/kernel/module.c
+++ b/arch/ia64/kernel/module.c
@@ -602,15 +602,15 @@ get_fdesc (struct module *mod, uint64_t value, int *okp)
 		return value;
 
 	/* Look for existing function descriptor. */
-	while (fdesc->ip) {
-		if (fdesc->ip = value)
+	while (fdesc->addr) {
+		if (fdesc->addr = value)
 			return (uint64_t)fdesc;
 		if ((uint64_t) ++fdesc >= mod->arch.opd->sh_addr + mod->arch.opd->sh_size)
 			BUG();
 	}
 
 	/* Create new one */
-	fdesc->ip = value;
+	fdesc->addr = value;
 	fdesc->gp = mod->arch.gp;
 	return (uint64_t) fdesc;
 }
-- 
2.31.1

^ permalink raw reply related	[flat|nested] 99+ messages in thread

* [PATCH v3 06/12] asm-generic: Define CONFIG_HAVE_FUNCTION_DESCRIPTORS
  2021-10-17 12:38 ` Christophe Leroy
  (?)
@ 2021-10-17 12:38   ` Christophe Leroy
  -1 siblings, 0 replies; 99+ messages in thread
From: Christophe Leroy @ 2021-10-17 12:38 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Andrew Morton, James E.J. Bottomley, Helge Deller, Arnd Bergmann,
	Kees Cook, Greg Kroah-Hartman
  Cc: Christophe Leroy, linux-kernel, linuxppc-dev, linux-ia64,
	linux-parisc, linux-arch, linux-mm, Nicholas Piggin

Replace HAVE_DEREFERENCE_FUNCTION_DESCRIPTOR by a config option
named CONFIG_HAVE_FUNCTION_DESCRIPTORS and use it instead of
'dereference_function_descriptor' macro to know whether an
arch has function descriptors.

To limit churn in one of the following patches, use
an #ifdef/#else construct with empty first part
instead of an #ifndef in asm-generic/sections.h

On powerpc, make sure the config option matches the ABI used
by the compiler with a BUILD_BUG_ON().

And include a helper to check whether an arch has function
descriptors or not : have_function_descriptors()

Reviewed-by: Kees Cook <keescook@chromium.org>
Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
 arch/Kconfig                        | 3 +++
 arch/ia64/Kconfig                   | 1 +
 arch/ia64/include/asm/sections.h    | 2 --
 arch/parisc/Kconfig                 | 1 +
 arch/parisc/include/asm/sections.h  | 2 --
 arch/powerpc/Kconfig                | 1 +
 arch/powerpc/include/asm/sections.h | 2 --
 arch/powerpc/kernel/ptrace/ptrace.c | 6 ++++++
 include/asm-generic/sections.h      | 8 +++++++-
 include/linux/kallsyms.h            | 2 +-
 10 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/arch/Kconfig b/arch/Kconfig
index 8df1c7102643..6e610a53d832 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -197,6 +197,9 @@ config HAVE_FUNCTION_ERROR_INJECTION
 config HAVE_NMI
 	bool
 
+config HAVE_FUNCTION_DESCRIPTORS
+	bool
+
 config TRACE_IRQFLAGS_SUPPORT
 	bool
 
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index 1e33666fa679..97cf02951610 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -34,6 +34,7 @@ config IA64
 	select HAVE_FUNCTION_TRACER
 	select TTY
 	select HAVE_ARCH_TRACEHOOK
+	select HAVE_FUNCTION_DESCRIPTORS
 	select HAVE_VIRT_CPU_ACCOUNTING
 	select HUGETLB_PAGE_SIZE_VARIABLE if HUGETLB_PAGE
 	select VIRT_TO_BUS
diff --git a/arch/ia64/include/asm/sections.h b/arch/ia64/include/asm/sections.h
index 35f24e52149a..2460d365a057 100644
--- a/arch/ia64/include/asm/sections.h
+++ b/arch/ia64/include/asm/sections.h
@@ -27,8 +27,6 @@ extern char __start_gate_brl_fsys_bubble_down_patchlist[], __end_gate_brl_fsys_b
 extern char __start_unwind[], __end_unwind[];
 extern char __start_ivt_text[], __end_ivt_text[];
 
-#define HAVE_DEREFERENCE_FUNCTION_DESCRIPTOR 1
-
 #undef dereference_function_descriptor
 static inline void *dereference_function_descriptor(void *ptr)
 {
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index 27a8b49af11f..01d46ca32119 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -65,6 +65,7 @@ config PARISC
 	select HAVE_DYNAMIC_FTRACE_WITH_REGS
 	select HAVE_SOFTIRQ_ON_OWN_STACK if IRQSTACKS
 	select TRACE_IRQFLAGS_SUPPORT
+	select HAVE_FUNCTION_DESCRIPTORS if 64BIT
 
 	help
 	  The PA-RISC microprocessor is designed by Hewlett-Packard and used
diff --git a/arch/parisc/include/asm/sections.h b/arch/parisc/include/asm/sections.h
index bb52aea0cb21..c8092e4d94de 100644
--- a/arch/parisc/include/asm/sections.h
+++ b/arch/parisc/include/asm/sections.h
@@ -9,8 +9,6 @@ extern char __alt_instructions[], __alt_instructions_end[];
 
 #ifdef CONFIG_64BIT
 
-#define HAVE_DEREFERENCE_FUNCTION_DESCRIPTOR 1
-
 #undef dereference_function_descriptor
 void *dereference_function_descriptor(void *);
 
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index ba5b66189358..0effedba082f 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -208,6 +208,7 @@ config PPC
 	select HAVE_EFFICIENT_UNALIGNED_ACCESS	if !(CPU_LITTLE_ENDIAN && POWER7_CPU)
 	select HAVE_FAST_GUP
 	select HAVE_FTRACE_MCOUNT_RECORD
+	select HAVE_FUNCTION_DESCRIPTORS	if PPC64 && !CPU_LITTLE_ENDIAN
 	select HAVE_FUNCTION_ERROR_INJECTION
 	select HAVE_FUNCTION_GRAPH_TRACER
 	select HAVE_FUNCTION_TRACER
diff --git a/arch/powerpc/include/asm/sections.h b/arch/powerpc/include/asm/sections.h
index abd2e5213197..fb11544d7e6a 100644
--- a/arch/powerpc/include/asm/sections.h
+++ b/arch/powerpc/include/asm/sections.h
@@ -69,8 +69,6 @@ static inline int overlaps_kernel_text(unsigned long start, unsigned long end)
 
 #ifdef PPC64_ELF_ABI_v1
 
-#define HAVE_DEREFERENCE_FUNCTION_DESCRIPTOR 1
-
 #undef dereference_function_descriptor
 static inline void *dereference_function_descriptor(void *ptr)
 {
diff --git a/arch/powerpc/kernel/ptrace/ptrace.c b/arch/powerpc/kernel/ptrace/ptrace.c
index 7c7093c17c45..740b682caa73 100644
--- a/arch/powerpc/kernel/ptrace/ptrace.c
+++ b/arch/powerpc/kernel/ptrace/ptrace.c
@@ -446,4 +446,10 @@ void __init pt_regs_check(void)
 	 * real registers.
 	 */
 	BUILD_BUG_ON(PT_DSCR < sizeof(struct user_pt_regs) / sizeof(unsigned long));
+
+#ifdef PPC64_ELF_ABI_v1
+	BUILD_BUG_ON(!IS_ENABLED(CONFIG_HAVE_FUNCTION_DESCRIPTORS));
+#else
+	BUILD_BUG_ON(IS_ENABLED(CONFIG_HAVE_FUNCTION_DESCRIPTORS));
+#endif
 }
diff --git a/include/asm-generic/sections.h b/include/asm-generic/sections.h
index d16302d3eb59..a918388d9bf6 100644
--- a/include/asm-generic/sections.h
+++ b/include/asm-generic/sections.h
@@ -59,11 +59,17 @@ extern char __noinstr_text_start[], __noinstr_text_end[];
 extern __visible const void __nosave_begin, __nosave_end;
 
 /* Function descriptor handling (if any).  Override in asm/sections.h */
-#ifndef dereference_function_descriptor
+#ifdef CONFIG_HAVE_FUNCTION_DESCRIPTORS
+#else
 #define dereference_function_descriptor(p) ((void *)(p))
 #define dereference_kernel_function_descriptor(p) ((void *)(p))
 #endif
 
+static inline bool have_function_descriptors(void)
+{
+	return IS_ENABLED(CONFIG_HAVE_FUNCTION_DESCRIPTORS);
+}
+
 /* random extra sections (if any).  Override
  * in asm/sections.h */
 #ifndef arch_is_kernel_text
diff --git a/include/linux/kallsyms.h b/include/linux/kallsyms.h
index a1d6fc82d7f0..18799df0c9bf 100644
--- a/include/linux/kallsyms.h
+++ b/include/linux/kallsyms.h
@@ -57,7 +57,7 @@ static inline int is_ksym_addr(unsigned long addr)
 
 static inline void *dereference_symbol_descriptor(void *ptr)
 {
-#ifdef HAVE_DEREFERENCE_FUNCTION_DESCRIPTOR
+#ifdef CONFIG_HAVE_FUNCTION_DESCRIPTORS
 	struct module *mod;
 
 	ptr = dereference_kernel_function_descriptor(ptr);
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 99+ messages in thread

* [PATCH v3 06/12] asm-generic: Define CONFIG_HAVE_FUNCTION_DESCRIPTORS
@ 2021-10-17 12:38   ` Christophe Leroy
  0 siblings, 0 replies; 99+ messages in thread
From: Christophe Leroy @ 2021-10-17 12:38 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Andrew Morton, James E.J. Bottomley, Helge Deller, Arnd Bergmann,
	Kees Cook, Greg Kroah-Hartman
  Cc: linux-arch, linux-ia64, linux-parisc, linux-kernel, linux-mm,
	Nicholas Piggin, linuxppc-dev

Replace HAVE_DEREFERENCE_FUNCTION_DESCRIPTOR by a config option
named CONFIG_HAVE_FUNCTION_DESCRIPTORS and use it instead of
'dereference_function_descriptor' macro to know whether an
arch has function descriptors.

To limit churn in one of the following patches, use
an #ifdef/#else construct with empty first part
instead of an #ifndef in asm-generic/sections.h

On powerpc, make sure the config option matches the ABI used
by the compiler with a BUILD_BUG_ON().

And include a helper to check whether an arch has function
descriptors or not : have_function_descriptors()

Reviewed-by: Kees Cook <keescook@chromium.org>
Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
 arch/Kconfig                        | 3 +++
 arch/ia64/Kconfig                   | 1 +
 arch/ia64/include/asm/sections.h    | 2 --
 arch/parisc/Kconfig                 | 1 +
 arch/parisc/include/asm/sections.h  | 2 --
 arch/powerpc/Kconfig                | 1 +
 arch/powerpc/include/asm/sections.h | 2 --
 arch/powerpc/kernel/ptrace/ptrace.c | 6 ++++++
 include/asm-generic/sections.h      | 8 +++++++-
 include/linux/kallsyms.h            | 2 +-
 10 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/arch/Kconfig b/arch/Kconfig
index 8df1c7102643..6e610a53d832 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -197,6 +197,9 @@ config HAVE_FUNCTION_ERROR_INJECTION
 config HAVE_NMI
 	bool
 
+config HAVE_FUNCTION_DESCRIPTORS
+	bool
+
 config TRACE_IRQFLAGS_SUPPORT
 	bool
 
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index 1e33666fa679..97cf02951610 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -34,6 +34,7 @@ config IA64
 	select HAVE_FUNCTION_TRACER
 	select TTY
 	select HAVE_ARCH_TRACEHOOK
+	select HAVE_FUNCTION_DESCRIPTORS
 	select HAVE_VIRT_CPU_ACCOUNTING
 	select HUGETLB_PAGE_SIZE_VARIABLE if HUGETLB_PAGE
 	select VIRT_TO_BUS
diff --git a/arch/ia64/include/asm/sections.h b/arch/ia64/include/asm/sections.h
index 35f24e52149a..2460d365a057 100644
--- a/arch/ia64/include/asm/sections.h
+++ b/arch/ia64/include/asm/sections.h
@@ -27,8 +27,6 @@ extern char __start_gate_brl_fsys_bubble_down_patchlist[], __end_gate_brl_fsys_b
 extern char __start_unwind[], __end_unwind[];
 extern char __start_ivt_text[], __end_ivt_text[];
 
-#define HAVE_DEREFERENCE_FUNCTION_DESCRIPTOR 1
-
 #undef dereference_function_descriptor
 static inline void *dereference_function_descriptor(void *ptr)
 {
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index 27a8b49af11f..01d46ca32119 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -65,6 +65,7 @@ config PARISC
 	select HAVE_DYNAMIC_FTRACE_WITH_REGS
 	select HAVE_SOFTIRQ_ON_OWN_STACK if IRQSTACKS
 	select TRACE_IRQFLAGS_SUPPORT
+	select HAVE_FUNCTION_DESCRIPTORS if 64BIT
 
 	help
 	  The PA-RISC microprocessor is designed by Hewlett-Packard and used
diff --git a/arch/parisc/include/asm/sections.h b/arch/parisc/include/asm/sections.h
index bb52aea0cb21..c8092e4d94de 100644
--- a/arch/parisc/include/asm/sections.h
+++ b/arch/parisc/include/asm/sections.h
@@ -9,8 +9,6 @@ extern char __alt_instructions[], __alt_instructions_end[];
 
 #ifdef CONFIG_64BIT
 
-#define HAVE_DEREFERENCE_FUNCTION_DESCRIPTOR 1
-
 #undef dereference_function_descriptor
 void *dereference_function_descriptor(void *);
 
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index ba5b66189358..0effedba082f 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -208,6 +208,7 @@ config PPC
 	select HAVE_EFFICIENT_UNALIGNED_ACCESS	if !(CPU_LITTLE_ENDIAN && POWER7_CPU)
 	select HAVE_FAST_GUP
 	select HAVE_FTRACE_MCOUNT_RECORD
+	select HAVE_FUNCTION_DESCRIPTORS	if PPC64 && !CPU_LITTLE_ENDIAN
 	select HAVE_FUNCTION_ERROR_INJECTION
 	select HAVE_FUNCTION_GRAPH_TRACER
 	select HAVE_FUNCTION_TRACER
diff --git a/arch/powerpc/include/asm/sections.h b/arch/powerpc/include/asm/sections.h
index abd2e5213197..fb11544d7e6a 100644
--- a/arch/powerpc/include/asm/sections.h
+++ b/arch/powerpc/include/asm/sections.h
@@ -69,8 +69,6 @@ static inline int overlaps_kernel_text(unsigned long start, unsigned long end)
 
 #ifdef PPC64_ELF_ABI_v1
 
-#define HAVE_DEREFERENCE_FUNCTION_DESCRIPTOR 1
-
 #undef dereference_function_descriptor
 static inline void *dereference_function_descriptor(void *ptr)
 {
diff --git a/arch/powerpc/kernel/ptrace/ptrace.c b/arch/powerpc/kernel/ptrace/ptrace.c
index 7c7093c17c45..740b682caa73 100644
--- a/arch/powerpc/kernel/ptrace/ptrace.c
+++ b/arch/powerpc/kernel/ptrace/ptrace.c
@@ -446,4 +446,10 @@ void __init pt_regs_check(void)
 	 * real registers.
 	 */
 	BUILD_BUG_ON(PT_DSCR < sizeof(struct user_pt_regs) / sizeof(unsigned long));
+
+#ifdef PPC64_ELF_ABI_v1
+	BUILD_BUG_ON(!IS_ENABLED(CONFIG_HAVE_FUNCTION_DESCRIPTORS));
+#else
+	BUILD_BUG_ON(IS_ENABLED(CONFIG_HAVE_FUNCTION_DESCRIPTORS));
+#endif
 }
diff --git a/include/asm-generic/sections.h b/include/asm-generic/sections.h
index d16302d3eb59..a918388d9bf6 100644
--- a/include/asm-generic/sections.h
+++ b/include/asm-generic/sections.h
@@ -59,11 +59,17 @@ extern char __noinstr_text_start[], __noinstr_text_end[];
 extern __visible const void __nosave_begin, __nosave_end;
 
 /* Function descriptor handling (if any).  Override in asm/sections.h */
-#ifndef dereference_function_descriptor
+#ifdef CONFIG_HAVE_FUNCTION_DESCRIPTORS
+#else
 #define dereference_function_descriptor(p) ((void *)(p))
 #define dereference_kernel_function_descriptor(p) ((void *)(p))
 #endif
 
+static inline bool have_function_descriptors(void)
+{
+	return IS_ENABLED(CONFIG_HAVE_FUNCTION_DESCRIPTORS);
+}
+
 /* random extra sections (if any).  Override
  * in asm/sections.h */
 #ifndef arch_is_kernel_text
diff --git a/include/linux/kallsyms.h b/include/linux/kallsyms.h
index a1d6fc82d7f0..18799df0c9bf 100644
--- a/include/linux/kallsyms.h
+++ b/include/linux/kallsyms.h
@@ -57,7 +57,7 @@ static inline int is_ksym_addr(unsigned long addr)
 
 static inline void *dereference_symbol_descriptor(void *ptr)
 {
-#ifdef HAVE_DEREFERENCE_FUNCTION_DESCRIPTOR
+#ifdef CONFIG_HAVE_FUNCTION_DESCRIPTORS
 	struct module *mod;
 
 	ptr = dereference_kernel_function_descriptor(ptr);
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 99+ messages in thread

* [PATCH v3 06/12] asm-generic: Define CONFIG_HAVE_FUNCTION_DESCRIPTORS
@ 2021-10-17 12:38   ` Christophe Leroy
  0 siblings, 0 replies; 99+ messages in thread
From: Christophe Leroy @ 2021-10-17 12:38 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Andrew Morton, James E.J. Bottomley, Helge Deller, Arnd Bergmann,
	Kees Cook, Greg Kroah-Hartman
  Cc: Christophe Leroy, linux-kernel, linuxppc-dev, linux-ia64,
	linux-parisc, linux-arch, linux-mm, Nicholas Piggin

Replace HAVE_DEREFERENCE_FUNCTION_DESCRIPTOR by a config option
named CONFIG_HAVE_FUNCTION_DESCRIPTORS and use it instead of
'dereference_function_descriptor' macro to know whether an
arch has function descriptors.

To limit churn in one of the following patches, use
an #ifdef/#else construct with empty first part
instead of an #ifndef in asm-generic/sections.h

On powerpc, make sure the config option matches the ABI used
by the compiler with a BUILD_BUG_ON().

And include a helper to check whether an arch has function
descriptors or not : have_function_descriptors()

Reviewed-by: Kees Cook <keescook@chromium.org>
Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
 arch/Kconfig                        | 3 +++
 arch/ia64/Kconfig                   | 1 +
 arch/ia64/include/asm/sections.h    | 2 --
 arch/parisc/Kconfig                 | 1 +
 arch/parisc/include/asm/sections.h  | 2 --
 arch/powerpc/Kconfig                | 1 +
 arch/powerpc/include/asm/sections.h | 2 --
 arch/powerpc/kernel/ptrace/ptrace.c | 6 ++++++
 include/asm-generic/sections.h      | 8 +++++++-
 include/linux/kallsyms.h            | 2 +-
 10 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/arch/Kconfig b/arch/Kconfig
index 8df1c7102643..6e610a53d832 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -197,6 +197,9 @@ config HAVE_FUNCTION_ERROR_INJECTION
 config HAVE_NMI
 	bool
 
+config HAVE_FUNCTION_DESCRIPTORS
+	bool
+
 config TRACE_IRQFLAGS_SUPPORT
 	bool
 
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index 1e33666fa679..97cf02951610 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -34,6 +34,7 @@ config IA64
 	select HAVE_FUNCTION_TRACER
 	select TTY
 	select HAVE_ARCH_TRACEHOOK
+	select HAVE_FUNCTION_DESCRIPTORS
 	select HAVE_VIRT_CPU_ACCOUNTING
 	select HUGETLB_PAGE_SIZE_VARIABLE if HUGETLB_PAGE
 	select VIRT_TO_BUS
diff --git a/arch/ia64/include/asm/sections.h b/arch/ia64/include/asm/sections.h
index 35f24e52149a..2460d365a057 100644
--- a/arch/ia64/include/asm/sections.h
+++ b/arch/ia64/include/asm/sections.h
@@ -27,8 +27,6 @@ extern char __start_gate_brl_fsys_bubble_down_patchlist[], __end_gate_brl_fsys_b
 extern char __start_unwind[], __end_unwind[];
 extern char __start_ivt_text[], __end_ivt_text[];
 
-#define HAVE_DEREFERENCE_FUNCTION_DESCRIPTOR 1
-
 #undef dereference_function_descriptor
 static inline void *dereference_function_descriptor(void *ptr)
 {
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index 27a8b49af11f..01d46ca32119 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -65,6 +65,7 @@ config PARISC
 	select HAVE_DYNAMIC_FTRACE_WITH_REGS
 	select HAVE_SOFTIRQ_ON_OWN_STACK if IRQSTACKS
 	select TRACE_IRQFLAGS_SUPPORT
+	select HAVE_FUNCTION_DESCRIPTORS if 64BIT
 
 	help
 	  The PA-RISC microprocessor is designed by Hewlett-Packard and used
diff --git a/arch/parisc/include/asm/sections.h b/arch/parisc/include/asm/sections.h
index bb52aea0cb21..c8092e4d94de 100644
--- a/arch/parisc/include/asm/sections.h
+++ b/arch/parisc/include/asm/sections.h
@@ -9,8 +9,6 @@ extern char __alt_instructions[], __alt_instructions_end[];
 
 #ifdef CONFIG_64BIT
 
-#define HAVE_DEREFERENCE_FUNCTION_DESCRIPTOR 1
-
 #undef dereference_function_descriptor
 void *dereference_function_descriptor(void *);
 
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index ba5b66189358..0effedba082f 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -208,6 +208,7 @@ config PPC
 	select HAVE_EFFICIENT_UNALIGNED_ACCESS	if !(CPU_LITTLE_ENDIAN && POWER7_CPU)
 	select HAVE_FAST_GUP
 	select HAVE_FTRACE_MCOUNT_RECORD
+	select HAVE_FUNCTION_DESCRIPTORS	if PPC64 && !CPU_LITTLE_ENDIAN
 	select HAVE_FUNCTION_ERROR_INJECTION
 	select HAVE_FUNCTION_GRAPH_TRACER
 	select HAVE_FUNCTION_TRACER
diff --git a/arch/powerpc/include/asm/sections.h b/arch/powerpc/include/asm/sections.h
index abd2e5213197..fb11544d7e6a 100644
--- a/arch/powerpc/include/asm/sections.h
+++ b/arch/powerpc/include/asm/sections.h
@@ -69,8 +69,6 @@ static inline int overlaps_kernel_text(unsigned long start, unsigned long end)
 
 #ifdef PPC64_ELF_ABI_v1
 
-#define HAVE_DEREFERENCE_FUNCTION_DESCRIPTOR 1
-
 #undef dereference_function_descriptor
 static inline void *dereference_function_descriptor(void *ptr)
 {
diff --git a/arch/powerpc/kernel/ptrace/ptrace.c b/arch/powerpc/kernel/ptrace/ptrace.c
index 7c7093c17c45..740b682caa73 100644
--- a/arch/powerpc/kernel/ptrace/ptrace.c
+++ b/arch/powerpc/kernel/ptrace/ptrace.c
@@ -446,4 +446,10 @@ void __init pt_regs_check(void)
 	 * real registers.
 	 */
 	BUILD_BUG_ON(PT_DSCR < sizeof(struct user_pt_regs) / sizeof(unsigned long));
+
+#ifdef PPC64_ELF_ABI_v1
+	BUILD_BUG_ON(!IS_ENABLED(CONFIG_HAVE_FUNCTION_DESCRIPTORS));
+#else
+	BUILD_BUG_ON(IS_ENABLED(CONFIG_HAVE_FUNCTION_DESCRIPTORS));
+#endif
 }
diff --git a/include/asm-generic/sections.h b/include/asm-generic/sections.h
index d16302d3eb59..a918388d9bf6 100644
--- a/include/asm-generic/sections.h
+++ b/include/asm-generic/sections.h
@@ -59,11 +59,17 @@ extern char __noinstr_text_start[], __noinstr_text_end[];
 extern __visible const void __nosave_begin, __nosave_end;
 
 /* Function descriptor handling (if any).  Override in asm/sections.h */
-#ifndef dereference_function_descriptor
+#ifdef CONFIG_HAVE_FUNCTION_DESCRIPTORS
+#else
 #define dereference_function_descriptor(p) ((void *)(p))
 #define dereference_kernel_function_descriptor(p) ((void *)(p))
 #endif
 
+static inline bool have_function_descriptors(void)
+{
+	return IS_ENABLED(CONFIG_HAVE_FUNCTION_DESCRIPTORS);
+}
+
 /* random extra sections (if any).  Override
  * in asm/sections.h */
 #ifndef arch_is_kernel_text
diff --git a/include/linux/kallsyms.h b/include/linux/kallsyms.h
index a1d6fc82d7f0..18799df0c9bf 100644
--- a/include/linux/kallsyms.h
+++ b/include/linux/kallsyms.h
@@ -57,7 +57,7 @@ static inline int is_ksym_addr(unsigned long addr)
 
 static inline void *dereference_symbol_descriptor(void *ptr)
 {
-#ifdef HAVE_DEREFERENCE_FUNCTION_DESCRIPTOR
+#ifdef CONFIG_HAVE_FUNCTION_DESCRIPTORS
 	struct module *mod;
 
 	ptr = dereference_kernel_function_descriptor(ptr);
-- 
2.31.1

^ permalink raw reply related	[flat|nested] 99+ messages in thread

* [PATCH v3 07/12] asm-generic: Define 'func_desc_t' to commonly describe function descriptors
  2021-10-17 12:38 ` Christophe Leroy
  (?)
@ 2021-10-17 12:38   ` Christophe Leroy
  -1 siblings, 0 replies; 99+ messages in thread
From: Christophe Leroy @ 2021-10-17 12:38 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Andrew Morton, James E.J. Bottomley, Helge Deller, Arnd Bergmann,
	Kees Cook, Greg Kroah-Hartman
  Cc: Christophe Leroy, linux-kernel, linuxppc-dev, linux-ia64,
	linux-parisc, linux-arch, linux-mm

We have three architectures using function descriptors, each with its
own type and name.

Add a common typedef that can be used in generic code.

Also add a stub typedef for architecture without function descriptors,
to avoid a forest of #ifdefs.

It replaces the similar 'func_desc_t' previously defined in
arch/powerpc/kernel/module_64.c

Reviewed-by: Kees Cook <keescook@chromium.org>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
 arch/ia64/include/asm/sections.h    | 3 +++
 arch/parisc/include/asm/sections.h  | 5 +++++
 arch/powerpc/include/asm/sections.h | 4 ++++
 arch/powerpc/kernel/module_64.c     | 8 --------
 include/asm-generic/sections.h      | 3 +++
 5 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/arch/ia64/include/asm/sections.h b/arch/ia64/include/asm/sections.h
index 2460d365a057..3abe0562b01a 100644
--- a/arch/ia64/include/asm/sections.h
+++ b/arch/ia64/include/asm/sections.h
@@ -9,6 +9,9 @@
 
 #include <linux/elf.h>
 #include <linux/uaccess.h>
+
+typedef struct fdesc func_desc_t;
+
 #include <asm-generic/sections.h>
 
 extern char __phys_per_cpu_start[];
diff --git a/arch/parisc/include/asm/sections.h b/arch/parisc/include/asm/sections.h
index c8092e4d94de..ace1d4047a0b 100644
--- a/arch/parisc/include/asm/sections.h
+++ b/arch/parisc/include/asm/sections.h
@@ -2,6 +2,11 @@
 #ifndef _PARISC_SECTIONS_H
 #define _PARISC_SECTIONS_H
 
+#ifdef CONFIG_HAVE_FUNCTION_DESCRIPTORS
+#include <asm/elf.h>
+typedef Elf64_Fdesc func_desc_t;
+#endif
+
 /* nothing to see, move along */
 #include <asm-generic/sections.h>
 
diff --git a/arch/powerpc/include/asm/sections.h b/arch/powerpc/include/asm/sections.h
index fb11544d7e6a..1e6b6e732fb3 100644
--- a/arch/powerpc/include/asm/sections.h
+++ b/arch/powerpc/include/asm/sections.h
@@ -8,6 +8,10 @@
 
 #define arch_is_kernel_initmem_freed arch_is_kernel_initmem_freed
 
+#ifdef CONFIG_HAVE_FUNCTION_DESCRIPTORS
+typedef struct func_desc func_desc_t;
+#endif
+
 #include <asm-generic/sections.h>
 
 extern bool init_mem_is_free;
diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c
index b687ef88c4c4..3d06b996d504 100644
--- a/arch/powerpc/kernel/module_64.c
+++ b/arch/powerpc/kernel/module_64.c
@@ -32,11 +32,6 @@
 
 #ifdef PPC64_ELF_ABI_v2
 
-/* An address is simply the address of the function. */
-typedef struct {
-	unsigned long addr;
-} func_desc_t;
-
 static func_desc_t func_desc(unsigned long addr)
 {
 	return (func_desc_t){addr};
@@ -57,9 +52,6 @@ static unsigned int local_entry_offset(const Elf64_Sym *sym)
 }
 #else
 
-/* An address is address of the OPD entry, which contains address of fn. */
-typedef struct func_desc func_desc_t;
-
 static func_desc_t func_desc(unsigned long addr)
 {
 	return *(struct func_desc *)addr;
diff --git a/include/asm-generic/sections.h b/include/asm-generic/sections.h
index a918388d9bf6..33b51efe3a24 100644
--- a/include/asm-generic/sections.h
+++ b/include/asm-generic/sections.h
@@ -63,6 +63,9 @@ extern __visible const void __nosave_begin, __nosave_end;
 #else
 #define dereference_function_descriptor(p) ((void *)(p))
 #define dereference_kernel_function_descriptor(p) ((void *)(p))
+typedef struct {
+	unsigned long addr;
+} func_desc_t;
 #endif
 
 static inline bool have_function_descriptors(void)
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 99+ messages in thread

* [PATCH v3 07/12] asm-generic: Define 'func_desc_t' to commonly describe function descriptors
@ 2021-10-17 12:38   ` Christophe Leroy
  0 siblings, 0 replies; 99+ messages in thread
From: Christophe Leroy @ 2021-10-17 12:38 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Andrew Morton, James E.J. Bottomley, Helge Deller, Arnd Bergmann,
	Kees Cook, Greg Kroah-Hartman
  Cc: linux-arch, linux-ia64, linux-parisc, linux-kernel, linux-mm,
	linuxppc-dev

We have three architectures using function descriptors, each with its
own type and name.

Add a common typedef that can be used in generic code.

Also add a stub typedef for architecture without function descriptors,
to avoid a forest of #ifdefs.

It replaces the similar 'func_desc_t' previously defined in
arch/powerpc/kernel/module_64.c

Reviewed-by: Kees Cook <keescook@chromium.org>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
 arch/ia64/include/asm/sections.h    | 3 +++
 arch/parisc/include/asm/sections.h  | 5 +++++
 arch/powerpc/include/asm/sections.h | 4 ++++
 arch/powerpc/kernel/module_64.c     | 8 --------
 include/asm-generic/sections.h      | 3 +++
 5 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/arch/ia64/include/asm/sections.h b/arch/ia64/include/asm/sections.h
index 2460d365a057..3abe0562b01a 100644
--- a/arch/ia64/include/asm/sections.h
+++ b/arch/ia64/include/asm/sections.h
@@ -9,6 +9,9 @@
 
 #include <linux/elf.h>
 #include <linux/uaccess.h>
+
+typedef struct fdesc func_desc_t;
+
 #include <asm-generic/sections.h>
 
 extern char __phys_per_cpu_start[];
diff --git a/arch/parisc/include/asm/sections.h b/arch/parisc/include/asm/sections.h
index c8092e4d94de..ace1d4047a0b 100644
--- a/arch/parisc/include/asm/sections.h
+++ b/arch/parisc/include/asm/sections.h
@@ -2,6 +2,11 @@
 #ifndef _PARISC_SECTIONS_H
 #define _PARISC_SECTIONS_H
 
+#ifdef CONFIG_HAVE_FUNCTION_DESCRIPTORS
+#include <asm/elf.h>
+typedef Elf64_Fdesc func_desc_t;
+#endif
+
 /* nothing to see, move along */
 #include <asm-generic/sections.h>
 
diff --git a/arch/powerpc/include/asm/sections.h b/arch/powerpc/include/asm/sections.h
index fb11544d7e6a..1e6b6e732fb3 100644
--- a/arch/powerpc/include/asm/sections.h
+++ b/arch/powerpc/include/asm/sections.h
@@ -8,6 +8,10 @@
 
 #define arch_is_kernel_initmem_freed arch_is_kernel_initmem_freed
 
+#ifdef CONFIG_HAVE_FUNCTION_DESCRIPTORS
+typedef struct func_desc func_desc_t;
+#endif
+
 #include <asm-generic/sections.h>
 
 extern bool init_mem_is_free;
diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c
index b687ef88c4c4..3d06b996d504 100644
--- a/arch/powerpc/kernel/module_64.c
+++ b/arch/powerpc/kernel/module_64.c
@@ -32,11 +32,6 @@
 
 #ifdef PPC64_ELF_ABI_v2
 
-/* An address is simply the address of the function. */
-typedef struct {
-	unsigned long addr;
-} func_desc_t;
-
 static func_desc_t func_desc(unsigned long addr)
 {
 	return (func_desc_t){addr};
@@ -57,9 +52,6 @@ static unsigned int local_entry_offset(const Elf64_Sym *sym)
 }
 #else
 
-/* An address is address of the OPD entry, which contains address of fn. */
-typedef struct func_desc func_desc_t;
-
 static func_desc_t func_desc(unsigned long addr)
 {
 	return *(struct func_desc *)addr;
diff --git a/include/asm-generic/sections.h b/include/asm-generic/sections.h
index a918388d9bf6..33b51efe3a24 100644
--- a/include/asm-generic/sections.h
+++ b/include/asm-generic/sections.h
@@ -63,6 +63,9 @@ extern __visible const void __nosave_begin, __nosave_end;
 #else
 #define dereference_function_descriptor(p) ((void *)(p))
 #define dereference_kernel_function_descriptor(p) ((void *)(p))
+typedef struct {
+	unsigned long addr;
+} func_desc_t;
 #endif
 
 static inline bool have_function_descriptors(void)
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 99+ messages in thread

* [PATCH v3 07/12] asm-generic: Define 'func_desc_t' to commonly describe function descriptors
@ 2021-10-17 12:38   ` Christophe Leroy
  0 siblings, 0 replies; 99+ messages in thread
From: Christophe Leroy @ 2021-10-17 12:38 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Andrew Morton, James E.J. Bottomley, Helge Deller, Arnd Bergmann,
	Kees Cook, Greg Kroah-Hartman
  Cc: Christophe Leroy, linux-kernel, linuxppc-dev, linux-ia64,
	linux-parisc, linux-arch, linux-mm

We have three architectures using function descriptors, each with its
own type and name.

Add a common typedef that can be used in generic code.

Also add a stub typedef for architecture without function descriptors,
to avoid a forest of #ifdefs.

It replaces the similar 'func_desc_t' previously defined in
arch/powerpc/kernel/module_64.c

Reviewed-by: Kees Cook <keescook@chromium.org>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
 arch/ia64/include/asm/sections.h    | 3 +++
 arch/parisc/include/asm/sections.h  | 5 +++++
 arch/powerpc/include/asm/sections.h | 4 ++++
 arch/powerpc/kernel/module_64.c     | 8 --------
 include/asm-generic/sections.h      | 3 +++
 5 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/arch/ia64/include/asm/sections.h b/arch/ia64/include/asm/sections.h
index 2460d365a057..3abe0562b01a 100644
--- a/arch/ia64/include/asm/sections.h
+++ b/arch/ia64/include/asm/sections.h
@@ -9,6 +9,9 @@
 
 #include <linux/elf.h>
 #include <linux/uaccess.h>
+
+typedef struct fdesc func_desc_t;
+
 #include <asm-generic/sections.h>
 
 extern char __phys_per_cpu_start[];
diff --git a/arch/parisc/include/asm/sections.h b/arch/parisc/include/asm/sections.h
index c8092e4d94de..ace1d4047a0b 100644
--- a/arch/parisc/include/asm/sections.h
+++ b/arch/parisc/include/asm/sections.h
@@ -2,6 +2,11 @@
 #ifndef _PARISC_SECTIONS_H
 #define _PARISC_SECTIONS_H
 
+#ifdef CONFIG_HAVE_FUNCTION_DESCRIPTORS
+#include <asm/elf.h>
+typedef Elf64_Fdesc func_desc_t;
+#endif
+
 /* nothing to see, move along */
 #include <asm-generic/sections.h>
 
diff --git a/arch/powerpc/include/asm/sections.h b/arch/powerpc/include/asm/sections.h
index fb11544d7e6a..1e6b6e732fb3 100644
--- a/arch/powerpc/include/asm/sections.h
+++ b/arch/powerpc/include/asm/sections.h
@@ -8,6 +8,10 @@
 
 #define arch_is_kernel_initmem_freed arch_is_kernel_initmem_freed
 
+#ifdef CONFIG_HAVE_FUNCTION_DESCRIPTORS
+typedef struct func_desc func_desc_t;
+#endif
+
 #include <asm-generic/sections.h>
 
 extern bool init_mem_is_free;
diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c
index b687ef88c4c4..3d06b996d504 100644
--- a/arch/powerpc/kernel/module_64.c
+++ b/arch/powerpc/kernel/module_64.c
@@ -32,11 +32,6 @@
 
 #ifdef PPC64_ELF_ABI_v2
 
-/* An address is simply the address of the function. */
-typedef struct {
-	unsigned long addr;
-} func_desc_t;
-
 static func_desc_t func_desc(unsigned long addr)
 {
 	return (func_desc_t){addr};
@@ -57,9 +52,6 @@ static unsigned int local_entry_offset(const Elf64_Sym *sym)
 }
 #else
 
-/* An address is address of the OPD entry, which contains address of fn. */
-typedef struct func_desc func_desc_t;
-
 static func_desc_t func_desc(unsigned long addr)
 {
 	return *(struct func_desc *)addr;
diff --git a/include/asm-generic/sections.h b/include/asm-generic/sections.h
index a918388d9bf6..33b51efe3a24 100644
--- a/include/asm-generic/sections.h
+++ b/include/asm-generic/sections.h
@@ -63,6 +63,9 @@ extern __visible const void __nosave_begin, __nosave_end;
 #else
 #define dereference_function_descriptor(p) ((void *)(p))
 #define dereference_kernel_function_descriptor(p) ((void *)(p))
+typedef struct {
+	unsigned long addr;
+} func_desc_t;
 #endif
 
 static inline bool have_function_descriptors(void)
-- 
2.31.1

^ permalink raw reply related	[flat|nested] 99+ messages in thread

* [PATCH v3 08/12] asm-generic: Refactor dereference_[kernel]_function_descriptor()
  2021-10-17 12:38 ` Christophe Leroy
  (?)
@ 2021-10-17 12:38   ` Christophe Leroy
  -1 siblings, 0 replies; 99+ messages in thread
From: Christophe Leroy @ 2021-10-17 12:38 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Andrew Morton, James E.J. Bottomley, Helge Deller, Arnd Bergmann,
	Kees Cook, Greg Kroah-Hartman
  Cc: Christophe Leroy, linux-kernel, linuxppc-dev, linux-ia64,
	linux-parisc, linux-arch, linux-mm

dereference_function_descriptor() and
dereference_kernel_function_descriptor() are identical on the
three architectures implementing them.

Make them common and put them out-of-line in kernel/extable.c
which is one of the users and has similar type of functions.

Reviewed-by: Kees Cook <keescook@chromium.org>
Reviewed-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
 arch/ia64/include/asm/sections.h    | 19 -------------------
 arch/parisc/include/asm/sections.h  |  9 ---------
 arch/parisc/kernel/process.c        | 21 ---------------------
 arch/powerpc/include/asm/sections.h | 23 -----------------------
 include/asm-generic/sections.h      |  2 ++
 kernel/extable.c                    | 23 ++++++++++++++++++++++-
 6 files changed, 24 insertions(+), 73 deletions(-)

diff --git a/arch/ia64/include/asm/sections.h b/arch/ia64/include/asm/sections.h
index 3abe0562b01a..8e0875cf6071 100644
--- a/arch/ia64/include/asm/sections.h
+++ b/arch/ia64/include/asm/sections.h
@@ -30,23 +30,4 @@ extern char __start_gate_brl_fsys_bubble_down_patchlist[], __end_gate_brl_fsys_b
 extern char __start_unwind[], __end_unwind[];
 extern char __start_ivt_text[], __end_ivt_text[];
 
-#undef dereference_function_descriptor
-static inline void *dereference_function_descriptor(void *ptr)
-{
-	struct fdesc *desc = ptr;
-	void *p;
-
-	if (!get_kernel_nofault(p, (void *)&desc->addr))
-		ptr = p;
-	return ptr;
-}
-
-#undef dereference_kernel_function_descriptor
-static inline void *dereference_kernel_function_descriptor(void *ptr)
-{
-	if (ptr < (void *)__start_opd || ptr >= (void *)__end_opd)
-		return ptr;
-	return dereference_function_descriptor(ptr);
-}
-
 #endif /* _ASM_IA64_SECTIONS_H */
diff --git a/arch/parisc/include/asm/sections.h b/arch/parisc/include/asm/sections.h
index ace1d4047a0b..33df42b5cc6d 100644
--- a/arch/parisc/include/asm/sections.h
+++ b/arch/parisc/include/asm/sections.h
@@ -12,13 +12,4 @@ typedef Elf64_Fdesc func_desc_t;
 
 extern char __alt_instructions[], __alt_instructions_end[];
 
-#ifdef CONFIG_64BIT
-
-#undef dereference_function_descriptor
-void *dereference_function_descriptor(void *);
-
-#undef dereference_kernel_function_descriptor
-void *dereference_kernel_function_descriptor(void *);
-#endif
-
 #endif
diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c
index 38ec4ae81239..7382576b52a8 100644
--- a/arch/parisc/kernel/process.c
+++ b/arch/parisc/kernel/process.c
@@ -266,27 +266,6 @@ get_wchan(struct task_struct *p)
 	return 0;
 }
 
-#ifdef CONFIG_64BIT
-void *dereference_function_descriptor(void *ptr)
-{
-	Elf64_Fdesc *desc = ptr;
-	void *p;
-
-	if (!get_kernel_nofault(p, (void *)&desc->addr))
-		ptr = p;
-	return ptr;
-}
-
-void *dereference_kernel_function_descriptor(void *ptr)
-{
-	if (ptr < (void *)__start_opd ||
-			ptr >= (void *)__end_opd)
-		return ptr;
-
-	return dereference_function_descriptor(ptr);
-}
-#endif
-
 static inline unsigned long brk_rnd(void)
 {
 	return (get_random_int() & BRK_RND_MASK) << PAGE_SHIFT;
diff --git a/arch/powerpc/include/asm/sections.h b/arch/powerpc/include/asm/sections.h
index 1e6b6e732fb3..2c3de9bd1a90 100644
--- a/arch/powerpc/include/asm/sections.h
+++ b/arch/powerpc/include/asm/sections.h
@@ -71,29 +71,6 @@ static inline int overlaps_kernel_text(unsigned long start, unsigned long end)
 		(unsigned long)_stext < end;
 }
 
-#ifdef PPC64_ELF_ABI_v1
-
-#undef dereference_function_descriptor
-static inline void *dereference_function_descriptor(void *ptr)
-{
-	struct func_desc *desc = ptr;
-	void *p;
-
-	if (!get_kernel_nofault(p, (void *)&desc->addr))
-		ptr = p;
-	return ptr;
-}
-
-#undef dereference_kernel_function_descriptor
-static inline void *dereference_kernel_function_descriptor(void *ptr)
-{
-	if (ptr < (void *)__start_opd || ptr >= (void *)__end_opd)
-		return ptr;
-
-	return dereference_function_descriptor(ptr);
-}
-#endif /* PPC64_ELF_ABI_v1 */
-
 #endif
 
 #endif /* __KERNEL__ */
diff --git a/include/asm-generic/sections.h b/include/asm-generic/sections.h
index 33b51efe3a24..c9f30b6e81f9 100644
--- a/include/asm-generic/sections.h
+++ b/include/asm-generic/sections.h
@@ -60,6 +60,8 @@ extern __visible const void __nosave_begin, __nosave_end;
 
 /* Function descriptor handling (if any).  Override in asm/sections.h */
 #ifdef CONFIG_HAVE_FUNCTION_DESCRIPTORS
+void *dereference_function_descriptor(void *ptr);
+void *dereference_kernel_function_descriptor(void *ptr);
 #else
 #define dereference_function_descriptor(p) ((void *)(p))
 #define dereference_kernel_function_descriptor(p) ((void *)(p))
diff --git a/kernel/extable.c b/kernel/extable.c
index b0ea5eb0c3b4..1ef13789bea9 100644
--- a/kernel/extable.c
+++ b/kernel/extable.c
@@ -3,6 +3,7 @@
    Copyright (C) 2001 Rusty Russell, 2002 Rusty Russell IBM.
 
 */
+#include <linux/elf.h>
 #include <linux/ftrace.h>
 #include <linux/memory.h>
 #include <linux/extable.h>
@@ -159,12 +160,32 @@ int kernel_text_address(unsigned long addr)
 }
 
 /*
- * On some architectures (PPC64, IA64) function pointers
+ * On some architectures (PPC64, IA64, PARISC) function pointers
  * are actually only tokens to some data that then holds the
  * real function address. As a result, to find if a function
  * pointer is part of the kernel text, we need to do some
  * special dereferencing first.
  */
+#ifdef CONFIG_HAVE_FUNCTION_DESCRIPTORS
+void *dereference_function_descriptor(void *ptr)
+{
+	func_desc_t *desc = ptr;
+	void *p;
+
+	if (!get_kernel_nofault(p, (void *)&desc->addr))
+		ptr = p;
+	return ptr;
+}
+
+void *dereference_kernel_function_descriptor(void *ptr)
+{
+	if (ptr < (void *)__start_opd || ptr >= (void *)__end_opd)
+		return ptr;
+
+	return dereference_function_descriptor(ptr);
+}
+#endif
+
 int func_ptr_is_kernel_text(void *ptr)
 {
 	unsigned long addr;
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 99+ messages in thread

* [PATCH v3 08/12] asm-generic: Refactor dereference_[kernel]_function_descriptor()
@ 2021-10-17 12:38   ` Christophe Leroy
  0 siblings, 0 replies; 99+ messages in thread
From: Christophe Leroy @ 2021-10-17 12:38 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Andrew Morton, James E.J. Bottomley, Helge Deller, Arnd Bergmann,
	Kees Cook, Greg Kroah-Hartman
  Cc: linux-arch, linux-ia64, linux-parisc, linux-kernel, linux-mm,
	linuxppc-dev

dereference_function_descriptor() and
dereference_kernel_function_descriptor() are identical on the
three architectures implementing them.

Make them common and put them out-of-line in kernel/extable.c
which is one of the users and has similar type of functions.

Reviewed-by: Kees Cook <keescook@chromium.org>
Reviewed-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
 arch/ia64/include/asm/sections.h    | 19 -------------------
 arch/parisc/include/asm/sections.h  |  9 ---------
 arch/parisc/kernel/process.c        | 21 ---------------------
 arch/powerpc/include/asm/sections.h | 23 -----------------------
 include/asm-generic/sections.h      |  2 ++
 kernel/extable.c                    | 23 ++++++++++++++++++++++-
 6 files changed, 24 insertions(+), 73 deletions(-)

diff --git a/arch/ia64/include/asm/sections.h b/arch/ia64/include/asm/sections.h
index 3abe0562b01a..8e0875cf6071 100644
--- a/arch/ia64/include/asm/sections.h
+++ b/arch/ia64/include/asm/sections.h
@@ -30,23 +30,4 @@ extern char __start_gate_brl_fsys_bubble_down_patchlist[], __end_gate_brl_fsys_b
 extern char __start_unwind[], __end_unwind[];
 extern char __start_ivt_text[], __end_ivt_text[];
 
-#undef dereference_function_descriptor
-static inline void *dereference_function_descriptor(void *ptr)
-{
-	struct fdesc *desc = ptr;
-	void *p;
-
-	if (!get_kernel_nofault(p, (void *)&desc->addr))
-		ptr = p;
-	return ptr;
-}
-
-#undef dereference_kernel_function_descriptor
-static inline void *dereference_kernel_function_descriptor(void *ptr)
-{
-	if (ptr < (void *)__start_opd || ptr >= (void *)__end_opd)
-		return ptr;
-	return dereference_function_descriptor(ptr);
-}
-
 #endif /* _ASM_IA64_SECTIONS_H */
diff --git a/arch/parisc/include/asm/sections.h b/arch/parisc/include/asm/sections.h
index ace1d4047a0b..33df42b5cc6d 100644
--- a/arch/parisc/include/asm/sections.h
+++ b/arch/parisc/include/asm/sections.h
@@ -12,13 +12,4 @@ typedef Elf64_Fdesc func_desc_t;
 
 extern char __alt_instructions[], __alt_instructions_end[];
 
-#ifdef CONFIG_64BIT
-
-#undef dereference_function_descriptor
-void *dereference_function_descriptor(void *);
-
-#undef dereference_kernel_function_descriptor
-void *dereference_kernel_function_descriptor(void *);
-#endif
-
 #endif
diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c
index 38ec4ae81239..7382576b52a8 100644
--- a/arch/parisc/kernel/process.c
+++ b/arch/parisc/kernel/process.c
@@ -266,27 +266,6 @@ get_wchan(struct task_struct *p)
 	return 0;
 }
 
-#ifdef CONFIG_64BIT
-void *dereference_function_descriptor(void *ptr)
-{
-	Elf64_Fdesc *desc = ptr;
-	void *p;
-
-	if (!get_kernel_nofault(p, (void *)&desc->addr))
-		ptr = p;
-	return ptr;
-}
-
-void *dereference_kernel_function_descriptor(void *ptr)
-{
-	if (ptr < (void *)__start_opd ||
-			ptr >= (void *)__end_opd)
-		return ptr;
-
-	return dereference_function_descriptor(ptr);
-}
-#endif
-
 static inline unsigned long brk_rnd(void)
 {
 	return (get_random_int() & BRK_RND_MASK) << PAGE_SHIFT;
diff --git a/arch/powerpc/include/asm/sections.h b/arch/powerpc/include/asm/sections.h
index 1e6b6e732fb3..2c3de9bd1a90 100644
--- a/arch/powerpc/include/asm/sections.h
+++ b/arch/powerpc/include/asm/sections.h
@@ -71,29 +71,6 @@ static inline int overlaps_kernel_text(unsigned long start, unsigned long end)
 		(unsigned long)_stext < end;
 }
 
-#ifdef PPC64_ELF_ABI_v1
-
-#undef dereference_function_descriptor
-static inline void *dereference_function_descriptor(void *ptr)
-{
-	struct func_desc *desc = ptr;
-	void *p;
-
-	if (!get_kernel_nofault(p, (void *)&desc->addr))
-		ptr = p;
-	return ptr;
-}
-
-#undef dereference_kernel_function_descriptor
-static inline void *dereference_kernel_function_descriptor(void *ptr)
-{
-	if (ptr < (void *)__start_opd || ptr >= (void *)__end_opd)
-		return ptr;
-
-	return dereference_function_descriptor(ptr);
-}
-#endif /* PPC64_ELF_ABI_v1 */
-
 #endif
 
 #endif /* __KERNEL__ */
diff --git a/include/asm-generic/sections.h b/include/asm-generic/sections.h
index 33b51efe3a24..c9f30b6e81f9 100644
--- a/include/asm-generic/sections.h
+++ b/include/asm-generic/sections.h
@@ -60,6 +60,8 @@ extern __visible const void __nosave_begin, __nosave_end;
 
 /* Function descriptor handling (if any).  Override in asm/sections.h */
 #ifdef CONFIG_HAVE_FUNCTION_DESCRIPTORS
+void *dereference_function_descriptor(void *ptr);
+void *dereference_kernel_function_descriptor(void *ptr);
 #else
 #define dereference_function_descriptor(p) ((void *)(p))
 #define dereference_kernel_function_descriptor(p) ((void *)(p))
diff --git a/kernel/extable.c b/kernel/extable.c
index b0ea5eb0c3b4..1ef13789bea9 100644
--- a/kernel/extable.c
+++ b/kernel/extable.c
@@ -3,6 +3,7 @@
    Copyright (C) 2001 Rusty Russell, 2002 Rusty Russell IBM.
 
 */
+#include <linux/elf.h>
 #include <linux/ftrace.h>
 #include <linux/memory.h>
 #include <linux/extable.h>
@@ -159,12 +160,32 @@ int kernel_text_address(unsigned long addr)
 }
 
 /*
- * On some architectures (PPC64, IA64) function pointers
+ * On some architectures (PPC64, IA64, PARISC) function pointers
  * are actually only tokens to some data that then holds the
  * real function address. As a result, to find if a function
  * pointer is part of the kernel text, we need to do some
  * special dereferencing first.
  */
+#ifdef CONFIG_HAVE_FUNCTION_DESCRIPTORS
+void *dereference_function_descriptor(void *ptr)
+{
+	func_desc_t *desc = ptr;
+	void *p;
+
+	if (!get_kernel_nofault(p, (void *)&desc->addr))
+		ptr = p;
+	return ptr;
+}
+
+void *dereference_kernel_function_descriptor(void *ptr)
+{
+	if (ptr < (void *)__start_opd || ptr >= (void *)__end_opd)
+		return ptr;
+
+	return dereference_function_descriptor(ptr);
+}
+#endif
+
 int func_ptr_is_kernel_text(void *ptr)
 {
 	unsigned long addr;
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 99+ messages in thread

* [PATCH v3 08/12] asm-generic: Refactor dereference_[kernel]_function_descriptor()
@ 2021-10-17 12:38   ` Christophe Leroy
  0 siblings, 0 replies; 99+ messages in thread
From: Christophe Leroy @ 2021-10-17 12:38 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Andrew Morton, James E.J. Bottomley, Helge Deller, Arnd Bergmann,
	Kees Cook, Greg Kroah-Hartman
  Cc: Christophe Leroy, linux-kernel, linuxppc-dev, linux-ia64,
	linux-parisc, linux-arch, linux-mm

dereference_function_descriptor() and
dereference_kernel_function_descriptor() are identical on the
three architectures implementing them.

Make them common and put them out-of-line in kernel/extable.c
which is one of the users and has similar type of functions.

Reviewed-by: Kees Cook <keescook@chromium.org>
Reviewed-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
 arch/ia64/include/asm/sections.h    | 19 -------------------
 arch/parisc/include/asm/sections.h  |  9 ---------
 arch/parisc/kernel/process.c        | 21 ---------------------
 arch/powerpc/include/asm/sections.h | 23 -----------------------
 include/asm-generic/sections.h      |  2 ++
 kernel/extable.c                    | 23 ++++++++++++++++++++++-
 6 files changed, 24 insertions(+), 73 deletions(-)

diff --git a/arch/ia64/include/asm/sections.h b/arch/ia64/include/asm/sections.h
index 3abe0562b01a..8e0875cf6071 100644
--- a/arch/ia64/include/asm/sections.h
+++ b/arch/ia64/include/asm/sections.h
@@ -30,23 +30,4 @@ extern char __start_gate_brl_fsys_bubble_down_patchlist[], __end_gate_brl_fsys_b
 extern char __start_unwind[], __end_unwind[];
 extern char __start_ivt_text[], __end_ivt_text[];
 
-#undef dereference_function_descriptor
-static inline void *dereference_function_descriptor(void *ptr)
-{
-	struct fdesc *desc = ptr;
-	void *p;
-
-	if (!get_kernel_nofault(p, (void *)&desc->addr))
-		ptr = p;
-	return ptr;
-}
-
-#undef dereference_kernel_function_descriptor
-static inline void *dereference_kernel_function_descriptor(void *ptr)
-{
-	if (ptr < (void *)__start_opd || ptr >= (void *)__end_opd)
-		return ptr;
-	return dereference_function_descriptor(ptr);
-}
-
 #endif /* _ASM_IA64_SECTIONS_H */
diff --git a/arch/parisc/include/asm/sections.h b/arch/parisc/include/asm/sections.h
index ace1d4047a0b..33df42b5cc6d 100644
--- a/arch/parisc/include/asm/sections.h
+++ b/arch/parisc/include/asm/sections.h
@@ -12,13 +12,4 @@ typedef Elf64_Fdesc func_desc_t;
 
 extern char __alt_instructions[], __alt_instructions_end[];
 
-#ifdef CONFIG_64BIT
-
-#undef dereference_function_descriptor
-void *dereference_function_descriptor(void *);
-
-#undef dereference_kernel_function_descriptor
-void *dereference_kernel_function_descriptor(void *);
-#endif
-
 #endif
diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c
index 38ec4ae81239..7382576b52a8 100644
--- a/arch/parisc/kernel/process.c
+++ b/arch/parisc/kernel/process.c
@@ -266,27 +266,6 @@ get_wchan(struct task_struct *p)
 	return 0;
 }
 
-#ifdef CONFIG_64BIT
-void *dereference_function_descriptor(void *ptr)
-{
-	Elf64_Fdesc *desc = ptr;
-	void *p;
-
-	if (!get_kernel_nofault(p, (void *)&desc->addr))
-		ptr = p;
-	return ptr;
-}
-
-void *dereference_kernel_function_descriptor(void *ptr)
-{
-	if (ptr < (void *)__start_opd ||
-			ptr >= (void *)__end_opd)
-		return ptr;
-
-	return dereference_function_descriptor(ptr);
-}
-#endif
-
 static inline unsigned long brk_rnd(void)
 {
 	return (get_random_int() & BRK_RND_MASK) << PAGE_SHIFT;
diff --git a/arch/powerpc/include/asm/sections.h b/arch/powerpc/include/asm/sections.h
index 1e6b6e732fb3..2c3de9bd1a90 100644
--- a/arch/powerpc/include/asm/sections.h
+++ b/arch/powerpc/include/asm/sections.h
@@ -71,29 +71,6 @@ static inline int overlaps_kernel_text(unsigned long start, unsigned long end)
 		(unsigned long)_stext < end;
 }
 
-#ifdef PPC64_ELF_ABI_v1
-
-#undef dereference_function_descriptor
-static inline void *dereference_function_descriptor(void *ptr)
-{
-	struct func_desc *desc = ptr;
-	void *p;
-
-	if (!get_kernel_nofault(p, (void *)&desc->addr))
-		ptr = p;
-	return ptr;
-}
-
-#undef dereference_kernel_function_descriptor
-static inline void *dereference_kernel_function_descriptor(void *ptr)
-{
-	if (ptr < (void *)__start_opd || ptr >= (void *)__end_opd)
-		return ptr;
-
-	return dereference_function_descriptor(ptr);
-}
-#endif /* PPC64_ELF_ABI_v1 */
-
 #endif
 
 #endif /* __KERNEL__ */
diff --git a/include/asm-generic/sections.h b/include/asm-generic/sections.h
index 33b51efe3a24..c9f30b6e81f9 100644
--- a/include/asm-generic/sections.h
+++ b/include/asm-generic/sections.h
@@ -60,6 +60,8 @@ extern __visible const void __nosave_begin, __nosave_end;
 
 /* Function descriptor handling (if any).  Override in asm/sections.h */
 #ifdef CONFIG_HAVE_FUNCTION_DESCRIPTORS
+void *dereference_function_descriptor(void *ptr);
+void *dereference_kernel_function_descriptor(void *ptr);
 #else
 #define dereference_function_descriptor(p) ((void *)(p))
 #define dereference_kernel_function_descriptor(p) ((void *)(p))
diff --git a/kernel/extable.c b/kernel/extable.c
index b0ea5eb0c3b4..1ef13789bea9 100644
--- a/kernel/extable.c
+++ b/kernel/extable.c
@@ -3,6 +3,7 @@
    Copyright (C) 2001 Rusty Russell, 2002 Rusty Russell IBM.
 
 */
+#include <linux/elf.h>
 #include <linux/ftrace.h>
 #include <linux/memory.h>
 #include <linux/extable.h>
@@ -159,12 +160,32 @@ int kernel_text_address(unsigned long addr)
 }
 
 /*
- * On some architectures (PPC64, IA64) function pointers
+ * On some architectures (PPC64, IA64, PARISC) function pointers
  * are actually only tokens to some data that then holds the
  * real function address. As a result, to find if a function
  * pointer is part of the kernel text, we need to do some
  * special dereferencing first.
  */
+#ifdef CONFIG_HAVE_FUNCTION_DESCRIPTORS
+void *dereference_function_descriptor(void *ptr)
+{
+	func_desc_t *desc = ptr;
+	void *p;
+
+	if (!get_kernel_nofault(p, (void *)&desc->addr))
+		ptr = p;
+	return ptr;
+}
+
+void *dereference_kernel_function_descriptor(void *ptr)
+{
+	if (ptr < (void *)__start_opd || ptr >= (void *)__end_opd)
+		return ptr;
+
+	return dereference_function_descriptor(ptr);
+}
+#endif
+
 int func_ptr_is_kernel_text(void *ptr)
 {
 	unsigned long addr;
-- 
2.31.1

^ permalink raw reply related	[flat|nested] 99+ messages in thread

* [PATCH v3 09/12] lkdtm: Force do_nothing() out of line
  2021-10-17 12:38 ` Christophe Leroy
  (?)
@ 2021-10-17 12:38   ` Christophe Leroy
  -1 siblings, 0 replies; 99+ messages in thread
From: Christophe Leroy @ 2021-10-17 12:38 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Andrew Morton, James E.J. Bottomley, Helge Deller, Arnd Bergmann,
	Kees Cook, Greg Kroah-Hartman
  Cc: Christophe Leroy, linux-kernel, linuxppc-dev, linux-ia64,
	linux-parisc, linux-arch, linux-mm

LKDTM tests display that the run do_nothing() at a given
address, but in reality do_nothing() is inlined into the
caller.

Force it out of line so that it really runs text at the
displayed address.

Acked-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
 drivers/misc/lkdtm/perms.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/misc/lkdtm/perms.c b/drivers/misc/lkdtm/perms.c
index 2dede2ef658f..60b3b2fe929d 100644
--- a/drivers/misc/lkdtm/perms.c
+++ b/drivers/misc/lkdtm/perms.c
@@ -21,7 +21,7 @@
 /* This is non-const, so it will end up in the .data section. */
 static u8 data_area[EXEC_SIZE];
 
-/* This is cost, so it will end up in the .rodata section. */
+/* This is const, so it will end up in the .rodata section. */
 static const unsigned long rodata = 0xAA55AA55;
 
 /* This is marked __ro_after_init, so it should ultimately be .rodata. */
@@ -31,7 +31,7 @@ static unsigned long ro_after_init __ro_after_init = 0x55AA5500;
  * This just returns to the caller. It is designed to be copied into
  * non-executable memory regions.
  */
-static void do_nothing(void)
+static noinline void do_nothing(void)
 {
 	return;
 }
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 99+ messages in thread

* [PATCH v3 09/12] lkdtm: Force do_nothing() out of line
@ 2021-10-17 12:38   ` Christophe Leroy
  0 siblings, 0 replies; 99+ messages in thread
From: Christophe Leroy @ 2021-10-17 12:38 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Andrew Morton, James E.J. Bottomley, Helge Deller, Arnd Bergmann,
	Kees Cook, Greg Kroah-Hartman
  Cc: linux-arch, linux-ia64, linux-parisc, linux-kernel, linux-mm,
	linuxppc-dev

LKDTM tests display that the run do_nothing() at a given
address, but in reality do_nothing() is inlined into the
caller.

Force it out of line so that it really runs text at the
displayed address.

Acked-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
 drivers/misc/lkdtm/perms.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/misc/lkdtm/perms.c b/drivers/misc/lkdtm/perms.c
index 2dede2ef658f..60b3b2fe929d 100644
--- a/drivers/misc/lkdtm/perms.c
+++ b/drivers/misc/lkdtm/perms.c
@@ -21,7 +21,7 @@
 /* This is non-const, so it will end up in the .data section. */
 static u8 data_area[EXEC_SIZE];
 
-/* This is cost, so it will end up in the .rodata section. */
+/* This is const, so it will end up in the .rodata section. */
 static const unsigned long rodata = 0xAA55AA55;
 
 /* This is marked __ro_after_init, so it should ultimately be .rodata. */
@@ -31,7 +31,7 @@ static unsigned long ro_after_init __ro_after_init = 0x55AA5500;
  * This just returns to the caller. It is designed to be copied into
  * non-executable memory regions.
  */
-static void do_nothing(void)
+static noinline void do_nothing(void)
 {
 	return;
 }
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 99+ messages in thread

* [PATCH v3 09/12] lkdtm: Force do_nothing() out of line
@ 2021-10-17 12:38   ` Christophe Leroy
  0 siblings, 0 replies; 99+ messages in thread
From: Christophe Leroy @ 2021-10-17 12:38 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Andrew Morton, James E.J. Bottomley, Helge Deller, Arnd Bergmann,
	Kees Cook, Greg Kroah-Hartman
  Cc: Christophe Leroy, linux-kernel, linuxppc-dev, linux-ia64,
	linux-parisc, linux-arch, linux-mm

LKDTM tests display that the run do_nothing() at a given
address, but in reality do_nothing() is inlined into the
caller.

Force it out of line so that it really runs text at the
displayed address.

Acked-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
 drivers/misc/lkdtm/perms.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/misc/lkdtm/perms.c b/drivers/misc/lkdtm/perms.c
index 2dede2ef658f..60b3b2fe929d 100644
--- a/drivers/misc/lkdtm/perms.c
+++ b/drivers/misc/lkdtm/perms.c
@@ -21,7 +21,7 @@
 /* This is non-const, so it will end up in the .data section. */
 static u8 data_area[EXEC_SIZE];
 
-/* This is cost, so it will end up in the .rodata section. */
+/* This is const, so it will end up in the .rodata section. */
 static const unsigned long rodata = 0xAA55AA55;
 
 /* This is marked __ro_after_init, so it should ultimately be .rodata. */
@@ -31,7 +31,7 @@ static unsigned long ro_after_init __ro_after_init = 0x55AA5500;
  * This just returns to the caller. It is designed to be copied into
  * non-executable memory regions.
  */
-static void do_nothing(void)
+static noinline void do_nothing(void)
 {
 	return;
 }
-- 
2.31.1

^ permalink raw reply related	[flat|nested] 99+ messages in thread

* [PATCH v3 10/12] lkdtm: Really write into kernel text in WRITE_KERN
  2021-10-17 12:38 ` Christophe Leroy
  (?)
@ 2021-10-17 12:38   ` Christophe Leroy
  -1 siblings, 0 replies; 99+ messages in thread
From: Christophe Leroy @ 2021-10-17 12:38 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Andrew Morton, James E.J. Bottomley, Helge Deller, Arnd Bergmann,
	Kees Cook, Greg Kroah-Hartman
  Cc: Christophe Leroy, linux-kernel, linuxppc-dev, linux-ia64,
	linux-parisc, linux-arch, linux-mm

WRITE_KERN is supposed to overwrite some kernel text, namely
do_overwritten() function.

But at the time being it overwrites do_overwritten() function
descriptor, not function text.

Fix it by dereferencing the function descriptor to obtain
function text pointer.

And make do_overwritten() noinline so that it is really
do_overwritten() which is called by lkdtm_WRITE_KERN().

Acked-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
 drivers/misc/lkdtm/perms.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/misc/lkdtm/perms.c b/drivers/misc/lkdtm/perms.c
index 60b3b2fe929d..035fcca441f0 100644
--- a/drivers/misc/lkdtm/perms.c
+++ b/drivers/misc/lkdtm/perms.c
@@ -10,6 +10,7 @@
 #include <linux/mman.h>
 #include <linux/uaccess.h>
 #include <asm/cacheflush.h>
+#include <asm/sections.h>
 
 /* Whether or not to fill the target memory area with do_nothing(). */
 #define CODE_WRITE	true
@@ -37,7 +38,7 @@ static noinline void do_nothing(void)
 }
 
 /* Must immediately follow do_nothing for size calculuations to work out. */
-static void do_overwritten(void)
+static noinline void do_overwritten(void)
 {
 	pr_info("do_overwritten wasn't overwritten!\n");
 	return;
@@ -113,8 +114,9 @@ void lkdtm_WRITE_KERN(void)
 	size_t size;
 	volatile unsigned char *ptr;
 
-	size = (unsigned long)do_overwritten - (unsigned long)do_nothing;
-	ptr = (unsigned char *)do_overwritten;
+	size = (unsigned long)dereference_function_descriptor(do_overwritten) -
+	       (unsigned long)dereference_function_descriptor(do_nothing);
+	ptr = dereference_function_descriptor(do_overwritten);
 
 	pr_info("attempting bad %zu byte write at %px\n", size, ptr);
 	memcpy((void *)ptr, (unsigned char *)do_nothing, size);
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 99+ messages in thread

* [PATCH v3 10/12] lkdtm: Really write into kernel text in WRITE_KERN
@ 2021-10-17 12:38   ` Christophe Leroy
  0 siblings, 0 replies; 99+ messages in thread
From: Christophe Leroy @ 2021-10-17 12:38 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Andrew Morton, James E.J. Bottomley, Helge Deller, Arnd Bergmann,
	Kees Cook, Greg Kroah-Hartman
  Cc: linux-arch, linux-ia64, linux-parisc, linux-kernel, linux-mm,
	linuxppc-dev

WRITE_KERN is supposed to overwrite some kernel text, namely
do_overwritten() function.

But at the time being it overwrites do_overwritten() function
descriptor, not function text.

Fix it by dereferencing the function descriptor to obtain
function text pointer.

And make do_overwritten() noinline so that it is really
do_overwritten() which is called by lkdtm_WRITE_KERN().

Acked-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
 drivers/misc/lkdtm/perms.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/misc/lkdtm/perms.c b/drivers/misc/lkdtm/perms.c
index 60b3b2fe929d..035fcca441f0 100644
--- a/drivers/misc/lkdtm/perms.c
+++ b/drivers/misc/lkdtm/perms.c
@@ -10,6 +10,7 @@
 #include <linux/mman.h>
 #include <linux/uaccess.h>
 #include <asm/cacheflush.h>
+#include <asm/sections.h>
 
 /* Whether or not to fill the target memory area with do_nothing(). */
 #define CODE_WRITE	true
@@ -37,7 +38,7 @@ static noinline void do_nothing(void)
 }
 
 /* Must immediately follow do_nothing for size calculuations to work out. */
-static void do_overwritten(void)
+static noinline void do_overwritten(void)
 {
 	pr_info("do_overwritten wasn't overwritten!\n");
 	return;
@@ -113,8 +114,9 @@ void lkdtm_WRITE_KERN(void)
 	size_t size;
 	volatile unsigned char *ptr;
 
-	size = (unsigned long)do_overwritten - (unsigned long)do_nothing;
-	ptr = (unsigned char *)do_overwritten;
+	size = (unsigned long)dereference_function_descriptor(do_overwritten) -
+	       (unsigned long)dereference_function_descriptor(do_nothing);
+	ptr = dereference_function_descriptor(do_overwritten);
 
 	pr_info("attempting bad %zu byte write at %px\n", size, ptr);
 	memcpy((void *)ptr, (unsigned char *)do_nothing, size);
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 99+ messages in thread

* [PATCH v3 10/12] lkdtm: Really write into kernel text in WRITE_KERN
@ 2021-10-17 12:38   ` Christophe Leroy
  0 siblings, 0 replies; 99+ messages in thread
From: Christophe Leroy @ 2021-10-17 12:38 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Andrew Morton, James E.J. Bottomley, Helge Deller, Arnd Bergmann,
	Kees Cook, Greg Kroah-Hartman
  Cc: Christophe Leroy, linux-kernel, linuxppc-dev, linux-ia64,
	linux-parisc, linux-arch, linux-mm

WRITE_KERN is supposed to overwrite some kernel text, namely
do_overwritten() function.

But at the time being it overwrites do_overwritten() function
descriptor, not function text.

Fix it by dereferencing the function descriptor to obtain
function text pointer.

And make do_overwritten() noinline so that it is really
do_overwritten() which is called by lkdtm_WRITE_KERN().

Acked-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
 drivers/misc/lkdtm/perms.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/misc/lkdtm/perms.c b/drivers/misc/lkdtm/perms.c
index 60b3b2fe929d..035fcca441f0 100644
--- a/drivers/misc/lkdtm/perms.c
+++ b/drivers/misc/lkdtm/perms.c
@@ -10,6 +10,7 @@
 #include <linux/mman.h>
 #include <linux/uaccess.h>
 #include <asm/cacheflush.h>
+#include <asm/sections.h>
 
 /* Whether or not to fill the target memory area with do_nothing(). */
 #define CODE_WRITE	true
@@ -37,7 +38,7 @@ static noinline void do_nothing(void)
 }
 
 /* Must immediately follow do_nothing for size calculuations to work out. */
-static void do_overwritten(void)
+static noinline void do_overwritten(void)
 {
 	pr_info("do_overwritten wasn't overwritten!\n");
 	return;
@@ -113,8 +114,9 @@ void lkdtm_WRITE_KERN(void)
 	size_t size;
 	volatile unsigned char *ptr;
 
-	size = (unsigned long)do_overwritten - (unsigned long)do_nothing;
-	ptr = (unsigned char *)do_overwritten;
+	size = (unsigned long)dereference_function_descriptor(do_overwritten) -
+	       (unsigned long)dereference_function_descriptor(do_nothing);
+	ptr = dereference_function_descriptor(do_overwritten);
 
 	pr_info("attempting bad %zu byte write at %px\n", size, ptr);
 	memcpy((void *)ptr, (unsigned char *)do_nothing, size);
-- 
2.31.1

^ permalink raw reply related	[flat|nested] 99+ messages in thread

* [PATCH v3 11/12] lkdtm: Fix execute_[user]_location()
  2021-10-17 12:38 ` Christophe Leroy
  (?)
@ 2021-10-17 12:38   ` Christophe Leroy
  -1 siblings, 0 replies; 99+ messages in thread
From: Christophe Leroy @ 2021-10-17 12:38 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Andrew Morton, James E.J. Bottomley, Helge Deller, Arnd Bergmann,
	Kees Cook, Greg Kroah-Hartman
  Cc: Christophe Leroy, linux-kernel, linuxppc-dev, linux-ia64,
	linux-parisc, linux-arch, linux-mm

execute_location() and execute_user_location() intent
to copy do_nothing() text and execute it at a new location.
However, at the time being it doesn't copy do_nothing() function
but do_nothing() function descriptor which still points to the
original text. So at the end it still executes do_nothing() at
its original location allthough using a copied function descriptor.

So, fix that by really copying do_nothing() text and build a new
function descriptor by copying do_nothing() function descriptor and
updating the target address with the new location.

Also fix the displayed addresses by dereferencing do_nothing()
function descriptor.

Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
 drivers/misc/lkdtm/perms.c | 37 ++++++++++++++++++++++++++++---------
 1 file changed, 28 insertions(+), 9 deletions(-)

diff --git a/drivers/misc/lkdtm/perms.c b/drivers/misc/lkdtm/perms.c
index 035fcca441f0..1cf24c4a79e9 100644
--- a/drivers/misc/lkdtm/perms.c
+++ b/drivers/misc/lkdtm/perms.c
@@ -44,19 +44,34 @@ static noinline void do_overwritten(void)
 	return;
 }
 
+static void *setup_function_descriptor(func_desc_t *fdesc, void *dst)
+{
+	if (!have_function_descriptors())
+		return dst;
+
+	memcpy(fdesc, do_nothing, sizeof(*fdesc));
+	fdesc->addr = (unsigned long)dst;
+	barrier();
+
+	return fdesc;
+}
+
 static noinline void execute_location(void *dst, bool write)
 {
-	void (*func)(void) = dst;
+	void (*func)(void);
+	func_desc_t fdesc;
+	void *do_nothing_text = dereference_function_descriptor(do_nothing);
 
-	pr_info("attempting ok execution at %px\n", do_nothing);
+	pr_info("attempting ok execution at %px\n", do_nothing_text);
 	do_nothing();
 
 	if (write == CODE_WRITE) {
-		memcpy(dst, do_nothing, EXEC_SIZE);
+		memcpy(dst, do_nothing_text, EXEC_SIZE);
 		flush_icache_range((unsigned long)dst,
 				   (unsigned long)dst + EXEC_SIZE);
 	}
-	pr_info("attempting bad execution at %px\n", func);
+	pr_info("attempting bad execution at %px\n", dst);
+	func = setup_function_descriptor(&fdesc, dst);
 	func();
 	pr_err("FAIL: func returned\n");
 }
@@ -66,16 +81,19 @@ static void execute_user_location(void *dst)
 	int copied;
 
 	/* Intentionally crossing kernel/user memory boundary. */
-	void (*func)(void) = dst;
+	void (*func)(void);
+	func_desc_t fdesc;
+	void *do_nothing_text = dereference_function_descriptor(do_nothing);
 
-	pr_info("attempting ok execution at %px\n", do_nothing);
+	pr_info("attempting ok execution at %px\n", do_nothing_text);
 	do_nothing();
 
-	copied = access_process_vm(current, (unsigned long)dst, do_nothing,
+	copied = access_process_vm(current, (unsigned long)dst, do_nothing_text,
 				   EXEC_SIZE, FOLL_WRITE);
 	if (copied < EXEC_SIZE)
 		return;
-	pr_info("attempting bad execution at %px\n", func);
+	pr_info("attempting bad execution at %px\n", dst);
+	func = setup_function_descriptor(&fdesc, dst);
 	func();
 	pr_err("FAIL: func returned\n");
 }
@@ -153,7 +171,8 @@ void lkdtm_EXEC_VMALLOC(void)
 
 void lkdtm_EXEC_RODATA(void)
 {
-	execute_location(lkdtm_rodata_do_nothing, CODE_AS_IS);
+	execute_location(dereference_function_descriptor(lkdtm_rodata_do_nothing),
+			 CODE_AS_IS);
 }
 
 void lkdtm_EXEC_USERSPACE(void)
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 99+ messages in thread

* [PATCH v3 11/12] lkdtm: Fix execute_[user]_location()
@ 2021-10-17 12:38   ` Christophe Leroy
  0 siblings, 0 replies; 99+ messages in thread
From: Christophe Leroy @ 2021-10-17 12:38 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Andrew Morton, James E.J. Bottomley, Helge Deller, Arnd Bergmann,
	Kees Cook, Greg Kroah-Hartman
  Cc: linux-arch, linux-ia64, linux-parisc, linux-kernel, linux-mm,
	linuxppc-dev

execute_location() and execute_user_location() intent
to copy do_nothing() text and execute it at a new location.
However, at the time being it doesn't copy do_nothing() function
but do_nothing() function descriptor which still points to the
original text. So at the end it still executes do_nothing() at
its original location allthough using a copied function descriptor.

So, fix that by really copying do_nothing() text and build a new
function descriptor by copying do_nothing() function descriptor and
updating the target address with the new location.

Also fix the displayed addresses by dereferencing do_nothing()
function descriptor.

Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
 drivers/misc/lkdtm/perms.c | 37 ++++++++++++++++++++++++++++---------
 1 file changed, 28 insertions(+), 9 deletions(-)

diff --git a/drivers/misc/lkdtm/perms.c b/drivers/misc/lkdtm/perms.c
index 035fcca441f0..1cf24c4a79e9 100644
--- a/drivers/misc/lkdtm/perms.c
+++ b/drivers/misc/lkdtm/perms.c
@@ -44,19 +44,34 @@ static noinline void do_overwritten(void)
 	return;
 }
 
+static void *setup_function_descriptor(func_desc_t *fdesc, void *dst)
+{
+	if (!have_function_descriptors())
+		return dst;
+
+	memcpy(fdesc, do_nothing, sizeof(*fdesc));
+	fdesc->addr = (unsigned long)dst;
+	barrier();
+
+	return fdesc;
+}
+
 static noinline void execute_location(void *dst, bool write)
 {
-	void (*func)(void) = dst;
+	void (*func)(void);
+	func_desc_t fdesc;
+	void *do_nothing_text = dereference_function_descriptor(do_nothing);
 
-	pr_info("attempting ok execution at %px\n", do_nothing);
+	pr_info("attempting ok execution at %px\n", do_nothing_text);
 	do_nothing();
 
 	if (write == CODE_WRITE) {
-		memcpy(dst, do_nothing, EXEC_SIZE);
+		memcpy(dst, do_nothing_text, EXEC_SIZE);
 		flush_icache_range((unsigned long)dst,
 				   (unsigned long)dst + EXEC_SIZE);
 	}
-	pr_info("attempting bad execution at %px\n", func);
+	pr_info("attempting bad execution at %px\n", dst);
+	func = setup_function_descriptor(&fdesc, dst);
 	func();
 	pr_err("FAIL: func returned\n");
 }
@@ -66,16 +81,19 @@ static void execute_user_location(void *dst)
 	int copied;
 
 	/* Intentionally crossing kernel/user memory boundary. */
-	void (*func)(void) = dst;
+	void (*func)(void);
+	func_desc_t fdesc;
+	void *do_nothing_text = dereference_function_descriptor(do_nothing);
 
-	pr_info("attempting ok execution at %px\n", do_nothing);
+	pr_info("attempting ok execution at %px\n", do_nothing_text);
 	do_nothing();
 
-	copied = access_process_vm(current, (unsigned long)dst, do_nothing,
+	copied = access_process_vm(current, (unsigned long)dst, do_nothing_text,
 				   EXEC_SIZE, FOLL_WRITE);
 	if (copied < EXEC_SIZE)
 		return;
-	pr_info("attempting bad execution at %px\n", func);
+	pr_info("attempting bad execution at %px\n", dst);
+	func = setup_function_descriptor(&fdesc, dst);
 	func();
 	pr_err("FAIL: func returned\n");
 }
@@ -153,7 +171,8 @@ void lkdtm_EXEC_VMALLOC(void)
 
 void lkdtm_EXEC_RODATA(void)
 {
-	execute_location(lkdtm_rodata_do_nothing, CODE_AS_IS);
+	execute_location(dereference_function_descriptor(lkdtm_rodata_do_nothing),
+			 CODE_AS_IS);
 }
 
 void lkdtm_EXEC_USERSPACE(void)
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 99+ messages in thread

* [PATCH v3 11/12] lkdtm: Fix execute_[user]_location()
@ 2021-10-17 12:38   ` Christophe Leroy
  0 siblings, 0 replies; 99+ messages in thread
From: Christophe Leroy @ 2021-10-17 12:38 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Andrew Morton, James E.J. Bottomley, Helge Deller, Arnd Bergmann,
	Kees Cook, Greg Kroah-Hartman
  Cc: Christophe Leroy, linux-kernel, linuxppc-dev, linux-ia64,
	linux-parisc, linux-arch, linux-mm

execute_location() and execute_user_location() intent
to copy do_nothing() text and execute it at a new location.
However, at the time being it doesn't copy do_nothing() function
but do_nothing() function descriptor which still points to the
original text. So at the end it still executes do_nothing() at
its original location allthough using a copied function descriptor.

So, fix that by really copying do_nothing() text and build a new
function descriptor by copying do_nothing() function descriptor and
updating the target address with the new location.

Also fix the displayed addresses by dereferencing do_nothing()
function descriptor.

Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
 drivers/misc/lkdtm/perms.c | 37 ++++++++++++++++++++++++++++---------
 1 file changed, 28 insertions(+), 9 deletions(-)

diff --git a/drivers/misc/lkdtm/perms.c b/drivers/misc/lkdtm/perms.c
index 035fcca441f0..1cf24c4a79e9 100644
--- a/drivers/misc/lkdtm/perms.c
+++ b/drivers/misc/lkdtm/perms.c
@@ -44,19 +44,34 @@ static noinline void do_overwritten(void)
 	return;
 }
 
+static void *setup_function_descriptor(func_desc_t *fdesc, void *dst)
+{
+	if (!have_function_descriptors())
+		return dst;
+
+	memcpy(fdesc, do_nothing, sizeof(*fdesc));
+	fdesc->addr = (unsigned long)dst;
+	barrier();
+
+	return fdesc;
+}
+
 static noinline void execute_location(void *dst, bool write)
 {
-	void (*func)(void) = dst;
+	void (*func)(void);
+	func_desc_t fdesc;
+	void *do_nothing_text = dereference_function_descriptor(do_nothing);
 
-	pr_info("attempting ok execution at %px\n", do_nothing);
+	pr_info("attempting ok execution at %px\n", do_nothing_text);
 	do_nothing();
 
 	if (write = CODE_WRITE) {
-		memcpy(dst, do_nothing, EXEC_SIZE);
+		memcpy(dst, do_nothing_text, EXEC_SIZE);
 		flush_icache_range((unsigned long)dst,
 				   (unsigned long)dst + EXEC_SIZE);
 	}
-	pr_info("attempting bad execution at %px\n", func);
+	pr_info("attempting bad execution at %px\n", dst);
+	func = setup_function_descriptor(&fdesc, dst);
 	func();
 	pr_err("FAIL: func returned\n");
 }
@@ -66,16 +81,19 @@ static void execute_user_location(void *dst)
 	int copied;
 
 	/* Intentionally crossing kernel/user memory boundary. */
-	void (*func)(void) = dst;
+	void (*func)(void);
+	func_desc_t fdesc;
+	void *do_nothing_text = dereference_function_descriptor(do_nothing);
 
-	pr_info("attempting ok execution at %px\n", do_nothing);
+	pr_info("attempting ok execution at %px\n", do_nothing_text);
 	do_nothing();
 
-	copied = access_process_vm(current, (unsigned long)dst, do_nothing,
+	copied = access_process_vm(current, (unsigned long)dst, do_nothing_text,
 				   EXEC_SIZE, FOLL_WRITE);
 	if (copied < EXEC_SIZE)
 		return;
-	pr_info("attempting bad execution at %px\n", func);
+	pr_info("attempting bad execution at %px\n", dst);
+	func = setup_function_descriptor(&fdesc, dst);
 	func();
 	pr_err("FAIL: func returned\n");
 }
@@ -153,7 +171,8 @@ void lkdtm_EXEC_VMALLOC(void)
 
 void lkdtm_EXEC_RODATA(void)
 {
-	execute_location(lkdtm_rodata_do_nothing, CODE_AS_IS);
+	execute_location(dereference_function_descriptor(lkdtm_rodata_do_nothing),
+			 CODE_AS_IS);
 }
 
 void lkdtm_EXEC_USERSPACE(void)
-- 
2.31.1

^ permalink raw reply related	[flat|nested] 99+ messages in thread

* [PATCH v3 12/12] lkdtm: Add a test for function descriptors protection
  2021-10-17 12:38 ` Christophe Leroy
  (?)
@ 2021-10-17 12:38   ` Christophe Leroy
  -1 siblings, 0 replies; 99+ messages in thread
From: Christophe Leroy @ 2021-10-17 12:38 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Andrew Morton, James E.J. Bottomley, Helge Deller, Arnd Bergmann,
	Kees Cook, Greg Kroah-Hartman
  Cc: Christophe Leroy, linux-kernel, linuxppc-dev, linux-ia64,
	linux-parisc, linux-arch, linux-mm

Add WRITE_OPD to check that you can't modify function
descriptors.

Gives the following result when function descriptors are
not protected:

	lkdtm: Performing direct entry WRITE_OPD
	lkdtm: attempting bad 16 bytes write at c00000000269b358
	lkdtm: FAIL: survived bad write
	lkdtm: do_nothing was hijacked!

Looks like a standard compiler barrier() is not enough to force
GCC to use the modified function descriptor. Had to add a fake empty
inline assembly to force GCC to reload the function descriptor.

Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
 drivers/misc/lkdtm/core.c  |  1 +
 drivers/misc/lkdtm/lkdtm.h |  1 +
 drivers/misc/lkdtm/perms.c | 22 ++++++++++++++++++++++
 3 files changed, 24 insertions(+)

diff --git a/drivers/misc/lkdtm/core.c b/drivers/misc/lkdtm/core.c
index fe6fd34b8caf..de092aa03b5d 100644
--- a/drivers/misc/lkdtm/core.c
+++ b/drivers/misc/lkdtm/core.c
@@ -148,6 +148,7 @@ static const struct crashtype crashtypes[] = {
 	CRASHTYPE(WRITE_RO),
 	CRASHTYPE(WRITE_RO_AFTER_INIT),
 	CRASHTYPE(WRITE_KERN),
+	CRASHTYPE(WRITE_OPD),
 	CRASHTYPE(REFCOUNT_INC_OVERFLOW),
 	CRASHTYPE(REFCOUNT_ADD_OVERFLOW),
 	CRASHTYPE(REFCOUNT_INC_NOT_ZERO_OVERFLOW),
diff --git a/drivers/misc/lkdtm/lkdtm.h b/drivers/misc/lkdtm/lkdtm.h
index c212a253edde..188bd0fd6575 100644
--- a/drivers/misc/lkdtm/lkdtm.h
+++ b/drivers/misc/lkdtm/lkdtm.h
@@ -105,6 +105,7 @@ void __init lkdtm_perms_init(void);
 void lkdtm_WRITE_RO(void);
 void lkdtm_WRITE_RO_AFTER_INIT(void);
 void lkdtm_WRITE_KERN(void);
+void lkdtm_WRITE_OPD(void);
 void lkdtm_EXEC_DATA(void);
 void lkdtm_EXEC_STACK(void);
 void lkdtm_EXEC_KMALLOC(void);
diff --git a/drivers/misc/lkdtm/perms.c b/drivers/misc/lkdtm/perms.c
index 1cf24c4a79e9..2c6aba3ff32b 100644
--- a/drivers/misc/lkdtm/perms.c
+++ b/drivers/misc/lkdtm/perms.c
@@ -44,6 +44,11 @@ static noinline void do_overwritten(void)
 	return;
 }
 
+static noinline void do_almost_nothing(void)
+{
+	pr_info("do_nothing was hijacked!\n");
+}
+
 static void *setup_function_descriptor(func_desc_t *fdesc, void *dst)
 {
 	if (!have_function_descriptors())
@@ -144,6 +149,23 @@ void lkdtm_WRITE_KERN(void)
 	do_overwritten();
 }
 
+void lkdtm_WRITE_OPD(void)
+{
+	size_t size = sizeof(func_desc_t);
+	void (*func)(void) = do_nothing;
+
+	if (!have_function_descriptors()) {
+		pr_info("XFAIL: Platform doesn't use function descriptors.\n");
+		return;
+	}
+	pr_info("attempting bad %zu bytes write at %px\n", size, do_nothing);
+	memcpy(do_nothing, do_almost_nothing, size);
+	pr_err("FAIL: survived bad write\n");
+
+	asm("" : "=m"(func));
+	func();
+}
+
 void lkdtm_EXEC_DATA(void)
 {
 	execute_location(data_area, CODE_WRITE);
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 99+ messages in thread

* [PATCH v3 12/12] lkdtm: Add a test for function descriptors protection
@ 2021-10-17 12:38   ` Christophe Leroy
  0 siblings, 0 replies; 99+ messages in thread
From: Christophe Leroy @ 2021-10-17 12:38 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Andrew Morton, James E.J. Bottomley, Helge Deller, Arnd Bergmann,
	Kees Cook, Greg Kroah-Hartman
  Cc: linux-arch, linux-ia64, linux-parisc, linux-kernel, linux-mm,
	linuxppc-dev

Add WRITE_OPD to check that you can't modify function
descriptors.

Gives the following result when function descriptors are
not protected:

	lkdtm: Performing direct entry WRITE_OPD
	lkdtm: attempting bad 16 bytes write at c00000000269b358
	lkdtm: FAIL: survived bad write
	lkdtm: do_nothing was hijacked!

Looks like a standard compiler barrier() is not enough to force
GCC to use the modified function descriptor. Had to add a fake empty
inline assembly to force GCC to reload the function descriptor.

Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
 drivers/misc/lkdtm/core.c  |  1 +
 drivers/misc/lkdtm/lkdtm.h |  1 +
 drivers/misc/lkdtm/perms.c | 22 ++++++++++++++++++++++
 3 files changed, 24 insertions(+)

diff --git a/drivers/misc/lkdtm/core.c b/drivers/misc/lkdtm/core.c
index fe6fd34b8caf..de092aa03b5d 100644
--- a/drivers/misc/lkdtm/core.c
+++ b/drivers/misc/lkdtm/core.c
@@ -148,6 +148,7 @@ static const struct crashtype crashtypes[] = {
 	CRASHTYPE(WRITE_RO),
 	CRASHTYPE(WRITE_RO_AFTER_INIT),
 	CRASHTYPE(WRITE_KERN),
+	CRASHTYPE(WRITE_OPD),
 	CRASHTYPE(REFCOUNT_INC_OVERFLOW),
 	CRASHTYPE(REFCOUNT_ADD_OVERFLOW),
 	CRASHTYPE(REFCOUNT_INC_NOT_ZERO_OVERFLOW),
diff --git a/drivers/misc/lkdtm/lkdtm.h b/drivers/misc/lkdtm/lkdtm.h
index c212a253edde..188bd0fd6575 100644
--- a/drivers/misc/lkdtm/lkdtm.h
+++ b/drivers/misc/lkdtm/lkdtm.h
@@ -105,6 +105,7 @@ void __init lkdtm_perms_init(void);
 void lkdtm_WRITE_RO(void);
 void lkdtm_WRITE_RO_AFTER_INIT(void);
 void lkdtm_WRITE_KERN(void);
+void lkdtm_WRITE_OPD(void);
 void lkdtm_EXEC_DATA(void);
 void lkdtm_EXEC_STACK(void);
 void lkdtm_EXEC_KMALLOC(void);
diff --git a/drivers/misc/lkdtm/perms.c b/drivers/misc/lkdtm/perms.c
index 1cf24c4a79e9..2c6aba3ff32b 100644
--- a/drivers/misc/lkdtm/perms.c
+++ b/drivers/misc/lkdtm/perms.c
@@ -44,6 +44,11 @@ static noinline void do_overwritten(void)
 	return;
 }
 
+static noinline void do_almost_nothing(void)
+{
+	pr_info("do_nothing was hijacked!\n");
+}
+
 static void *setup_function_descriptor(func_desc_t *fdesc, void *dst)
 {
 	if (!have_function_descriptors())
@@ -144,6 +149,23 @@ void lkdtm_WRITE_KERN(void)
 	do_overwritten();
 }
 
+void lkdtm_WRITE_OPD(void)
+{
+	size_t size = sizeof(func_desc_t);
+	void (*func)(void) = do_nothing;
+
+	if (!have_function_descriptors()) {
+		pr_info("XFAIL: Platform doesn't use function descriptors.\n");
+		return;
+	}
+	pr_info("attempting bad %zu bytes write at %px\n", size, do_nothing);
+	memcpy(do_nothing, do_almost_nothing, size);
+	pr_err("FAIL: survived bad write\n");
+
+	asm("" : "=m"(func));
+	func();
+}
+
 void lkdtm_EXEC_DATA(void)
 {
 	execute_location(data_area, CODE_WRITE);
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 99+ messages in thread

* [PATCH v3 12/12] lkdtm: Add a test for function descriptors protection
@ 2021-10-17 12:38   ` Christophe Leroy
  0 siblings, 0 replies; 99+ messages in thread
From: Christophe Leroy @ 2021-10-17 12:38 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Andrew Morton, James E.J. Bottomley, Helge Deller, Arnd Bergmann,
	Kees Cook, Greg Kroah-Hartman
  Cc: Christophe Leroy, linux-kernel, linuxppc-dev, linux-ia64,
	linux-parisc, linux-arch, linux-mm

Add WRITE_OPD to check that you can't modify function
descriptors.

Gives the following result when function descriptors are
not protected:

	lkdtm: Performing direct entry WRITE_OPD
	lkdtm: attempting bad 16 bytes write at c00000000269b358
	lkdtm: FAIL: survived bad write
	lkdtm: do_nothing was hijacked!

Looks like a standard compiler barrier() is not enough to force
GCC to use the modified function descriptor. Had to add a fake empty
inline assembly to force GCC to reload the function descriptor.

Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
 drivers/misc/lkdtm/core.c  |  1 +
 drivers/misc/lkdtm/lkdtm.h |  1 +
 drivers/misc/lkdtm/perms.c | 22 ++++++++++++++++++++++
 3 files changed, 24 insertions(+)

diff --git a/drivers/misc/lkdtm/core.c b/drivers/misc/lkdtm/core.c
index fe6fd34b8caf..de092aa03b5d 100644
--- a/drivers/misc/lkdtm/core.c
+++ b/drivers/misc/lkdtm/core.c
@@ -148,6 +148,7 @@ static const struct crashtype crashtypes[] = {
 	CRASHTYPE(WRITE_RO),
 	CRASHTYPE(WRITE_RO_AFTER_INIT),
 	CRASHTYPE(WRITE_KERN),
+	CRASHTYPE(WRITE_OPD),
 	CRASHTYPE(REFCOUNT_INC_OVERFLOW),
 	CRASHTYPE(REFCOUNT_ADD_OVERFLOW),
 	CRASHTYPE(REFCOUNT_INC_NOT_ZERO_OVERFLOW),
diff --git a/drivers/misc/lkdtm/lkdtm.h b/drivers/misc/lkdtm/lkdtm.h
index c212a253edde..188bd0fd6575 100644
--- a/drivers/misc/lkdtm/lkdtm.h
+++ b/drivers/misc/lkdtm/lkdtm.h
@@ -105,6 +105,7 @@ void __init lkdtm_perms_init(void);
 void lkdtm_WRITE_RO(void);
 void lkdtm_WRITE_RO_AFTER_INIT(void);
 void lkdtm_WRITE_KERN(void);
+void lkdtm_WRITE_OPD(void);
 void lkdtm_EXEC_DATA(void);
 void lkdtm_EXEC_STACK(void);
 void lkdtm_EXEC_KMALLOC(void);
diff --git a/drivers/misc/lkdtm/perms.c b/drivers/misc/lkdtm/perms.c
index 1cf24c4a79e9..2c6aba3ff32b 100644
--- a/drivers/misc/lkdtm/perms.c
+++ b/drivers/misc/lkdtm/perms.c
@@ -44,6 +44,11 @@ static noinline void do_overwritten(void)
 	return;
 }
 
+static noinline void do_almost_nothing(void)
+{
+	pr_info("do_nothing was hijacked!\n");
+}
+
 static void *setup_function_descriptor(func_desc_t *fdesc, void *dst)
 {
 	if (!have_function_descriptors())
@@ -144,6 +149,23 @@ void lkdtm_WRITE_KERN(void)
 	do_overwritten();
 }
 
+void lkdtm_WRITE_OPD(void)
+{
+	size_t size = sizeof(func_desc_t);
+	void (*func)(void) = do_nothing;
+
+	if (!have_function_descriptors()) {
+		pr_info("XFAIL: Platform doesn't use function descriptors.\n");
+		return;
+	}
+	pr_info("attempting bad %zu bytes write at %px\n", size, do_nothing);
+	memcpy(do_nothing, do_almost_nothing, size);
+	pr_err("FAIL: survived bad write\n");
+
+	asm("" : "=m"(func));
+	func();
+}
+
 void lkdtm_EXEC_DATA(void)
 {
 	execute_location(data_area, CODE_WRITE);
-- 
2.31.1

^ permalink raw reply related	[flat|nested] 99+ messages in thread

* Re: [PATCH v3 01/12] powerpc: Move and rename func_descr_t
  2021-10-17 12:38   ` Christophe Leroy
  (?)
@ 2021-10-18  5:58     ` Nicholas Piggin
  -1 siblings, 0 replies; 99+ messages in thread
From: Nicholas Piggin @ 2021-10-18  5:58 UTC (permalink / raw)
  To: Andrew Morton, Arnd Bergmann, Benjamin Herrenschmidt,
	Christophe Leroy, Helge Deller, Greg Kroah-Hartman,
	James E.J. Bottomley, Kees Cook, Michael Ellerman,
	Paul Mackerras
  Cc: linux-arch, linux-ia64, linux-kernel, linux-mm, linux-parisc,
	linuxppc-dev

Excerpts from Christophe Leroy's message of October 17, 2021 10:38 pm:
> There are three architectures with function descriptors, try to
> have common names for the address they contain in order to
> refactor some functions into generic functions later.
> 
> powerpc has 'entry'
> ia64 has 'ip'
> parisc has 'addr'
> 
> Vote for 'addr' and update 'func_descr_t' accordingly.
> 
> Move it in asm/elf.h to have it at the same place on all
> three architectures, remove the typedef which hides its real
> type, and change it to a smoother name 'struct func_desc'.
> 

Reviewed-by: Nicholas Piggin <npiggin@gmail.com>

> Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
> ---
>  arch/powerpc/include/asm/code-patching.h | 2 +-
>  arch/powerpc/include/asm/elf.h           | 6 ++++++
>  arch/powerpc/include/asm/types.h         | 6 ------
>  arch/powerpc/kernel/signal_64.c          | 8 ++++----
>  4 files changed, 11 insertions(+), 11 deletions(-)
> 
> diff --git a/arch/powerpc/include/asm/code-patching.h b/arch/powerpc/include/asm/code-patching.h
> index 4ba834599c4d..c6e805976e6f 100644
> --- a/arch/powerpc/include/asm/code-patching.h
> +++ b/arch/powerpc/include/asm/code-patching.h
> @@ -110,7 +110,7 @@ static inline unsigned long ppc_function_entry(void *func)
>  	 * function's descriptor. The first entry in the descriptor is the
>  	 * address of the function text.
>  	 */
> -	return ((func_descr_t *)func)->entry;
> +	return ((struct func_desc *)func)->addr;
>  #else
>  	return (unsigned long)func;
>  #endif
> diff --git a/arch/powerpc/include/asm/elf.h b/arch/powerpc/include/asm/elf.h
> index b8425e3cfd81..971589a21bc0 100644
> --- a/arch/powerpc/include/asm/elf.h
> +++ b/arch/powerpc/include/asm/elf.h
> @@ -176,4 +176,10 @@ do {									\
>  /* Relocate the kernel image to @final_address */
>  void relocate(unsigned long final_address);
>  
> +struct func_desc {
> +	unsigned long addr;
> +	unsigned long toc;
> +	unsigned long env;
> +};
> +
>  #endif /* _ASM_POWERPC_ELF_H */
> diff --git a/arch/powerpc/include/asm/types.h b/arch/powerpc/include/asm/types.h
> index f1630c553efe..97da77bc48c9 100644
> --- a/arch/powerpc/include/asm/types.h
> +++ b/arch/powerpc/include/asm/types.h
> @@ -23,12 +23,6 @@
>  
>  typedef __vector128 vector128;
>  
> -typedef struct {
> -	unsigned long entry;
> -	unsigned long toc;
> -	unsigned long env;
> -} func_descr_t;
> -
>  #endif /* __ASSEMBLY__ */
>  
>  #endif /* _ASM_POWERPC_TYPES_H */
> diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c
> index 1831bba0582e..36537d7d5191 100644
> --- a/arch/powerpc/kernel/signal_64.c
> +++ b/arch/powerpc/kernel/signal_64.c
> @@ -933,11 +933,11 @@ int handle_rt_signal64(struct ksignal *ksig, sigset_t *set,
>  		 * descriptor is the entry address of signal and the second
>  		 * entry is the TOC value we need to use.
>  		 */
> -		func_descr_t __user *funct_desc_ptr =
> -			(func_descr_t __user *) ksig->ka.sa.sa_handler;
> +		struct func_desc __user *ptr =
> +			(struct func_desc __user *)ksig->ka.sa.sa_handler;
>  
> -		err |= get_user(regs->ctr, &funct_desc_ptr->entry);
> -		err |= get_user(regs->gpr[2], &funct_desc_ptr->toc);
> +		err |= get_user(regs->ctr, &ptr->addr);
> +		err |= get_user(regs->gpr[2], &ptr->toc);
>  	}
>  
>  	/* enter the signal handler in native-endian mode */
> -- 
> 2.31.1
> 
> 
> 

^ permalink raw reply	[flat|nested] 99+ messages in thread

* Re: [PATCH v3 01/12] powerpc: Move and rename func_descr_t
@ 2021-10-18  5:58     ` Nicholas Piggin
  0 siblings, 0 replies; 99+ messages in thread
From: Nicholas Piggin @ 2021-10-18  5:58 UTC (permalink / raw)
  To: Andrew Morton, Arnd Bergmann, Benjamin Herrenschmidt,
	Christophe Leroy, Helge Deller, Greg Kroah-Hartman,
	James E.J. Bottomley, Kees Cook, Michael Ellerman,
	Paul Mackerras
  Cc: linux-arch, linux-ia64, linux-parisc, linux-kernel, linux-mm,
	linuxppc-dev

Excerpts from Christophe Leroy's message of October 17, 2021 10:38 pm:
> There are three architectures with function descriptors, try to
> have common names for the address they contain in order to
> refactor some functions into generic functions later.
> 
> powerpc has 'entry'
> ia64 has 'ip'
> parisc has 'addr'
> 
> Vote for 'addr' and update 'func_descr_t' accordingly.
> 
> Move it in asm/elf.h to have it at the same place on all
> three architectures, remove the typedef which hides its real
> type, and change it to a smoother name 'struct func_desc'.
> 

Reviewed-by: Nicholas Piggin <npiggin@gmail.com>

> Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
> ---
>  arch/powerpc/include/asm/code-patching.h | 2 +-
>  arch/powerpc/include/asm/elf.h           | 6 ++++++
>  arch/powerpc/include/asm/types.h         | 6 ------
>  arch/powerpc/kernel/signal_64.c          | 8 ++++----
>  4 files changed, 11 insertions(+), 11 deletions(-)
> 
> diff --git a/arch/powerpc/include/asm/code-patching.h b/arch/powerpc/include/asm/code-patching.h
> index 4ba834599c4d..c6e805976e6f 100644
> --- a/arch/powerpc/include/asm/code-patching.h
> +++ b/arch/powerpc/include/asm/code-patching.h
> @@ -110,7 +110,7 @@ static inline unsigned long ppc_function_entry(void *func)
>  	 * function's descriptor. The first entry in the descriptor is the
>  	 * address of the function text.
>  	 */
> -	return ((func_descr_t *)func)->entry;
> +	return ((struct func_desc *)func)->addr;
>  #else
>  	return (unsigned long)func;
>  #endif
> diff --git a/arch/powerpc/include/asm/elf.h b/arch/powerpc/include/asm/elf.h
> index b8425e3cfd81..971589a21bc0 100644
> --- a/arch/powerpc/include/asm/elf.h
> +++ b/arch/powerpc/include/asm/elf.h
> @@ -176,4 +176,10 @@ do {									\
>  /* Relocate the kernel image to @final_address */
>  void relocate(unsigned long final_address);
>  
> +struct func_desc {
> +	unsigned long addr;
> +	unsigned long toc;
> +	unsigned long env;
> +};
> +
>  #endif /* _ASM_POWERPC_ELF_H */
> diff --git a/arch/powerpc/include/asm/types.h b/arch/powerpc/include/asm/types.h
> index f1630c553efe..97da77bc48c9 100644
> --- a/arch/powerpc/include/asm/types.h
> +++ b/arch/powerpc/include/asm/types.h
> @@ -23,12 +23,6 @@
>  
>  typedef __vector128 vector128;
>  
> -typedef struct {
> -	unsigned long entry;
> -	unsigned long toc;
> -	unsigned long env;
> -} func_descr_t;
> -
>  #endif /* __ASSEMBLY__ */
>  
>  #endif /* _ASM_POWERPC_TYPES_H */
> diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c
> index 1831bba0582e..36537d7d5191 100644
> --- a/arch/powerpc/kernel/signal_64.c
> +++ b/arch/powerpc/kernel/signal_64.c
> @@ -933,11 +933,11 @@ int handle_rt_signal64(struct ksignal *ksig, sigset_t *set,
>  		 * descriptor is the entry address of signal and the second
>  		 * entry is the TOC value we need to use.
>  		 */
> -		func_descr_t __user *funct_desc_ptr =
> -			(func_descr_t __user *) ksig->ka.sa.sa_handler;
> +		struct func_desc __user *ptr =
> +			(struct func_desc __user *)ksig->ka.sa.sa_handler;
>  
> -		err |= get_user(regs->ctr, &funct_desc_ptr->entry);
> -		err |= get_user(regs->gpr[2], &funct_desc_ptr->toc);
> +		err |= get_user(regs->ctr, &ptr->addr);
> +		err |= get_user(regs->gpr[2], &ptr->toc);
>  	}
>  
>  	/* enter the signal handler in native-endian mode */
> -- 
> 2.31.1
> 
> 
> 

^ permalink raw reply	[flat|nested] 99+ messages in thread

* Re: [PATCH v3 01/12] powerpc: Move and rename func_descr_t
@ 2021-10-18  5:58     ` Nicholas Piggin
  0 siblings, 0 replies; 99+ messages in thread
From: Nicholas Piggin @ 2021-10-18  5:58 UTC (permalink / raw)
  To: Andrew Morton, Arnd Bergmann, Benjamin Herrenschmidt,
	Christophe Leroy, Helge Deller, Greg Kroah-Hartman,
	James E.J. Bottomley, Kees Cook, Michael Ellerman,
	Paul Mackerras
  Cc: linux-arch, linux-ia64, linux-kernel, linux-mm, linux-parisc,
	linuxppc-dev

Excerpts from Christophe Leroy's message of October 17, 2021 10:38 pm:
> There are three architectures with function descriptors, try to
> have common names for the address they contain in order to
> refactor some functions into generic functions later.
> 
> powerpc has 'entry'
> ia64 has 'ip'
> parisc has 'addr'
> 
> Vote for 'addr' and update 'func_descr_t' accordingly.
> 
> Move it in asm/elf.h to have it at the same place on all
> three architectures, remove the typedef which hides its real
> type, and change it to a smoother name 'struct func_desc'.
> 

Reviewed-by: Nicholas Piggin <npiggin@gmail.com>

> Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
> ---
>  arch/powerpc/include/asm/code-patching.h | 2 +-
>  arch/powerpc/include/asm/elf.h           | 6 ++++++
>  arch/powerpc/include/asm/types.h         | 6 ------
>  arch/powerpc/kernel/signal_64.c          | 8 ++++----
>  4 files changed, 11 insertions(+), 11 deletions(-)
> 
> diff --git a/arch/powerpc/include/asm/code-patching.h b/arch/powerpc/include/asm/code-patching.h
> index 4ba834599c4d..c6e805976e6f 100644
> --- a/arch/powerpc/include/asm/code-patching.h
> +++ b/arch/powerpc/include/asm/code-patching.h
> @@ -110,7 +110,7 @@ static inline unsigned long ppc_function_entry(void *func)
>  	 * function's descriptor. The first entry in the descriptor is the
>  	 * address of the function text.
>  	 */
> -	return ((func_descr_t *)func)->entry;
> +	return ((struct func_desc *)func)->addr;
>  #else
>  	return (unsigned long)func;
>  #endif
> diff --git a/arch/powerpc/include/asm/elf.h b/arch/powerpc/include/asm/elf.h
> index b8425e3cfd81..971589a21bc0 100644
> --- a/arch/powerpc/include/asm/elf.h
> +++ b/arch/powerpc/include/asm/elf.h
> @@ -176,4 +176,10 @@ do {									\
>  /* Relocate the kernel image to @final_address */
>  void relocate(unsigned long final_address);
>  
> +struct func_desc {
> +	unsigned long addr;
> +	unsigned long toc;
> +	unsigned long env;
> +};
> +
>  #endif /* _ASM_POWERPC_ELF_H */
> diff --git a/arch/powerpc/include/asm/types.h b/arch/powerpc/include/asm/types.h
> index f1630c553efe..97da77bc48c9 100644
> --- a/arch/powerpc/include/asm/types.h
> +++ b/arch/powerpc/include/asm/types.h
> @@ -23,12 +23,6 @@
>  
>  typedef __vector128 vector128;
>  
> -typedef struct {
> -	unsigned long entry;
> -	unsigned long toc;
> -	unsigned long env;
> -} func_descr_t;
> -
>  #endif /* __ASSEMBLY__ */
>  
>  #endif /* _ASM_POWERPC_TYPES_H */
> diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c
> index 1831bba0582e..36537d7d5191 100644
> --- a/arch/powerpc/kernel/signal_64.c
> +++ b/arch/powerpc/kernel/signal_64.c
> @@ -933,11 +933,11 @@ int handle_rt_signal64(struct ksignal *ksig, sigset_t *set,
>  		 * descriptor is the entry address of signal and the second
>  		 * entry is the TOC value we need to use.
>  		 */
> -		func_descr_t __user *funct_desc_ptr =
> -			(func_descr_t __user *) ksig->ka.sa.sa_handler;
> +		struct func_desc __user *ptr =
> +			(struct func_desc __user *)ksig->ka.sa.sa_handler;
>  
> -		err |= get_user(regs->ctr, &funct_desc_ptr->entry);
> -		err |= get_user(regs->gpr[2], &funct_desc_ptr->toc);
> +		err |= get_user(regs->ctr, &ptr->addr);
> +		err |= get_user(regs->gpr[2], &ptr->toc);
>  	}
>  
>  	/* enter the signal handler in native-endian mode */
> -- 
> 2.31.1
> 
> 
> 

^ permalink raw reply	[flat|nested] 99+ messages in thread

* Re: [PATCH v3 04/12] powerpc: Prepare func_desc_t for refactorisation
  2021-10-17 12:38   ` Christophe Leroy
  (?)
@ 2021-10-18  6:27     ` Nicholas Piggin
  -1 siblings, 0 replies; 99+ messages in thread
From: Nicholas Piggin @ 2021-10-18  6:27 UTC (permalink / raw)
  To: Andrew Morton, Arnd Bergmann, Benjamin Herrenschmidt,
	Christophe Leroy, Helge Deller, Greg Kroah-Hartman,
	James E.J. Bottomley, Kees Cook, Michael Ellerman,
	Paul Mackerras
  Cc: linux-arch, linux-ia64, linux-kernel, linux-mm, linux-parisc,
	linuxppc-dev

Excerpts from Christophe Leroy's message of October 17, 2021 10:38 pm:
> In preparation of making func_desc_t generic, change the ELFv2
> version to a struct containing 'addr' element.
> 
> This allows using single helpers common to ELFv1 and ELFv2.
> 
> Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>

> ---
>  arch/powerpc/kernel/module_64.c | 32 ++++++++++++++------------------
>  1 file changed, 14 insertions(+), 18 deletions(-)
> 
> diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c
> index a89da0ee25e2..b687ef88c4c4 100644
> --- a/arch/powerpc/kernel/module_64.c
> +++ b/arch/powerpc/kernel/module_64.c
> @@ -33,19 +33,13 @@
>  #ifdef PPC64_ELF_ABI_v2
>  
>  /* An address is simply the address of the function. */
> -typedef unsigned long func_desc_t;
> +typedef struct {
> +	unsigned long addr;
> +} func_desc_t;

I'm not quite following why this change is done. I guess it is so you 
can move this func_desc_t type into core code, but why do that? Is it
just to avoid using the preprocessor?

On its own this patch looks okay.

Acked-by: Nicholas Piggin <npiggin@gmail.com>

^ permalink raw reply	[flat|nested] 99+ messages in thread

* Re: [PATCH v3 04/12] powerpc: Prepare func_desc_t for refactorisation
@ 2021-10-18  6:27     ` Nicholas Piggin
  0 siblings, 0 replies; 99+ messages in thread
From: Nicholas Piggin @ 2021-10-18  6:27 UTC (permalink / raw)
  To: Andrew Morton, Arnd Bergmann, Benjamin Herrenschmidt,
	Christophe Leroy, Helge Deller, Greg Kroah-Hartman,
	James E.J. Bottomley, Kees Cook, Michael Ellerman,
	Paul Mackerras
  Cc: linux-arch, linux-ia64, linux-parisc, linux-kernel, linux-mm,
	linuxppc-dev

Excerpts from Christophe Leroy's message of October 17, 2021 10:38 pm:
> In preparation of making func_desc_t generic, change the ELFv2
> version to a struct containing 'addr' element.
> 
> This allows using single helpers common to ELFv1 and ELFv2.
> 
> Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>

> ---
>  arch/powerpc/kernel/module_64.c | 32 ++++++++++++++------------------
>  1 file changed, 14 insertions(+), 18 deletions(-)
> 
> diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c
> index a89da0ee25e2..b687ef88c4c4 100644
> --- a/arch/powerpc/kernel/module_64.c
> +++ b/arch/powerpc/kernel/module_64.c
> @@ -33,19 +33,13 @@
>  #ifdef PPC64_ELF_ABI_v2
>  
>  /* An address is simply the address of the function. */
> -typedef unsigned long func_desc_t;
> +typedef struct {
> +	unsigned long addr;
> +} func_desc_t;

I'm not quite following why this change is done. I guess it is so you 
can move this func_desc_t type into core code, but why do that? Is it
just to avoid using the preprocessor?

On its own this patch looks okay.

Acked-by: Nicholas Piggin <npiggin@gmail.com>

^ permalink raw reply	[flat|nested] 99+ messages in thread

* Re: [PATCH v3 04/12] powerpc: Prepare func_desc_t for refactorisation
@ 2021-10-18  6:27     ` Nicholas Piggin
  0 siblings, 0 replies; 99+ messages in thread
From: Nicholas Piggin @ 2021-10-18  6:27 UTC (permalink / raw)
  To: Andrew Morton, Arnd Bergmann, Benjamin Herrenschmidt,
	Christophe Leroy, Helge Deller, Greg Kroah-Hartman,
	James E.J. Bottomley, Kees Cook, Michael Ellerman,
	Paul Mackerras
  Cc: linux-arch, linux-ia64, linux-kernel, linux-mm, linux-parisc,
	linuxppc-dev

Excerpts from Christophe Leroy's message of October 17, 2021 10:38 pm:
> In preparation of making func_desc_t generic, change the ELFv2
> version to a struct containing 'addr' element.
> 
> This allows using single helpers common to ELFv1 and ELFv2.
> 
> Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>

> ---
>  arch/powerpc/kernel/module_64.c | 32 ++++++++++++++------------------
>  1 file changed, 14 insertions(+), 18 deletions(-)
> 
> diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c
> index a89da0ee25e2..b687ef88c4c4 100644
> --- a/arch/powerpc/kernel/module_64.c
> +++ b/arch/powerpc/kernel/module_64.c
> @@ -33,19 +33,13 @@
>  #ifdef PPC64_ELF_ABI_v2
>  
>  /* An address is simply the address of the function. */
> -typedef unsigned long func_desc_t;
> +typedef struct {
> +	unsigned long addr;
> +} func_desc_t;

I'm not quite following why this change is done. I guess it is so you 
can move this func_desc_t type into core code, but why do that? Is it
just to avoid using the preprocessor?

On its own this patch looks okay.

Acked-by: Nicholas Piggin <npiggin@gmail.com>

^ permalink raw reply	[flat|nested] 99+ messages in thread

* Re: [PATCH v3 07/12] asm-generic: Define 'func_desc_t' to commonly describe function descriptors
  2021-10-17 12:38   ` Christophe Leroy
  (?)
@ 2021-10-18  6:29     ` Nicholas Piggin
  -1 siblings, 0 replies; 99+ messages in thread
From: Nicholas Piggin @ 2021-10-18  6:29 UTC (permalink / raw)
  To: Andrew Morton, Arnd Bergmann, Benjamin Herrenschmidt,
	Christophe Leroy, Helge Deller, Greg Kroah-Hartman,
	James E.J. Bottomley, Kees Cook, Michael Ellerman,
	Paul Mackerras
  Cc: linux-arch, linux-ia64, linux-kernel, linux-mm, linux-parisc,
	linuxppc-dev

Excerpts from Christophe Leroy's message of October 17, 2021 10:38 pm:
> We have three architectures using function descriptors, each with its
> own type and name.
> 
> Add a common typedef that can be used in generic code.
> 
> Also add a stub typedef for architecture without function descriptors,
> to avoid a forest of #ifdefs.
> 
> It replaces the similar 'func_desc_t' previously defined in
> arch/powerpc/kernel/module_64.c
> 
> Reviewed-by: Kees Cook <keescook@chromium.org>
> Acked-by: Arnd Bergmann <arnd@arndb.de>
> Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
> ---

[...]

> diff --git a/include/asm-generic/sections.h b/include/asm-generic/sections.h
> index a918388d9bf6..33b51efe3a24 100644
> --- a/include/asm-generic/sections.h
> +++ b/include/asm-generic/sections.h
> @@ -63,6 +63,9 @@ extern __visible const void __nosave_begin, __nosave_end;
>  #else
>  #define dereference_function_descriptor(p) ((void *)(p))
>  #define dereference_kernel_function_descriptor(p) ((void *)(p))
> +typedef struct {
> +	unsigned long addr;
> +} func_desc_t;
>  #endif
>  

I think that deserves a comment. If it's just to allow ifdef to be 
avoided, I guess that's okay with a comment. Would be nice if you could 
cause it to generate a link time error if it was ever used like
undefined functions, but I guess you can't. It's not a necessity though.

Thanks,
Nick

^ permalink raw reply	[flat|nested] 99+ messages in thread

* Re: [PATCH v3 07/12] asm-generic: Define 'func_desc_t' to commonly describe function descriptors
@ 2021-10-18  6:29     ` Nicholas Piggin
  0 siblings, 0 replies; 99+ messages in thread
From: Nicholas Piggin @ 2021-10-18  6:29 UTC (permalink / raw)
  To: Andrew Morton, Arnd Bergmann, Benjamin Herrenschmidt,
	Christophe Leroy, Helge Deller, Greg Kroah-Hartman,
	James E.J. Bottomley, Kees Cook, Michael Ellerman,
	Paul Mackerras
  Cc: linux-arch, linux-ia64, linux-parisc, linux-kernel, linux-mm,
	linuxppc-dev

Excerpts from Christophe Leroy's message of October 17, 2021 10:38 pm:
> We have three architectures using function descriptors, each with its
> own type and name.
> 
> Add a common typedef that can be used in generic code.
> 
> Also add a stub typedef for architecture without function descriptors,
> to avoid a forest of #ifdefs.
> 
> It replaces the similar 'func_desc_t' previously defined in
> arch/powerpc/kernel/module_64.c
> 
> Reviewed-by: Kees Cook <keescook@chromium.org>
> Acked-by: Arnd Bergmann <arnd@arndb.de>
> Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
> ---

[...]

> diff --git a/include/asm-generic/sections.h b/include/asm-generic/sections.h
> index a918388d9bf6..33b51efe3a24 100644
> --- a/include/asm-generic/sections.h
> +++ b/include/asm-generic/sections.h
> @@ -63,6 +63,9 @@ extern __visible const void __nosave_begin, __nosave_end;
>  #else
>  #define dereference_function_descriptor(p) ((void *)(p))
>  #define dereference_kernel_function_descriptor(p) ((void *)(p))
> +typedef struct {
> +	unsigned long addr;
> +} func_desc_t;
>  #endif
>  

I think that deserves a comment. If it's just to allow ifdef to be 
avoided, I guess that's okay with a comment. Would be nice if you could 
cause it to generate a link time error if it was ever used like
undefined functions, but I guess you can't. It's not a necessity though.

Thanks,
Nick

^ permalink raw reply	[flat|nested] 99+ messages in thread

* Re: [PATCH v3 07/12] asm-generic: Define 'func_desc_t' to commonly describe function descriptors
@ 2021-10-18  6:29     ` Nicholas Piggin
  0 siblings, 0 replies; 99+ messages in thread
From: Nicholas Piggin @ 2021-10-18  6:29 UTC (permalink / raw)
  To: Andrew Morton, Arnd Bergmann, Benjamin Herrenschmidt,
	Christophe Leroy, Helge Deller, Greg Kroah-Hartman,
	James E.J. Bottomley, Kees Cook, Michael Ellerman,
	Paul Mackerras
  Cc: linux-arch, linux-ia64, linux-kernel, linux-mm, linux-parisc,
	linuxppc-dev

Excerpts from Christophe Leroy's message of October 17, 2021 10:38 pm:
> We have three architectures using function descriptors, each with its
> own type and name.
> 
> Add a common typedef that can be used in generic code.
> 
> Also add a stub typedef for architecture without function descriptors,
> to avoid a forest of #ifdefs.
> 
> It replaces the similar 'func_desc_t' previously defined in
> arch/powerpc/kernel/module_64.c
> 
> Reviewed-by: Kees Cook <keescook@chromium.org>
> Acked-by: Arnd Bergmann <arnd@arndb.de>
> Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
> ---

[...]

> diff --git a/include/asm-generic/sections.h b/include/asm-generic/sections.h
> index a918388d9bf6..33b51efe3a24 100644
> --- a/include/asm-generic/sections.h
> +++ b/include/asm-generic/sections.h
> @@ -63,6 +63,9 @@ extern __visible const void __nosave_begin, __nosave_end;
>  #else
>  #define dereference_function_descriptor(p) ((void *)(p))
>  #define dereference_kernel_function_descriptor(p) ((void *)(p))
> +typedef struct {
> +	unsigned long addr;
> +} func_desc_t;
>  #endif
>  

I think that deserves a comment. If it's just to allow ifdef to be 
avoided, I guess that's okay with a comment. Would be nice if you could 
cause it to generate a link time error if it was ever used like
undefined functions, but I guess you can't. It's not a necessity though.

Thanks,
Nick

^ permalink raw reply	[flat|nested] 99+ messages in thread

* Re: [PATCH v3 07/12] asm-generic: Define 'func_desc_t' to commonly describe function descriptors
  2021-10-18  6:29     ` Nicholas Piggin
  (?)
@ 2021-10-18  7:07       ` Christophe Leroy
  -1 siblings, 0 replies; 99+ messages in thread
From: Christophe Leroy @ 2021-10-18  7:07 UTC (permalink / raw)
  To: Nicholas Piggin, Andrew Morton, Arnd Bergmann,
	Benjamin Herrenschmidt, Helge Deller, Greg Kroah-Hartman,
	James E.J. Bottomley, Kees Cook, Michael Ellerman,
	Paul Mackerras
  Cc: linux-arch, linux-ia64, linux-kernel, linux-mm, linux-parisc,
	linuxppc-dev



Le 18/10/2021 à 08:29, Nicholas Piggin a écrit :
> Excerpts from Christophe Leroy's message of October 17, 2021 10:38 pm:
>> We have three architectures using function descriptors, each with its
>> own type and name.
>>
>> Add a common typedef that can be used in generic code.
>>
>> Also add a stub typedef for architecture without function descriptors,
>> to avoid a forest of #ifdefs.
>>
>> It replaces the similar 'func_desc_t' previously defined in
>> arch/powerpc/kernel/module_64.c
>>
>> Reviewed-by: Kees Cook <keescook@chromium.org>
>> Acked-by: Arnd Bergmann <arnd@arndb.de>
>> Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
>> ---
> 
> [...]
> 
>> diff --git a/include/asm-generic/sections.h b/include/asm-generic/sections.h
>> index a918388d9bf6..33b51efe3a24 100644
>> --- a/include/asm-generic/sections.h
>> +++ b/include/asm-generic/sections.h
>> @@ -63,6 +63,9 @@ extern __visible const void __nosave_begin, __nosave_end;
>>   #else
>>   #define dereference_function_descriptor(p) ((void *)(p))
>>   #define dereference_kernel_function_descriptor(p) ((void *)(p))
>> +typedef struct {
>> +	unsigned long addr;
>> +} func_desc_t;
>>   #endif
>>   
> 
> I think that deserves a comment. If it's just to allow ifdef to be
> avoided, I guess that's okay with a comment. Would be nice if you could
> cause it to generate a link time error if it was ever used like
> undefined functions, but I guess you can't. It's not a necessity though.
> 

I tried to explain it in the commit message, but I can add a comment 
here in addition for sure.

By the way, it IS used in powerpc's module_64.c:

static func_desc_t func_desc(unsigned long addr)
{
	return (func_desc_t){addr};
}

static unsigned long func_addr(unsigned long addr)
{
	return func_desc(addr).addr;
}

^ permalink raw reply	[flat|nested] 99+ messages in thread

* Re: [PATCH v3 07/12] asm-generic: Define 'func_desc_t' to commonly describe function descriptors
@ 2021-10-18  7:07       ` Christophe Leroy
  0 siblings, 0 replies; 99+ messages in thread
From: Christophe Leroy @ 2021-10-18  7:07 UTC (permalink / raw)
  To: Nicholas Piggin, Andrew Morton, Arnd Bergmann,
	Benjamin Herrenschmidt, Helge Deller, Greg Kroah-Hartman,
	James E.J. Bottomley, Kees Cook, Michael Ellerman,
	Paul Mackerras
  Cc: linux-arch, linux-ia64, linux-parisc, linux-kernel, linux-mm,
	linuxppc-dev



Le 18/10/2021 à 08:29, Nicholas Piggin a écrit :
> Excerpts from Christophe Leroy's message of October 17, 2021 10:38 pm:
>> We have three architectures using function descriptors, each with its
>> own type and name.
>>
>> Add a common typedef that can be used in generic code.
>>
>> Also add a stub typedef for architecture without function descriptors,
>> to avoid a forest of #ifdefs.
>>
>> It replaces the similar 'func_desc_t' previously defined in
>> arch/powerpc/kernel/module_64.c
>>
>> Reviewed-by: Kees Cook <keescook@chromium.org>
>> Acked-by: Arnd Bergmann <arnd@arndb.de>
>> Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
>> ---
> 
> [...]
> 
>> diff --git a/include/asm-generic/sections.h b/include/asm-generic/sections.h
>> index a918388d9bf6..33b51efe3a24 100644
>> --- a/include/asm-generic/sections.h
>> +++ b/include/asm-generic/sections.h
>> @@ -63,6 +63,9 @@ extern __visible const void __nosave_begin, __nosave_end;
>>   #else
>>   #define dereference_function_descriptor(p) ((void *)(p))
>>   #define dereference_kernel_function_descriptor(p) ((void *)(p))
>> +typedef struct {
>> +	unsigned long addr;
>> +} func_desc_t;
>>   #endif
>>   
> 
> I think that deserves a comment. If it's just to allow ifdef to be
> avoided, I guess that's okay with a comment. Would be nice if you could
> cause it to generate a link time error if it was ever used like
> undefined functions, but I guess you can't. It's not a necessity though.
> 

I tried to explain it in the commit message, but I can add a comment 
here in addition for sure.

By the way, it IS used in powerpc's module_64.c:

static func_desc_t func_desc(unsigned long addr)
{
	return (func_desc_t){addr};
}

static unsigned long func_addr(unsigned long addr)
{
	return func_desc(addr).addr;
}

^ permalink raw reply	[flat|nested] 99+ messages in thread

* Re: [PATCH v3 07/12] asm-generic: Define 'func_desc_t' to commonly describe function descriptors
@ 2021-10-18  7:07       ` Christophe Leroy
  0 siblings, 0 replies; 99+ messages in thread
From: Christophe Leroy @ 2021-10-18  7:07 UTC (permalink / raw)
  To: Nicholas Piggin, Andrew Morton, Arnd Bergmann,
	Benjamin Herrenschmidt, Helge Deller, Greg Kroah-Hartman,
	James E.J. Bottomley, Kees Cook, Michael Ellerman,
	Paul Mackerras
  Cc: linux-arch, linux-ia64, linux-kernel, linux-mm, linux-parisc,
	linuxppc-dev



Le 18/10/2021 à 08:29, Nicholas Piggin a écrit :
> Excerpts from Christophe Leroy's message of October 17, 2021 10:38 pm:
>> We have three architectures using function descriptors, each with its
>> own type and name.
>>
>> Add a common typedef that can be used in generic code.
>>
>> Also add a stub typedef for architecture without function descriptors,
>> to avoid a forest of #ifdefs.
>>
>> It replaces the similar 'func_desc_t' previously defined in
>> arch/powerpc/kernel/module_64.c
>>
>> Reviewed-by: Kees Cook <keescook@chromium.org>
>> Acked-by: Arnd Bergmann <arnd@arndb.de>
>> Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
>> ---
> 
> [...]
> 
>> diff --git a/include/asm-generic/sections.h b/include/asm-generic/sections.h
>> index a918388d9bf6..33b51efe3a24 100644
>> --- a/include/asm-generic/sections.h
>> +++ b/include/asm-generic/sections.h
>> @@ -63,6 +63,9 @@ extern __visible const void __nosave_begin, __nosave_end;
>>   #else
>>   #define dereference_function_descriptor(p) ((void *)(p))
>>   #define dereference_kernel_function_descriptor(p) ((void *)(p))
>> +typedef struct {
>> +	unsigned long addr;
>> +} func_desc_t;
>>   #endif
>>   
> 
> I think that deserves a comment. If it's just to allow ifdef to be
> avoided, I guess that's okay with a comment. Would be nice if you could
> cause it to generate a link time error if it was ever used like
> undefined functions, but I guess you can't. It's not a necessity though.
> 

I tried to explain it in the commit message, but I can add a comment 
here in addition for sure.

By the way, it IS used in powerpc's module_64.c:

static func_desc_t func_desc(unsigned long addr)
{
	return (func_desc_t){addr};
}

static unsigned long func_addr(unsigned long addr)
{
	return func_desc(addr).addr;
}

^ permalink raw reply	[flat|nested] 99+ messages in thread

* Re: [PATCH v3 04/12] powerpc: Prepare func_desc_t for refactorisation
  2021-10-18  6:27     ` Nicholas Piggin
  (?)
@ 2021-10-18  7:08       ` Christophe Leroy
  -1 siblings, 0 replies; 99+ messages in thread
From: Christophe Leroy @ 2021-10-18  7:08 UTC (permalink / raw)
  To: Nicholas Piggin, Andrew Morton, Arnd Bergmann,
	Benjamin Herrenschmidt, Helge Deller, Greg Kroah-Hartman,
	James E.J. Bottomley, Kees Cook, Michael Ellerman,
	Paul Mackerras
  Cc: linux-arch, linux-ia64, linux-kernel, linux-mm, linux-parisc,
	linuxppc-dev



Le 18/10/2021 à 08:27, Nicholas Piggin a écrit :
> Excerpts from Christophe Leroy's message of October 17, 2021 10:38 pm:
>> In preparation of making func_desc_t generic, change the ELFv2
>> version to a struct containing 'addr' element.
>>
>> This allows using single helpers common to ELFv1 and ELFv2.
>>
>> Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
> 
>> ---
>>   arch/powerpc/kernel/module_64.c | 32 ++++++++++++++------------------
>>   1 file changed, 14 insertions(+), 18 deletions(-)
>>
>> diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c
>> index a89da0ee25e2..b687ef88c4c4 100644
>> --- a/arch/powerpc/kernel/module_64.c
>> +++ b/arch/powerpc/kernel/module_64.c
>> @@ -33,19 +33,13 @@
>>   #ifdef PPC64_ELF_ABI_v2
>>   
>>   /* An address is simply the address of the function. */
>> -typedef unsigned long func_desc_t;
>> +typedef struct {
>> +	unsigned long addr;
>> +} func_desc_t;
> 
> I'm not quite following why this change is done. I guess it is so you
> can move this func_desc_t type into core code, but why do that? Is it
> just to avoid using the preprocessor?

I explained it in patch 7 but yes it probably also deserves some more 
explanation here as well.

That's right, it's to avoid having to spread #ifdefs everywhere.

> 
> On its own this patch looks okay.
> 
> Acked-by: Nicholas Piggin <npiggin@gmail.com>
> 

^ permalink raw reply	[flat|nested] 99+ messages in thread

* Re: [PATCH v3 04/12] powerpc: Prepare func_desc_t for refactorisation
@ 2021-10-18  7:08       ` Christophe Leroy
  0 siblings, 0 replies; 99+ messages in thread
From: Christophe Leroy @ 2021-10-18  7:08 UTC (permalink / raw)
  To: Nicholas Piggin, Andrew Morton, Arnd Bergmann,
	Benjamin Herrenschmidt, Helge Deller, Greg Kroah-Hartman,
	James E.J. Bottomley, Kees Cook, Michael Ellerman,
	Paul Mackerras
  Cc: linux-arch, linux-ia64, linux-parisc, linux-kernel, linux-mm,
	linuxppc-dev



Le 18/10/2021 à 08:27, Nicholas Piggin a écrit :
> Excerpts from Christophe Leroy's message of October 17, 2021 10:38 pm:
>> In preparation of making func_desc_t generic, change the ELFv2
>> version to a struct containing 'addr' element.
>>
>> This allows using single helpers common to ELFv1 and ELFv2.
>>
>> Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
> 
>> ---
>>   arch/powerpc/kernel/module_64.c | 32 ++++++++++++++------------------
>>   1 file changed, 14 insertions(+), 18 deletions(-)
>>
>> diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c
>> index a89da0ee25e2..b687ef88c4c4 100644
>> --- a/arch/powerpc/kernel/module_64.c
>> +++ b/arch/powerpc/kernel/module_64.c
>> @@ -33,19 +33,13 @@
>>   #ifdef PPC64_ELF_ABI_v2
>>   
>>   /* An address is simply the address of the function. */
>> -typedef unsigned long func_desc_t;
>> +typedef struct {
>> +	unsigned long addr;
>> +} func_desc_t;
> 
> I'm not quite following why this change is done. I guess it is so you
> can move this func_desc_t type into core code, but why do that? Is it
> just to avoid using the preprocessor?

I explained it in patch 7 but yes it probably also deserves some more 
explanation here as well.

That's right, it's to avoid having to spread #ifdefs everywhere.

> 
> On its own this patch looks okay.
> 
> Acked-by: Nicholas Piggin <npiggin@gmail.com>
> 

^ permalink raw reply	[flat|nested] 99+ messages in thread

* Re: [PATCH v3 04/12] powerpc: Prepare func_desc_t for refactorisation
@ 2021-10-18  7:08       ` Christophe Leroy
  0 siblings, 0 replies; 99+ messages in thread
From: Christophe Leroy @ 2021-10-18  7:08 UTC (permalink / raw)
  To: Nicholas Piggin, Andrew Morton, Arnd Bergmann,
	Benjamin Herrenschmidt, Helge Deller, Greg Kroah-Hartman,
	James E.J. Bottomley, Kees Cook, Michael Ellerman,
	Paul Mackerras
  Cc: linux-arch, linux-ia64, linux-kernel, linux-mm, linux-parisc,
	linuxppc-dev



Le 18/10/2021 à 08:27, Nicholas Piggin a écrit :
> Excerpts from Christophe Leroy's message of October 17, 2021 10:38 pm:
>> In preparation of making func_desc_t generic, change the ELFv2
>> version to a struct containing 'addr' element.
>>
>> This allows using single helpers common to ELFv1 and ELFv2.
>>
>> Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
> 
>> ---
>>   arch/powerpc/kernel/module_64.c | 32 ++++++++++++++------------------
>>   1 file changed, 14 insertions(+), 18 deletions(-)
>>
>> diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c
>> index a89da0ee25e2..b687ef88c4c4 100644
>> --- a/arch/powerpc/kernel/module_64.c
>> +++ b/arch/powerpc/kernel/module_64.c
>> @@ -33,19 +33,13 @@
>>   #ifdef PPC64_ELF_ABI_v2
>>   
>>   /* An address is simply the address of the function. */
>> -typedef unsigned long func_desc_t;
>> +typedef struct {
>> +	unsigned long addr;
>> +} func_desc_t;
> 
> I'm not quite following why this change is done. I guess it is so you
> can move this func_desc_t type into core code, but why do that? Is it
> just to avoid using the preprocessor?

I explained it in patch 7 but yes it probably also deserves some more 
explanation here as well.

That's right, it's to avoid having to spread #ifdefs everywhere.

> 
> On its own this patch looks okay.
> 
> Acked-by: Nicholas Piggin <npiggin@gmail.com>
> 

^ permalink raw reply	[flat|nested] 99+ messages in thread

* Re: [PATCH v3 07/12] asm-generic: Define 'func_desc_t' to commonly describe function descriptors
  2021-10-18  7:07       ` Christophe Leroy
  (?)
@ 2021-10-18  9:16         ` Nicholas Piggin
  -1 siblings, 0 replies; 99+ messages in thread
From: Nicholas Piggin @ 2021-10-18  9:16 UTC (permalink / raw)
  To: Andrew Morton, Arnd Bergmann, Benjamin Herrenschmidt,
	Christophe Leroy, Helge Deller, Greg Kroah-Hartman,
	James E.J. Bottomley, Kees Cook, Michael Ellerman,
	Paul Mackerras
  Cc: linux-arch, linux-ia64, linux-kernel, linux-mm, linux-parisc,
	linuxppc-dev

Excerpts from Christophe Leroy's message of October 18, 2021 5:07 pm:
> 
> 
> Le 18/10/2021 à 08:29, Nicholas Piggin a écrit :
>> Excerpts from Christophe Leroy's message of October 17, 2021 10:38 pm:
>>> We have three architectures using function descriptors, each with its
>>> own type and name.
>>>
>>> Add a common typedef that can be used in generic code.
>>>
>>> Also add a stub typedef for architecture without function descriptors,
>>> to avoid a forest of #ifdefs.
>>>
>>> It replaces the similar 'func_desc_t' previously defined in
>>> arch/powerpc/kernel/module_64.c
>>>
>>> Reviewed-by: Kees Cook <keescook@chromium.org>
>>> Acked-by: Arnd Bergmann <arnd@arndb.de>
>>> Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
>>> ---
>> 
>> [...]
>> 
>>> diff --git a/include/asm-generic/sections.h b/include/asm-generic/sections.h
>>> index a918388d9bf6..33b51efe3a24 100644
>>> --- a/include/asm-generic/sections.h
>>> +++ b/include/asm-generic/sections.h
>>> @@ -63,6 +63,9 @@ extern __visible const void __nosave_begin, __nosave_end;
>>>   #else
>>>   #define dereference_function_descriptor(p) ((void *)(p))
>>>   #define dereference_kernel_function_descriptor(p) ((void *)(p))
>>> +typedef struct {
>>> +	unsigned long addr;
>>> +} func_desc_t;
>>>   #endif
>>>   
>> 
>> I think that deserves a comment. If it's just to allow ifdef to be
>> avoided, I guess that's okay with a comment. Would be nice if you could
>> cause it to generate a link time error if it was ever used like
>> undefined functions, but I guess you can't. It's not a necessity though.
>> 
> 
> I tried to explain it in the commit message, but I can add a comment 
> here in addition for sure.

Thanks.

> 
> By the way, it IS used in powerpc's module_64.c:

Ah yes of course. I guess the point is function descriptors don't exist 
so it should not be used (in general). powerpc module code knows what it
is doing, I guess it's okay for it to use it.

Thanks,
Nick

^ permalink raw reply	[flat|nested] 99+ messages in thread

* Re: [PATCH v3 07/12] asm-generic: Define 'func_desc_t' to commonly describe function descriptors
@ 2021-10-18  9:16         ` Nicholas Piggin
  0 siblings, 0 replies; 99+ messages in thread
From: Nicholas Piggin @ 2021-10-18  9:16 UTC (permalink / raw)
  To: Andrew Morton, Arnd Bergmann, Benjamin Herrenschmidt,
	Christophe Leroy, Helge Deller, Greg Kroah-Hartman,
	James E.J. Bottomley, Kees Cook, Michael Ellerman,
	Paul Mackerras
  Cc: linux-arch, linux-ia64, linux-parisc, linux-kernel, linux-mm,
	linuxppc-dev

Excerpts from Christophe Leroy's message of October 18, 2021 5:07 pm:
> 
> 
> Le 18/10/2021 à 08:29, Nicholas Piggin a écrit :
>> Excerpts from Christophe Leroy's message of October 17, 2021 10:38 pm:
>>> We have three architectures using function descriptors, each with its
>>> own type and name.
>>>
>>> Add a common typedef that can be used in generic code.
>>>
>>> Also add a stub typedef for architecture without function descriptors,
>>> to avoid a forest of #ifdefs.
>>>
>>> It replaces the similar 'func_desc_t' previously defined in
>>> arch/powerpc/kernel/module_64.c
>>>
>>> Reviewed-by: Kees Cook <keescook@chromium.org>
>>> Acked-by: Arnd Bergmann <arnd@arndb.de>
>>> Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
>>> ---
>> 
>> [...]
>> 
>>> diff --git a/include/asm-generic/sections.h b/include/asm-generic/sections.h
>>> index a918388d9bf6..33b51efe3a24 100644
>>> --- a/include/asm-generic/sections.h
>>> +++ b/include/asm-generic/sections.h
>>> @@ -63,6 +63,9 @@ extern __visible const void __nosave_begin, __nosave_end;
>>>   #else
>>>   #define dereference_function_descriptor(p) ((void *)(p))
>>>   #define dereference_kernel_function_descriptor(p) ((void *)(p))
>>> +typedef struct {
>>> +	unsigned long addr;
>>> +} func_desc_t;
>>>   #endif
>>>   
>> 
>> I think that deserves a comment. If it's just to allow ifdef to be
>> avoided, I guess that's okay with a comment. Would be nice if you could
>> cause it to generate a link time error if it was ever used like
>> undefined functions, but I guess you can't. It's not a necessity though.
>> 
> 
> I tried to explain it in the commit message, but I can add a comment 
> here in addition for sure.

Thanks.

> 
> By the way, it IS used in powerpc's module_64.c:

Ah yes of course. I guess the point is function descriptors don't exist 
so it should not be used (in general). powerpc module code knows what it
is doing, I guess it's okay for it to use it.

Thanks,
Nick

^ permalink raw reply	[flat|nested] 99+ messages in thread

* Re: [PATCH v3 07/12] asm-generic: Define 'func_desc_t' to commonly describe function descriptors
@ 2021-10-18  9:16         ` Nicholas Piggin
  0 siblings, 0 replies; 99+ messages in thread
From: Nicholas Piggin @ 2021-10-18  9:16 UTC (permalink / raw)
  To: Andrew Morton, Arnd Bergmann, Benjamin Herrenschmidt,
	Christophe Leroy, Helge Deller, Greg Kroah-Hartman,
	James E.J. Bottomley, Kees Cook, Michael Ellerman,
	Paul Mackerras
  Cc: linux-arch, linux-ia64, linux-kernel, linux-mm, linux-parisc,
	linuxppc-dev

Excerpts from Christophe Leroy's message of October 18, 2021 5:07 pm:
> 
> 
> Le 18/10/2021 à 08:29, Nicholas Piggin a écrit :
>> Excerpts from Christophe Leroy's message of October 17, 2021 10:38 pm:
>>> We have three architectures using function descriptors, each with its
>>> own type and name.
>>>
>>> Add a common typedef that can be used in generic code.
>>>
>>> Also add a stub typedef for architecture without function descriptors,
>>> to avoid a forest of #ifdefs.
>>>
>>> It replaces the similar 'func_desc_t' previously defined in
>>> arch/powerpc/kernel/module_64.c
>>>
>>> Reviewed-by: Kees Cook <keescook@chromium.org>
>>> Acked-by: Arnd Bergmann <arnd@arndb.de>
>>> Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
>>> ---
>> 
>> [...]
>> 
>>> diff --git a/include/asm-generic/sections.h b/include/asm-generic/sections.h
>>> index a918388d9bf6..33b51efe3a24 100644
>>> --- a/include/asm-generic/sections.h
>>> +++ b/include/asm-generic/sections.h
>>> @@ -63,6 +63,9 @@ extern __visible const void __nosave_begin, __nosave_end;
>>>   #else
>>>   #define dereference_function_descriptor(p) ((void *)(p))
>>>   #define dereference_kernel_function_descriptor(p) ((void *)(p))
>>> +typedef struct {
>>> +	unsigned long addr;
>>> +} func_desc_t;
>>>   #endif
>>>   
>> 
>> I think that deserves a comment. If it's just to allow ifdef to be
>> avoided, I guess that's okay with a comment. Would be nice if you could
>> cause it to generate a link time error if it was ever used like
>> undefined functions, but I guess you can't. It's not a necessity though.
>> 
> 
> I tried to explain it in the commit message, but I can add a comment 
> here in addition for sure.

Thanks.

> 
> By the way, it IS used in powerpc's module_64.c:

Ah yes of course. I guess the point is function descriptors don't exist 
so it should not be used (in general). powerpc module code knows what it
is doing, I guess it's okay for it to use it.

Thanks,
Nick

^ permalink raw reply	[flat|nested] 99+ messages in thread

* Re: [PATCH v3 11/12] lkdtm: Fix execute_[user]_location()
  2021-10-17 12:38   ` Christophe Leroy
  (?)
@ 2021-12-17 11:49     ` Christophe Leroy
  -1 siblings, 0 replies; 99+ messages in thread
From: Christophe Leroy @ 2021-12-17 11:49 UTC (permalink / raw)
  To: Kees Cook, Michael Ellerman
  Cc: Helge Deller, Benjamin Herrenschmidt, Greg Kroah-Hartman,
	linux-kernel, Andrew Morton, linuxppc-dev, linux-ia64,
	linux-parisc, linux-arch, linux-mm, James E.J. Bottomley,
	Paul Mackerras, Arnd Bergmann

Hi Kees,

Le 17/10/2021 à 14:38, Christophe Leroy a écrit :
> execute_location() and execute_user_location() intent
> to copy do_nothing() text and execute it at a new location.
> However, at the time being it doesn't copy do_nothing() function
> but do_nothing() function descriptor which still points to the
> original text. So at the end it still executes do_nothing() at
> its original location allthough using a copied function descriptor.
> 
> So, fix that by really copying do_nothing() text and build a new
> function descriptor by copying do_nothing() function descriptor and
> updating the target address with the new location.
> 
> Also fix the displayed addresses by dereferencing do_nothing()
> function descriptor.
> 
> Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>

Do you have any comment to this patch and to patch 12 ?

If not, is it ok to get your acked-by ?

Thanks
Christophe

> ---
>   drivers/misc/lkdtm/perms.c | 37 ++++++++++++++++++++++++++++---------
>   1 file changed, 28 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/misc/lkdtm/perms.c b/drivers/misc/lkdtm/perms.c
> index 035fcca441f0..1cf24c4a79e9 100644
> --- a/drivers/misc/lkdtm/perms.c
> +++ b/drivers/misc/lkdtm/perms.c
> @@ -44,19 +44,34 @@ static noinline void do_overwritten(void)
>   	return;
>   }
>   
> +static void *setup_function_descriptor(func_desc_t *fdesc, void *dst)
> +{
> +	if (!have_function_descriptors())
> +		return dst;
> +
> +	memcpy(fdesc, do_nothing, sizeof(*fdesc));
> +	fdesc->addr = (unsigned long)dst;
> +	barrier();
> +
> +	return fdesc;
> +}
> +
>   static noinline void execute_location(void *dst, bool write)
>   {
> -	void (*func)(void) = dst;
> +	void (*func)(void);
> +	func_desc_t fdesc;
> +	void *do_nothing_text = dereference_function_descriptor(do_nothing);
>   
> -	pr_info("attempting ok execution at %px\n", do_nothing);
> +	pr_info("attempting ok execution at %px\n", do_nothing_text);
>   	do_nothing();
>   
>   	if (write == CODE_WRITE) {
> -		memcpy(dst, do_nothing, EXEC_SIZE);
> +		memcpy(dst, do_nothing_text, EXEC_SIZE);
>   		flush_icache_range((unsigned long)dst,
>   				   (unsigned long)dst + EXEC_SIZE);
>   	}
> -	pr_info("attempting bad execution at %px\n", func);
> +	pr_info("attempting bad execution at %px\n", dst);
> +	func = setup_function_descriptor(&fdesc, dst);
>   	func();
>   	pr_err("FAIL: func returned\n");
>   }
> @@ -66,16 +81,19 @@ static void execute_user_location(void *dst)
>   	int copied;
>   
>   	/* Intentionally crossing kernel/user memory boundary. */
> -	void (*func)(void) = dst;
> +	void (*func)(void);
> +	func_desc_t fdesc;
> +	void *do_nothing_text = dereference_function_descriptor(do_nothing);
>   
> -	pr_info("attempting ok execution at %px\n", do_nothing);
> +	pr_info("attempting ok execution at %px\n", do_nothing_text);
>   	do_nothing();
>   
> -	copied = access_process_vm(current, (unsigned long)dst, do_nothing,
> +	copied = access_process_vm(current, (unsigned long)dst, do_nothing_text,
>   				   EXEC_SIZE, FOLL_WRITE);
>   	if (copied < EXEC_SIZE)
>   		return;
> -	pr_info("attempting bad execution at %px\n", func);
> +	pr_info("attempting bad execution at %px\n", dst);
> +	func = setup_function_descriptor(&fdesc, dst);
>   	func();
>   	pr_err("FAIL: func returned\n");
>   }
> @@ -153,7 +171,8 @@ void lkdtm_EXEC_VMALLOC(void)
>   
>   void lkdtm_EXEC_RODATA(void)
>   {
> -	execute_location(lkdtm_rodata_do_nothing, CODE_AS_IS);
> +	execute_location(dereference_function_descriptor(lkdtm_rodata_do_nothing),
> +			 CODE_AS_IS);
>   }
>   
>   void lkdtm_EXEC_USERSPACE(void)
> 

^ permalink raw reply	[flat|nested] 99+ messages in thread

* Re: [PATCH v3 11/12] lkdtm: Fix execute_[user]_location()
@ 2021-12-17 11:49     ` Christophe Leroy
  0 siblings, 0 replies; 99+ messages in thread
From: Christophe Leroy @ 2021-12-17 11:49 UTC (permalink / raw)
  To: Kees Cook, Michael Ellerman
  Cc: linux-arch, linux-ia64, Arnd Bergmann, linux-parisc,
	Helge Deller, linux-kernel, James E.J. Bottomley, linux-mm,
	Paul Mackerras, Greg Kroah-Hartman, Andrew Morton, linuxppc-dev

Hi Kees,

Le 17/10/2021 à 14:38, Christophe Leroy a écrit :
> execute_location() and execute_user_location() intent
> to copy do_nothing() text and execute it at a new location.
> However, at the time being it doesn't copy do_nothing() function
> but do_nothing() function descriptor which still points to the
> original text. So at the end it still executes do_nothing() at
> its original location allthough using a copied function descriptor.
> 
> So, fix that by really copying do_nothing() text and build a new
> function descriptor by copying do_nothing() function descriptor and
> updating the target address with the new location.
> 
> Also fix the displayed addresses by dereferencing do_nothing()
> function descriptor.
> 
> Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>

Do you have any comment to this patch and to patch 12 ?

If not, is it ok to get your acked-by ?

Thanks
Christophe

> ---
>   drivers/misc/lkdtm/perms.c | 37 ++++++++++++++++++++++++++++---------
>   1 file changed, 28 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/misc/lkdtm/perms.c b/drivers/misc/lkdtm/perms.c
> index 035fcca441f0..1cf24c4a79e9 100644
> --- a/drivers/misc/lkdtm/perms.c
> +++ b/drivers/misc/lkdtm/perms.c
> @@ -44,19 +44,34 @@ static noinline void do_overwritten(void)
>   	return;
>   }
>   
> +static void *setup_function_descriptor(func_desc_t *fdesc, void *dst)
> +{
> +	if (!have_function_descriptors())
> +		return dst;
> +
> +	memcpy(fdesc, do_nothing, sizeof(*fdesc));
> +	fdesc->addr = (unsigned long)dst;
> +	barrier();
> +
> +	return fdesc;
> +}
> +
>   static noinline void execute_location(void *dst, bool write)
>   {
> -	void (*func)(void) = dst;
> +	void (*func)(void);
> +	func_desc_t fdesc;
> +	void *do_nothing_text = dereference_function_descriptor(do_nothing);
>   
> -	pr_info("attempting ok execution at %px\n", do_nothing);
> +	pr_info("attempting ok execution at %px\n", do_nothing_text);
>   	do_nothing();
>   
>   	if (write == CODE_WRITE) {
> -		memcpy(dst, do_nothing, EXEC_SIZE);
> +		memcpy(dst, do_nothing_text, EXEC_SIZE);
>   		flush_icache_range((unsigned long)dst,
>   				   (unsigned long)dst + EXEC_SIZE);
>   	}
> -	pr_info("attempting bad execution at %px\n", func);
> +	pr_info("attempting bad execution at %px\n", dst);
> +	func = setup_function_descriptor(&fdesc, dst);
>   	func();
>   	pr_err("FAIL: func returned\n");
>   }
> @@ -66,16 +81,19 @@ static void execute_user_location(void *dst)
>   	int copied;
>   
>   	/* Intentionally crossing kernel/user memory boundary. */
> -	void (*func)(void) = dst;
> +	void (*func)(void);
> +	func_desc_t fdesc;
> +	void *do_nothing_text = dereference_function_descriptor(do_nothing);
>   
> -	pr_info("attempting ok execution at %px\n", do_nothing);
> +	pr_info("attempting ok execution at %px\n", do_nothing_text);
>   	do_nothing();
>   
> -	copied = access_process_vm(current, (unsigned long)dst, do_nothing,
> +	copied = access_process_vm(current, (unsigned long)dst, do_nothing_text,
>   				   EXEC_SIZE, FOLL_WRITE);
>   	if (copied < EXEC_SIZE)
>   		return;
> -	pr_info("attempting bad execution at %px\n", func);
> +	pr_info("attempting bad execution at %px\n", dst);
> +	func = setup_function_descriptor(&fdesc, dst);
>   	func();
>   	pr_err("FAIL: func returned\n");
>   }
> @@ -153,7 +171,8 @@ void lkdtm_EXEC_VMALLOC(void)
>   
>   void lkdtm_EXEC_RODATA(void)
>   {
> -	execute_location(lkdtm_rodata_do_nothing, CODE_AS_IS);
> +	execute_location(dereference_function_descriptor(lkdtm_rodata_do_nothing),
> +			 CODE_AS_IS);
>   }
>   
>   void lkdtm_EXEC_USERSPACE(void)
> 

^ permalink raw reply	[flat|nested] 99+ messages in thread

* Re: [PATCH v3 11/12] lkdtm: Fix execute_[user]_location()
@ 2021-12-17 11:49     ` Christophe Leroy
  0 siblings, 0 replies; 99+ messages in thread
From: Christophe Leroy @ 2021-12-17 11:49 UTC (permalink / raw)
  To: Kees Cook, Michael Ellerman
  Cc: Helge Deller, Benjamin Herrenschmidt, Greg Kroah-Hartman,
	linux-kernel, Andrew Morton, linuxppc-dev, linux-ia64,
	linux-parisc, linux-arch, linux-mm, James E.J. Bottomley,
	Paul Mackerras, Arnd Bergmann

SGkgS2VlcywNCg0KTGUgMTcvMTAvMjAyMSDDoCAxNDozOCwgQ2hyaXN0b3BoZSBMZXJveSBhIMOp
Y3JpdMKgOg0KPiBleGVjdXRlX2xvY2F0aW9uKCkgYW5kIGV4ZWN1dGVfdXNlcl9sb2NhdGlvbigp
IGludGVudA0KPiB0byBjb3B5IGRvX25vdGhpbmcoKSB0ZXh0IGFuZCBleGVjdXRlIGl0IGF0IGEg
bmV3IGxvY2F0aW9uLg0KPiBIb3dldmVyLCBhdCB0aGUgdGltZSBiZWluZyBpdCBkb2Vzbid0IGNv
cHkgZG9fbm90aGluZygpIGZ1bmN0aW9uDQo+IGJ1dCBkb19ub3RoaW5nKCkgZnVuY3Rpb24gZGVz
Y3JpcHRvciB3aGljaCBzdGlsbCBwb2ludHMgdG8gdGhlDQo+IG9yaWdpbmFsIHRleHQuIFNvIGF0
IHRoZSBlbmQgaXQgc3RpbGwgZXhlY3V0ZXMgZG9fbm90aGluZygpIGF0DQo+IGl0cyBvcmlnaW5h
bCBsb2NhdGlvbiBhbGx0aG91Z2ggdXNpbmcgYSBjb3BpZWQgZnVuY3Rpb24gZGVzY3JpcHRvci4N
Cj4gDQo+IFNvLCBmaXggdGhhdCBieSByZWFsbHkgY29weWluZyBkb19ub3RoaW5nKCkgdGV4dCBh
bmQgYnVpbGQgYSBuZXcNCj4gZnVuY3Rpb24gZGVzY3JpcHRvciBieSBjb3B5aW5nIGRvX25vdGhp
bmcoKSBmdW5jdGlvbiBkZXNjcmlwdG9yIGFuZA0KPiB1cGRhdGluZyB0aGUgdGFyZ2V0IGFkZHJl
c3Mgd2l0aCB0aGUgbmV3IGxvY2F0aW9uLg0KPiANCj4gQWxzbyBmaXggdGhlIGRpc3BsYXllZCBh
ZGRyZXNzZXMgYnkgZGVyZWZlcmVuY2luZyBkb19ub3RoaW5nKCkNCj4gZnVuY3Rpb24gZGVzY3Jp
cHRvci4NCj4gDQo+IFNpZ25lZC1vZmYtYnk6IENocmlzdG9waGUgTGVyb3kgPGNocmlzdG9waGUu
bGVyb3lAY3Nncm91cC5ldT4NCg0KRG8geW91IGhhdmUgYW55IGNvbW1lbnQgdG8gdGhpcyBwYXRj
aCBhbmQgdG8gcGF0Y2ggMTIgPw0KDQpJZiBub3QsIGlzIGl0IG9rIHRvIGdldCB5b3VyIGFja2Vk
LWJ5ID8NCg0KVGhhbmtzDQpDaHJpc3RvcGhlDQoNCj4gLS0tDQo+ICAgZHJpdmVycy9taXNjL2xr
ZHRtL3Blcm1zLmMgfCAzNyArKysrKysrKysrKysrKysrKysrKysrKysrKysrLS0tLS0tLS0tDQo+
ICAgMSBmaWxlIGNoYW5nZWQsIDI4IGluc2VydGlvbnMoKyksIDkgZGVsZXRpb25zKC0pDQo+IA0K
PiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9taXNjL2xrZHRtL3Blcm1zLmMgYi9kcml2ZXJzL21pc2Mv
bGtkdG0vcGVybXMuYw0KPiBpbmRleCAwMzVmY2NhNDQxZjAuLjFjZjI0YzRhNzllOSAxMDA2NDQN
Cj4gLS0tIGEvZHJpdmVycy9taXNjL2xrZHRtL3Blcm1zLmMNCj4gKysrIGIvZHJpdmVycy9taXNj
L2xrZHRtL3Blcm1zLmMNCj4gQEAgLTQ0LDE5ICs0NCwzNCBAQCBzdGF0aWMgbm9pbmxpbmUgdm9p
ZCBkb19vdmVyd3JpdHRlbih2b2lkKQ0KPiAgIAlyZXR1cm47DQo+ICAgfQ0KPiAgIA0KPiArc3Rh
dGljIHZvaWQgKnNldHVwX2Z1bmN0aW9uX2Rlc2NyaXB0b3IoZnVuY19kZXNjX3QgKmZkZXNjLCB2
b2lkICpkc3QpDQo+ICt7DQo+ICsJaWYgKCFoYXZlX2Z1bmN0aW9uX2Rlc2NyaXB0b3JzKCkpDQo+
ICsJCXJldHVybiBkc3Q7DQo+ICsNCj4gKwltZW1jcHkoZmRlc2MsIGRvX25vdGhpbmcsIHNpemVv
ZigqZmRlc2MpKTsNCj4gKwlmZGVzYy0+YWRkciA9ICh1bnNpZ25lZCBsb25nKWRzdDsNCj4gKwli
YXJyaWVyKCk7DQo+ICsNCj4gKwlyZXR1cm4gZmRlc2M7DQo+ICt9DQo+ICsNCj4gICBzdGF0aWMg
bm9pbmxpbmUgdm9pZCBleGVjdXRlX2xvY2F0aW9uKHZvaWQgKmRzdCwgYm9vbCB3cml0ZSkNCj4g
ICB7DQo+IC0Jdm9pZCAoKmZ1bmMpKHZvaWQpID0gZHN0Ow0KPiArCXZvaWQgKCpmdW5jKSh2b2lk
KTsNCj4gKwlmdW5jX2Rlc2NfdCBmZGVzYzsNCj4gKwl2b2lkICpkb19ub3RoaW5nX3RleHQgPSBk
ZXJlZmVyZW5jZV9mdW5jdGlvbl9kZXNjcmlwdG9yKGRvX25vdGhpbmcpOw0KPiAgIA0KPiAtCXBy
X2luZm8oImF0dGVtcHRpbmcgb2sgZXhlY3V0aW9uIGF0ICVweFxuIiwgZG9fbm90aGluZyk7DQo+
ICsJcHJfaW5mbygiYXR0ZW1wdGluZyBvayBleGVjdXRpb24gYXQgJXB4XG4iLCBkb19ub3RoaW5n
X3RleHQpOw0KPiAgIAlkb19ub3RoaW5nKCk7DQo+ICAgDQo+ICAgCWlmICh3cml0ZSA9PSBDT0RF
X1dSSVRFKSB7DQo+IC0JCW1lbWNweShkc3QsIGRvX25vdGhpbmcsIEVYRUNfU0laRSk7DQo+ICsJ
CW1lbWNweShkc3QsIGRvX25vdGhpbmdfdGV4dCwgRVhFQ19TSVpFKTsNCj4gICAJCWZsdXNoX2lj
YWNoZV9yYW5nZSgodW5zaWduZWQgbG9uZylkc3QsDQo+ICAgCQkJCSAgICh1bnNpZ25lZCBsb25n
KWRzdCArIEVYRUNfU0laRSk7DQo+ICAgCX0NCj4gLQlwcl9pbmZvKCJhdHRlbXB0aW5nIGJhZCBl
eGVjdXRpb24gYXQgJXB4XG4iLCBmdW5jKTsNCj4gKwlwcl9pbmZvKCJhdHRlbXB0aW5nIGJhZCBl
eGVjdXRpb24gYXQgJXB4XG4iLCBkc3QpOw0KPiArCWZ1bmMgPSBzZXR1cF9mdW5jdGlvbl9kZXNj
cmlwdG9yKCZmZGVzYywgZHN0KTsNCj4gICAJZnVuYygpOw0KPiAgIAlwcl9lcnIoIkZBSUw6IGZ1
bmMgcmV0dXJuZWRcbiIpOw0KPiAgIH0NCj4gQEAgLTY2LDE2ICs4MSwxOSBAQCBzdGF0aWMgdm9p
ZCBleGVjdXRlX3VzZXJfbG9jYXRpb24odm9pZCAqZHN0KQ0KPiAgIAlpbnQgY29waWVkOw0KPiAg
IA0KPiAgIAkvKiBJbnRlbnRpb25hbGx5IGNyb3NzaW5nIGtlcm5lbC91c2VyIG1lbW9yeSBib3Vu
ZGFyeS4gKi8NCj4gLQl2b2lkICgqZnVuYykodm9pZCkgPSBkc3Q7DQo+ICsJdm9pZCAoKmZ1bmMp
KHZvaWQpOw0KPiArCWZ1bmNfZGVzY190IGZkZXNjOw0KPiArCXZvaWQgKmRvX25vdGhpbmdfdGV4
dCA9IGRlcmVmZXJlbmNlX2Z1bmN0aW9uX2Rlc2NyaXB0b3IoZG9fbm90aGluZyk7DQo+ICAgDQo+
IC0JcHJfaW5mbygiYXR0ZW1wdGluZyBvayBleGVjdXRpb24gYXQgJXB4XG4iLCBkb19ub3RoaW5n
KTsNCj4gKwlwcl9pbmZvKCJhdHRlbXB0aW5nIG9rIGV4ZWN1dGlvbiBhdCAlcHhcbiIsIGRvX25v
dGhpbmdfdGV4dCk7DQo+ICAgCWRvX25vdGhpbmcoKTsNCj4gICANCj4gLQljb3BpZWQgPSBhY2Nl
c3NfcHJvY2Vzc192bShjdXJyZW50LCAodW5zaWduZWQgbG9uZylkc3QsIGRvX25vdGhpbmcsDQo+
ICsJY29waWVkID0gYWNjZXNzX3Byb2Nlc3Nfdm0oY3VycmVudCwgKHVuc2lnbmVkIGxvbmcpZHN0
LCBkb19ub3RoaW5nX3RleHQsDQo+ICAgCQkJCSAgIEVYRUNfU0laRSwgRk9MTF9XUklURSk7DQo+
ICAgCWlmIChjb3BpZWQgPCBFWEVDX1NJWkUpDQo+ICAgCQlyZXR1cm47DQo+IC0JcHJfaW5mbygi
YXR0ZW1wdGluZyBiYWQgZXhlY3V0aW9uIGF0ICVweFxuIiwgZnVuYyk7DQo+ICsJcHJfaW5mbygi
YXR0ZW1wdGluZyBiYWQgZXhlY3V0aW9uIGF0ICVweFxuIiwgZHN0KTsNCj4gKwlmdW5jID0gc2V0
dXBfZnVuY3Rpb25fZGVzY3JpcHRvcigmZmRlc2MsIGRzdCk7DQo+ICAgCWZ1bmMoKTsNCj4gICAJ
cHJfZXJyKCJGQUlMOiBmdW5jIHJldHVybmVkXG4iKTsNCj4gICB9DQo+IEBAIC0xNTMsNyArMTcx
LDggQEAgdm9pZCBsa2R0bV9FWEVDX1ZNQUxMT0Modm9pZCkNCj4gICANCj4gICB2b2lkIGxrZHRt
X0VYRUNfUk9EQVRBKHZvaWQpDQo+ICAgew0KPiAtCWV4ZWN1dGVfbG9jYXRpb24obGtkdG1fcm9k
YXRhX2RvX25vdGhpbmcsIENPREVfQVNfSVMpOw0KPiArCWV4ZWN1dGVfbG9jYXRpb24oZGVyZWZl
cmVuY2VfZnVuY3Rpb25fZGVzY3JpcHRvcihsa2R0bV9yb2RhdGFfZG9fbm90aGluZyksDQo+ICsJ
CQkgQ09ERV9BU19JUyk7DQo+ICAgfQ0KPiAgIA0KPiAgIHZvaWQgbGtkdG1fRVhFQ19VU0VSU1BB
Q0Uodm9pZCkNCj4g

^ permalink raw reply	[flat|nested] 99+ messages in thread

* Re: [PATCH v3 11/12] lkdtm: Fix execute_[user]_location()
  2021-12-17 11:49     ` Christophe Leroy
  (?)
@ 2021-12-17 17:12       ` Helge Deller
  -1 siblings, 0 replies; 99+ messages in thread
From: Helge Deller @ 2021-12-17 17:12 UTC (permalink / raw)
  To: Christophe Leroy, Kees Cook, Michael Ellerman
  Cc: Benjamin Herrenschmidt, Greg Kroah-Hartman, linux-kernel,
	Andrew Morton, linuxppc-dev, linux-ia64, linux-parisc,
	linux-arch, linux-mm, James E.J. Bottomley, Paul Mackerras,
	Arnd Bergmann

On 12/17/21 12:49, Christophe Leroy wrote:
> Hi Kees,
>
> Le 17/10/2021 à 14:38, Christophe Leroy a écrit :
>> execute_location() and execute_user_location() intent
>> to copy do_nothing() text and execute it at a new location.
>> However, at the time being it doesn't copy do_nothing() function
>> but do_nothing() function descriptor which still points to the
>> original text. So at the end it still executes do_nothing() at
>> its original location allthough using a copied function descriptor.
>>
>> So, fix that by really copying do_nothing() text and build a new
>> function descriptor by copying do_nothing() function descriptor and
>> updating the target address with the new location.
>>
>> Also fix the displayed addresses by dereferencing do_nothing()
>> function descriptor.
>>
>> Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
>
> Do you have any comment to this patch and to patch 12 ?
>
> If not, is it ok to get your acked-by ?


Hi Christophe,

I think this whole series is a nice cleanup and harmonization
of how function descriptors are used.

At least for the PA-RISC parts you may add:
Acked-by: Helge Deller <deller@gmx.de>

Thanks!
Helge

>
>> ---
>>   drivers/misc/lkdtm/perms.c | 37 ++++++++++++++++++++++++++++---------
>>   1 file changed, 28 insertions(+), 9 deletions(-)
>>
>> diff --git a/drivers/misc/lkdtm/perms.c b/drivers/misc/lkdtm/perms.c
>> index 035fcca441f0..1cf24c4a79e9 100644
>> --- a/drivers/misc/lkdtm/perms.c
>> +++ b/drivers/misc/lkdtm/perms.c
>> @@ -44,19 +44,34 @@ static noinline void do_overwritten(void)
>>   	return;
>>   }
>>
>> +static void *setup_function_descriptor(func_desc_t *fdesc, void *dst)
>> +{
>> +	if (!have_function_descriptors())
>> +		return dst;
>> +
>> +	memcpy(fdesc, do_nothing, sizeof(*fdesc));
>> +	fdesc->addr = (unsigned long)dst;
>> +	barrier();
>> +
>> +	return fdesc;
>> +}
>> +
>>   static noinline void execute_location(void *dst, bool write)
>>   {
>> -	void (*func)(void) = dst;
>> +	void (*func)(void);
>> +	func_desc_t fdesc;
>> +	void *do_nothing_text = dereference_function_descriptor(do_nothing);
>>
>> -	pr_info("attempting ok execution at %px\n", do_nothing);
>> +	pr_info("attempting ok execution at %px\n", do_nothing_text);
>>   	do_nothing();
>>
>>   	if (write == CODE_WRITE) {
>> -		memcpy(dst, do_nothing, EXEC_SIZE);
>> +		memcpy(dst, do_nothing_text, EXEC_SIZE);
>>   		flush_icache_range((unsigned long)dst,
>>   				   (unsigned long)dst + EXEC_SIZE);
>>   	}
>> -	pr_info("attempting bad execution at %px\n", func);
>> +	pr_info("attempting bad execution at %px\n", dst);
>> +	func = setup_function_descriptor(&fdesc, dst);
>>   	func();
>>   	pr_err("FAIL: func returned\n");
>>   }
>> @@ -66,16 +81,19 @@ static void execute_user_location(void *dst)
>>   	int copied;
>>
>>   	/* Intentionally crossing kernel/user memory boundary. */
>> -	void (*func)(void) = dst;
>> +	void (*func)(void);
>> +	func_desc_t fdesc;
>> +	void *do_nothing_text = dereference_function_descriptor(do_nothing);
>>
>> -	pr_info("attempting ok execution at %px\n", do_nothing);
>> +	pr_info("attempting ok execution at %px\n", do_nothing_text);
>>   	do_nothing();
>>
>> -	copied = access_process_vm(current, (unsigned long)dst, do_nothing,
>> +	copied = access_process_vm(current, (unsigned long)dst, do_nothing_text,
>>   				   EXEC_SIZE, FOLL_WRITE);
>>   	if (copied < EXEC_SIZE)
>>   		return;
>> -	pr_info("attempting bad execution at %px\n", func);
>> +	pr_info("attempting bad execution at %px\n", dst);
>> +	func = setup_function_descriptor(&fdesc, dst);
>>   	func();
>>   	pr_err("FAIL: func returned\n");
>>   }
>> @@ -153,7 +171,8 @@ void lkdtm_EXEC_VMALLOC(void)
>>
>>   void lkdtm_EXEC_RODATA(void)
>>   {
>> -	execute_location(lkdtm_rodata_do_nothing, CODE_AS_IS);
>> +	execute_location(dereference_function_descriptor(lkdtm_rodata_do_nothing),
>> +			 CODE_AS_IS);
>>   }
>>
>>   void lkdtm_EXEC_USERSPACE(void)


^ permalink raw reply	[flat|nested] 99+ messages in thread

* Re: [PATCH v3 11/12] lkdtm: Fix execute_[user]_location()
@ 2021-12-17 17:12       ` Helge Deller
  0 siblings, 0 replies; 99+ messages in thread
From: Helge Deller @ 2021-12-17 17:12 UTC (permalink / raw)
  To: Christophe Leroy, Kees Cook, Michael Ellerman
  Cc: linux-arch, linux-ia64, Arnd Bergmann, linux-parisc,
	linux-kernel, James E.J. Bottomley, linux-mm, Paul Mackerras,
	Greg Kroah-Hartman, Andrew Morton, linuxppc-dev

On 12/17/21 12:49, Christophe Leroy wrote:
> Hi Kees,
>
> Le 17/10/2021 à 14:38, Christophe Leroy a écrit :
>> execute_location() and execute_user_location() intent
>> to copy do_nothing() text and execute it at a new location.
>> However, at the time being it doesn't copy do_nothing() function
>> but do_nothing() function descriptor which still points to the
>> original text. So at the end it still executes do_nothing() at
>> its original location allthough using a copied function descriptor.
>>
>> So, fix that by really copying do_nothing() text and build a new
>> function descriptor by copying do_nothing() function descriptor and
>> updating the target address with the new location.
>>
>> Also fix the displayed addresses by dereferencing do_nothing()
>> function descriptor.
>>
>> Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
>
> Do you have any comment to this patch and to patch 12 ?
>
> If not, is it ok to get your acked-by ?


Hi Christophe,

I think this whole series is a nice cleanup and harmonization
of how function descriptors are used.

At least for the PA-RISC parts you may add:
Acked-by: Helge Deller <deller@gmx.de>

Thanks!
Helge

>
>> ---
>>   drivers/misc/lkdtm/perms.c | 37 ++++++++++++++++++++++++++++---------
>>   1 file changed, 28 insertions(+), 9 deletions(-)
>>
>> diff --git a/drivers/misc/lkdtm/perms.c b/drivers/misc/lkdtm/perms.c
>> index 035fcca441f0..1cf24c4a79e9 100644
>> --- a/drivers/misc/lkdtm/perms.c
>> +++ b/drivers/misc/lkdtm/perms.c
>> @@ -44,19 +44,34 @@ static noinline void do_overwritten(void)
>>   	return;
>>   }
>>
>> +static void *setup_function_descriptor(func_desc_t *fdesc, void *dst)
>> +{
>> +	if (!have_function_descriptors())
>> +		return dst;
>> +
>> +	memcpy(fdesc, do_nothing, sizeof(*fdesc));
>> +	fdesc->addr = (unsigned long)dst;
>> +	barrier();
>> +
>> +	return fdesc;
>> +}
>> +
>>   static noinline void execute_location(void *dst, bool write)
>>   {
>> -	void (*func)(void) = dst;
>> +	void (*func)(void);
>> +	func_desc_t fdesc;
>> +	void *do_nothing_text = dereference_function_descriptor(do_nothing);
>>
>> -	pr_info("attempting ok execution at %px\n", do_nothing);
>> +	pr_info("attempting ok execution at %px\n", do_nothing_text);
>>   	do_nothing();
>>
>>   	if (write == CODE_WRITE) {
>> -		memcpy(dst, do_nothing, EXEC_SIZE);
>> +		memcpy(dst, do_nothing_text, EXEC_SIZE);
>>   		flush_icache_range((unsigned long)dst,
>>   				   (unsigned long)dst + EXEC_SIZE);
>>   	}
>> -	pr_info("attempting bad execution at %px\n", func);
>> +	pr_info("attempting bad execution at %px\n", dst);
>> +	func = setup_function_descriptor(&fdesc, dst);
>>   	func();
>>   	pr_err("FAIL: func returned\n");
>>   }
>> @@ -66,16 +81,19 @@ static void execute_user_location(void *dst)
>>   	int copied;
>>
>>   	/* Intentionally crossing kernel/user memory boundary. */
>> -	void (*func)(void) = dst;
>> +	void (*func)(void);
>> +	func_desc_t fdesc;
>> +	void *do_nothing_text = dereference_function_descriptor(do_nothing);
>>
>> -	pr_info("attempting ok execution at %px\n", do_nothing);
>> +	pr_info("attempting ok execution at %px\n", do_nothing_text);
>>   	do_nothing();
>>
>> -	copied = access_process_vm(current, (unsigned long)dst, do_nothing,
>> +	copied = access_process_vm(current, (unsigned long)dst, do_nothing_text,
>>   				   EXEC_SIZE, FOLL_WRITE);
>>   	if (copied < EXEC_SIZE)
>>   		return;
>> -	pr_info("attempting bad execution at %px\n", func);
>> +	pr_info("attempting bad execution at %px\n", dst);
>> +	func = setup_function_descriptor(&fdesc, dst);
>>   	func();
>>   	pr_err("FAIL: func returned\n");
>>   }
>> @@ -153,7 +171,8 @@ void lkdtm_EXEC_VMALLOC(void)
>>
>>   void lkdtm_EXEC_RODATA(void)
>>   {
>> -	execute_location(lkdtm_rodata_do_nothing, CODE_AS_IS);
>> +	execute_location(dereference_function_descriptor(lkdtm_rodata_do_nothing),
>> +			 CODE_AS_IS);
>>   }
>>
>>   void lkdtm_EXEC_USERSPACE(void)


^ permalink raw reply	[flat|nested] 99+ messages in thread

* Re: [PATCH v3 11/12] lkdtm: Fix execute_[user]_location()
@ 2021-12-17 17:12       ` Helge Deller
  0 siblings, 0 replies; 99+ messages in thread
From: Helge Deller @ 2021-12-17 17:12 UTC (permalink / raw)
  To: Christophe Leroy, Kees Cook, Michael Ellerman
  Cc: Benjamin Herrenschmidt, Greg Kroah-Hartman, linux-kernel,
	Andrew Morton, linuxppc-dev, linux-ia64, linux-parisc,
	linux-arch, linux-mm, James E.J. Bottomley, Paul Mackerras,
	Arnd Bergmann

On 12/17/21 12:49, Christophe Leroy wrote:
> Hi Kees,
>
> Le 17/10/2021 à 14:38, Christophe Leroy a écrit :
>> execute_location() and execute_user_location() intent
>> to copy do_nothing() text and execute it at a new location.
>> However, at the time being it doesn't copy do_nothing() function
>> but do_nothing() function descriptor which still points to the
>> original text. So at the end it still executes do_nothing() at
>> its original location allthough using a copied function descriptor.
>>
>> So, fix that by really copying do_nothing() text and build a new
>> function descriptor by copying do_nothing() function descriptor and
>> updating the target address with the new location.
>>
>> Also fix the displayed addresses by dereferencing do_nothing()
>> function descriptor.
>>
>> Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
>
> Do you have any comment to this patch and to patch 12 ?
>
> If not, is it ok to get your acked-by ?


Hi Christophe,

I think this whole series is a nice cleanup and harmonization
of how function descriptors are used.

At least for the PA-RISC parts you may add:
Acked-by: Helge Deller <deller@gmx.de>

Thanks!
Helge

>
>> ---
>>   drivers/misc/lkdtm/perms.c | 37 ++++++++++++++++++++++++++++---------
>>   1 file changed, 28 insertions(+), 9 deletions(-)
>>
>> diff --git a/drivers/misc/lkdtm/perms.c b/drivers/misc/lkdtm/perms.c
>> index 035fcca441f0..1cf24c4a79e9 100644
>> --- a/drivers/misc/lkdtm/perms.c
>> +++ b/drivers/misc/lkdtm/perms.c
>> @@ -44,19 +44,34 @@ static noinline void do_overwritten(void)
>>   	return;
>>   }
>>
>> +static void *setup_function_descriptor(func_desc_t *fdesc, void *dst)
>> +{
>> +	if (!have_function_descriptors())
>> +		return dst;
>> +
>> +	memcpy(fdesc, do_nothing, sizeof(*fdesc));
>> +	fdesc->addr = (unsigned long)dst;
>> +	barrier();
>> +
>> +	return fdesc;
>> +}
>> +
>>   static noinline void execute_location(void *dst, bool write)
>>   {
>> -	void (*func)(void) = dst;
>> +	void (*func)(void);
>> +	func_desc_t fdesc;
>> +	void *do_nothing_text = dereference_function_descriptor(do_nothing);
>>
>> -	pr_info("attempting ok execution at %px\n", do_nothing);
>> +	pr_info("attempting ok execution at %px\n", do_nothing_text);
>>   	do_nothing();
>>
>>   	if (write == CODE_WRITE) {
>> -		memcpy(dst, do_nothing, EXEC_SIZE);
>> +		memcpy(dst, do_nothing_text, EXEC_SIZE);
>>   		flush_icache_range((unsigned long)dst,
>>   				   (unsigned long)dst + EXEC_SIZE);
>>   	}
>> -	pr_info("attempting bad execution at %px\n", func);
>> +	pr_info("attempting bad execution at %px\n", dst);
>> +	func = setup_function_descriptor(&fdesc, dst);
>>   	func();
>>   	pr_err("FAIL: func returned\n");
>>   }
>> @@ -66,16 +81,19 @@ static void execute_user_location(void *dst)
>>   	int copied;
>>
>>   	/* Intentionally crossing kernel/user memory boundary. */
>> -	void (*func)(void) = dst;
>> +	void (*func)(void);
>> +	func_desc_t fdesc;
>> +	void *do_nothing_text = dereference_function_descriptor(do_nothing);
>>
>> -	pr_info("attempting ok execution at %px\n", do_nothing);
>> +	pr_info("attempting ok execution at %px\n", do_nothing_text);
>>   	do_nothing();
>>
>> -	copied = access_process_vm(current, (unsigned long)dst, do_nothing,
>> +	copied = access_process_vm(current, (unsigned long)dst, do_nothing_text,
>>   				   EXEC_SIZE, FOLL_WRITE);
>>   	if (copied < EXEC_SIZE)
>>   		return;
>> -	pr_info("attempting bad execution at %px\n", func);
>> +	pr_info("attempting bad execution at %px\n", dst);
>> +	func = setup_function_descriptor(&fdesc, dst);
>>   	func();
>>   	pr_err("FAIL: func returned\n");
>>   }
>> @@ -153,7 +171,8 @@ void lkdtm_EXEC_VMALLOC(void)
>>
>>   void lkdtm_EXEC_RODATA(void)
>>   {
>> -	execute_location(lkdtm_rodata_do_nothing, CODE_AS_IS);
>> +	execute_location(dereference_function_descriptor(lkdtm_rodata_do_nothing),
>> +			 CODE_AS_IS);
>>   }
>>
>>   void lkdtm_EXEC_USERSPACE(void)

^ permalink raw reply	[flat|nested] 99+ messages in thread

* Re: [PATCH v3 11/12] lkdtm: Fix execute_[user]_location()
  2021-12-17 11:49     ` Christophe Leroy
  (?)
@ 2022-01-19 19:28       ` Christophe Leroy
  -1 siblings, 0 replies; 99+ messages in thread
From: Christophe Leroy @ 2022-01-19 19:28 UTC (permalink / raw)
  To: Kees Cook
  Cc: Helge Deller, Benjamin Herrenschmidt, Greg Kroah-Hartman,
	linux-kernel, Andrew Morton, linuxppc-dev, linux-ia64,
	linux-parisc, linux-arch, linux-mm, James E.J. Bottomley,
	Paul Mackerras, Arnd Bergmann, Michael Ellerman

Hi Kees,


Le 17/12/2021 à 12:49, Christophe Leroy a écrit :
> Hi Kees,
> 
> Le 17/10/2021 à 14:38, Christophe Leroy a écrit :
>> execute_location() and execute_user_location() intent
>> to copy do_nothing() text and execute it at a new location.
>> However, at the time being it doesn't copy do_nothing() function
>> but do_nothing() function descriptor which still points to the
>> original text. So at the end it still executes do_nothing() at
>> its original location allthough using a copied function descriptor.
>>
>> So, fix that by really copying do_nothing() text and build a new
>> function descriptor by copying do_nothing() function descriptor and
>> updating the target address with the new location.
>>
>> Also fix the displayed addresses by dereferencing do_nothing()
>> function descriptor.
>>
>> Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
> 
> Do you have any comment to this patch and to patch 12 ?
> 
> If not, is it ok to get your acked-by ?

Any feedback please, even if it's to say no feedback ?

Many thanks,
Christophe

> 
> Thanks
> Christophe
> 
>> ---
>>   drivers/misc/lkdtm/perms.c | 37 ++++++++++++++++++++++++++++---------
>>   1 file changed, 28 insertions(+), 9 deletions(-)
>>
>> diff --git a/drivers/misc/lkdtm/perms.c b/drivers/misc/lkdtm/perms.c
>> index 035fcca441f0..1cf24c4a79e9 100644
>> --- a/drivers/misc/lkdtm/perms.c
>> +++ b/drivers/misc/lkdtm/perms.c
>> @@ -44,19 +44,34 @@ static noinline void do_overwritten(void)
>>       return;
>>   }
>> +static void *setup_function_descriptor(func_desc_t *fdesc, void *dst)
>> +{
>> +    if (!have_function_descriptors())
>> +        return dst;
>> +
>> +    memcpy(fdesc, do_nothing, sizeof(*fdesc));
>> +    fdesc->addr = (unsigned long)dst;
>> +    barrier();
>> +
>> +    return fdesc;
>> +}
>> +
>>   static noinline void execute_location(void *dst, bool write)
>>   {
>> -    void (*func)(void) = dst;
>> +    void (*func)(void);
>> +    func_desc_t fdesc;
>> +    void *do_nothing_text = dereference_function_descriptor(do_nothing);
>> -    pr_info("attempting ok execution at %px\n", do_nothing);
>> +    pr_info("attempting ok execution at %px\n", do_nothing_text);
>>       do_nothing();
>>       if (write == CODE_WRITE) {
>> -        memcpy(dst, do_nothing, EXEC_SIZE);
>> +        memcpy(dst, do_nothing_text, EXEC_SIZE);
>>           flush_icache_range((unsigned long)dst,
>>                      (unsigned long)dst + EXEC_SIZE);
>>       }
>> -    pr_info("attempting bad execution at %px\n", func);
>> +    pr_info("attempting bad execution at %px\n", dst);
>> +    func = setup_function_descriptor(&fdesc, dst);
>>       func();
>>       pr_err("FAIL: func returned\n");
>>   }
>> @@ -66,16 +81,19 @@ static void execute_user_location(void *dst)
>>       int copied;
>>       /* Intentionally crossing kernel/user memory boundary. */
>> -    void (*func)(void) = dst;
>> +    void (*func)(void);
>> +    func_desc_t fdesc;
>> +    void *do_nothing_text = dereference_function_descriptor(do_nothing);
>> -    pr_info("attempting ok execution at %px\n", do_nothing);
>> +    pr_info("attempting ok execution at %px\n", do_nothing_text);
>>       do_nothing();
>> -    copied = access_process_vm(current, (unsigned long)dst, do_nothing,
>> +    copied = access_process_vm(current, (unsigned long)dst, 
>> do_nothing_text,
>>                      EXEC_SIZE, FOLL_WRITE);
>>       if (copied < EXEC_SIZE)
>>           return;
>> -    pr_info("attempting bad execution at %px\n", func);
>> +    pr_info("attempting bad execution at %px\n", dst);
>> +    func = setup_function_descriptor(&fdesc, dst);
>>       func();
>>       pr_err("FAIL: func returned\n");
>>   }
>> @@ -153,7 +171,8 @@ void lkdtm_EXEC_VMALLOC(void)
>>   void lkdtm_EXEC_RODATA(void)
>>   {
>> -    execute_location(lkdtm_rodata_do_nothing, CODE_AS_IS);
>> +    
>> execute_location(dereference_function_descriptor(lkdtm_rodata_do_nothing), 
>>
>> +             CODE_AS_IS);
>>   }
>>   void lkdtm_EXEC_USERSPACE(void)
>>

^ permalink raw reply	[flat|nested] 99+ messages in thread

* Re: [PATCH v3 11/12] lkdtm: Fix execute_[user]_location()
@ 2022-01-19 19:28       ` Christophe Leroy
  0 siblings, 0 replies; 99+ messages in thread
From: Christophe Leroy @ 2022-01-19 19:28 UTC (permalink / raw)
  To: Kees Cook
  Cc: linux-arch, linux-ia64, Arnd Bergmann, linux-parisc,
	Helge Deller, linux-kernel, James E.J. Bottomley, linux-mm,
	Paul Mackerras, Greg Kroah-Hartman, Andrew Morton, linuxppc-dev

Hi Kees,


Le 17/12/2021 à 12:49, Christophe Leroy a écrit :
> Hi Kees,
> 
> Le 17/10/2021 à 14:38, Christophe Leroy a écrit :
>> execute_location() and execute_user_location() intent
>> to copy do_nothing() text and execute it at a new location.
>> However, at the time being it doesn't copy do_nothing() function
>> but do_nothing() function descriptor which still points to the
>> original text. So at the end it still executes do_nothing() at
>> its original location allthough using a copied function descriptor.
>>
>> So, fix that by really copying do_nothing() text and build a new
>> function descriptor by copying do_nothing() function descriptor and
>> updating the target address with the new location.
>>
>> Also fix the displayed addresses by dereferencing do_nothing()
>> function descriptor.
>>
>> Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
> 
> Do you have any comment to this patch and to patch 12 ?
> 
> If not, is it ok to get your acked-by ?

Any feedback please, even if it's to say no feedback ?

Many thanks,
Christophe

> 
> Thanks
> Christophe
> 
>> ---
>>   drivers/misc/lkdtm/perms.c | 37 ++++++++++++++++++++++++++++---------
>>   1 file changed, 28 insertions(+), 9 deletions(-)
>>
>> diff --git a/drivers/misc/lkdtm/perms.c b/drivers/misc/lkdtm/perms.c
>> index 035fcca441f0..1cf24c4a79e9 100644
>> --- a/drivers/misc/lkdtm/perms.c
>> +++ b/drivers/misc/lkdtm/perms.c
>> @@ -44,19 +44,34 @@ static noinline void do_overwritten(void)
>>       return;
>>   }
>> +static void *setup_function_descriptor(func_desc_t *fdesc, void *dst)
>> +{
>> +    if (!have_function_descriptors())
>> +        return dst;
>> +
>> +    memcpy(fdesc, do_nothing, sizeof(*fdesc));
>> +    fdesc->addr = (unsigned long)dst;
>> +    barrier();
>> +
>> +    return fdesc;
>> +}
>> +
>>   static noinline void execute_location(void *dst, bool write)
>>   {
>> -    void (*func)(void) = dst;
>> +    void (*func)(void);
>> +    func_desc_t fdesc;
>> +    void *do_nothing_text = dereference_function_descriptor(do_nothing);
>> -    pr_info("attempting ok execution at %px\n", do_nothing);
>> +    pr_info("attempting ok execution at %px\n", do_nothing_text);
>>       do_nothing();
>>       if (write == CODE_WRITE) {
>> -        memcpy(dst, do_nothing, EXEC_SIZE);
>> +        memcpy(dst, do_nothing_text, EXEC_SIZE);
>>           flush_icache_range((unsigned long)dst,
>>                      (unsigned long)dst + EXEC_SIZE);
>>       }
>> -    pr_info("attempting bad execution at %px\n", func);
>> +    pr_info("attempting bad execution at %px\n", dst);
>> +    func = setup_function_descriptor(&fdesc, dst);
>>       func();
>>       pr_err("FAIL: func returned\n");
>>   }
>> @@ -66,16 +81,19 @@ static void execute_user_location(void *dst)
>>       int copied;
>>       /* Intentionally crossing kernel/user memory boundary. */
>> -    void (*func)(void) = dst;
>> +    void (*func)(void);
>> +    func_desc_t fdesc;
>> +    void *do_nothing_text = dereference_function_descriptor(do_nothing);
>> -    pr_info("attempting ok execution at %px\n", do_nothing);
>> +    pr_info("attempting ok execution at %px\n", do_nothing_text);
>>       do_nothing();
>> -    copied = access_process_vm(current, (unsigned long)dst, do_nothing,
>> +    copied = access_process_vm(current, (unsigned long)dst, 
>> do_nothing_text,
>>                      EXEC_SIZE, FOLL_WRITE);
>>       if (copied < EXEC_SIZE)
>>           return;
>> -    pr_info("attempting bad execution at %px\n", func);
>> +    pr_info("attempting bad execution at %px\n", dst);
>> +    func = setup_function_descriptor(&fdesc, dst);
>>       func();
>>       pr_err("FAIL: func returned\n");
>>   }
>> @@ -153,7 +171,8 @@ void lkdtm_EXEC_VMALLOC(void)
>>   void lkdtm_EXEC_RODATA(void)
>>   {
>> -    execute_location(lkdtm_rodata_do_nothing, CODE_AS_IS);
>> +    
>> execute_location(dereference_function_descriptor(lkdtm_rodata_do_nothing), 
>>
>> +             CODE_AS_IS);
>>   }
>>   void lkdtm_EXEC_USERSPACE(void)
>>

^ permalink raw reply	[flat|nested] 99+ messages in thread

* Re: [PATCH v3 11/12] lkdtm: Fix execute_[user]_location()
@ 2022-01-19 19:28       ` Christophe Leroy
  0 siblings, 0 replies; 99+ messages in thread
From: Christophe Leroy @ 2022-01-19 19:28 UTC (permalink / raw)
  To: Kees Cook
  Cc: Helge Deller, Benjamin Herrenschmidt, Greg Kroah-Hartman,
	linux-kernel, Andrew Morton, linuxppc-dev, linux-ia64,
	linux-parisc, linux-arch, linux-mm, James E.J. Bottomley,
	Paul Mackerras, Arnd Bergmann, Michael Ellerman

Hi Kees,


Le 17/12/2021 à 12:49, Christophe Leroy a écrit :
> Hi Kees,
> 
> Le 17/10/2021 à 14:38, Christophe Leroy a écrit :
>> execute_location() and execute_user_location() intent
>> to copy do_nothing() text and execute it at a new location.
>> However, at the time being it doesn't copy do_nothing() function
>> but do_nothing() function descriptor which still points to the
>> original text. So at the end it still executes do_nothing() at
>> its original location allthough using a copied function descriptor.
>>
>> So, fix that by really copying do_nothing() text and build a new
>> function descriptor by copying do_nothing() function descriptor and
>> updating the target address with the new location.
>>
>> Also fix the displayed addresses by dereferencing do_nothing()
>> function descriptor.
>>
>> Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
> 
> Do you have any comment to this patch and to patch 12 ?
> 
> If not, is it ok to get your acked-by ?

Any feedback please, even if it's to say no feedback ?

Many thanks,
Christophe

> 
> Thanks
> Christophe
> 
>> ---
>>   drivers/misc/lkdtm/perms.c | 37 ++++++++++++++++++++++++++++---------
>>   1 file changed, 28 insertions(+), 9 deletions(-)
>>
>> diff --git a/drivers/misc/lkdtm/perms.c b/drivers/misc/lkdtm/perms.c
>> index 035fcca441f0..1cf24c4a79e9 100644
>> --- a/drivers/misc/lkdtm/perms.c
>> +++ b/drivers/misc/lkdtm/perms.c
>> @@ -44,19 +44,34 @@ static noinline void do_overwritten(void)
>>       return;
>>   }
>> +static void *setup_function_descriptor(func_desc_t *fdesc, void *dst)
>> +{
>> +    if (!have_function_descriptors())
>> +        return dst;
>> +
>> +    memcpy(fdesc, do_nothing, sizeof(*fdesc));
>> +    fdesc->addr = (unsigned long)dst;
>> +    barrier();
>> +
>> +    return fdesc;
>> +}
>> +
>>   static noinline void execute_location(void *dst, bool write)
>>   {
>> -    void (*func)(void) = dst;
>> +    void (*func)(void);
>> +    func_desc_t fdesc;
>> +    void *do_nothing_text = dereference_function_descriptor(do_nothing);
>> -    pr_info("attempting ok execution at %px\n", do_nothing);
>> +    pr_info("attempting ok execution at %px\n", do_nothing_text);
>>       do_nothing();
>>       if (write = CODE_WRITE) {
>> -        memcpy(dst, do_nothing, EXEC_SIZE);
>> +        memcpy(dst, do_nothing_text, EXEC_SIZE);
>>           flush_icache_range((unsigned long)dst,
>>                      (unsigned long)dst + EXEC_SIZE);
>>       }
>> -    pr_info("attempting bad execution at %px\n", func);
>> +    pr_info("attempting bad execution at %px\n", dst);
>> +    func = setup_function_descriptor(&fdesc, dst);
>>       func();
>>       pr_err("FAIL: func returned\n");
>>   }
>> @@ -66,16 +81,19 @@ static void execute_user_location(void *dst)
>>       int copied;
>>       /* Intentionally crossing kernel/user memory boundary. */
>> -    void (*func)(void) = dst;
>> +    void (*func)(void);
>> +    func_desc_t fdesc;
>> +    void *do_nothing_text = dereference_function_descriptor(do_nothing);
>> -    pr_info("attempting ok execution at %px\n", do_nothing);
>> +    pr_info("attempting ok execution at %px\n", do_nothing_text);
>>       do_nothing();
>> -    copied = access_process_vm(current, (unsigned long)dst, do_nothing,
>> +    copied = access_process_vm(current, (unsigned long)dst, 
>> do_nothing_text,
>>                      EXEC_SIZE, FOLL_WRITE);
>>       if (copied < EXEC_SIZE)
>>           return;
>> -    pr_info("attempting bad execution at %px\n", func);
>> +    pr_info("attempting bad execution at %px\n", dst);
>> +    func = setup_function_descriptor(&fdesc, dst);
>>       func();
>>       pr_err("FAIL: func returned\n");
>>   }
>> @@ -153,7 +171,8 @@ void lkdtm_EXEC_VMALLOC(void)
>>   void lkdtm_EXEC_RODATA(void)
>>   {
>> -    execute_location(lkdtm_rodata_do_nothing, CODE_AS_IS);
>> +    
>> execute_location(dereference_function_descriptor(lkdtm_rodata_do_nothing), 
>>
>> +             CODE_AS_IS);
>>   }
>>   void lkdtm_EXEC_USERSPACE(void)
>>

^ permalink raw reply	[flat|nested] 99+ messages in thread

* Re: [PATCH v3 11/12] lkdtm: Fix execute_[user]_location()
  2022-01-19 19:28       ` Christophe Leroy
  (?)
@ 2022-01-19 22:00         ` Kees Cook
  -1 siblings, 0 replies; 99+ messages in thread
From: Kees Cook @ 2022-01-19 21:58 UTC (permalink / raw)
  To: Christophe Leroy
  Cc: Helge Deller, Benjamin Herrenschmidt, Greg Kroah-Hartman,
	linux-kernel, Andrew Morton, linuxppc-dev, linux-ia64,
	linux-parisc, linux-arch, linux-mm, James E.J. Bottomley,
	Paul Mackerras, Arnd Bergmann, Michael Ellerman

On Wed, Jan 19, 2022 at 08:28:54PM +0100, Christophe Leroy wrote:
> Hi Kees,
> 
> 
> Le 17/12/2021 à 12:49, Christophe Leroy a écrit :
> > Hi Kees,
> > 
> > Le 17/10/2021 à 14:38, Christophe Leroy a écrit :
> > > execute_location() and execute_user_location() intent
> > > to copy do_nothing() text and execute it at a new location.
> > > However, at the time being it doesn't copy do_nothing() function
> > > but do_nothing() function descriptor which still points to the
> > > original text. So at the end it still executes do_nothing() at
> > > its original location allthough using a copied function descriptor.
> > > 
> > > So, fix that by really copying do_nothing() text and build a new
> > > function descriptor by copying do_nothing() function descriptor and
> > > updating the target address with the new location.
> > > 
> > > Also fix the displayed addresses by dereferencing do_nothing()
> > > function descriptor.
> > > 
> > > Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
> > 
> > Do you have any comment to this patch and to patch 12 ?
> > 
> > If not, is it ok to get your acked-by ?
> 
> Any feedback please, even if it's to say no feedback ?

Hi! Thanks for the ping; I haven't had time yet to look at this, but
with -rc1 coming, I should be able to task-switch back to LKDTM for the
dev cycle and I can give some feedback.

-Kees

> 
> Many thanks,
> Christophe
> 
> > 
> > Thanks
> > Christophe
> > 
> > > ---
> > >   drivers/misc/lkdtm/perms.c | 37 ++++++++++++++++++++++++++++---------
> > >   1 file changed, 28 insertions(+), 9 deletions(-)
> > > 
> > > diff --git a/drivers/misc/lkdtm/perms.c b/drivers/misc/lkdtm/perms.c
> > > index 035fcca441f0..1cf24c4a79e9 100644
> > > --- a/drivers/misc/lkdtm/perms.c
> > > +++ b/drivers/misc/lkdtm/perms.c
> > > @@ -44,19 +44,34 @@ static noinline void do_overwritten(void)
> > >       return;
> > >   }
> > > +static void *setup_function_descriptor(func_desc_t *fdesc, void *dst)
> > > +{
> > > +    if (!have_function_descriptors())
> > > +        return dst;
> > > +
> > > +    memcpy(fdesc, do_nothing, sizeof(*fdesc));
> > > +    fdesc->addr = (unsigned long)dst;
> > > +    barrier();
> > > +
> > > +    return fdesc;
> > > +}
> > > +
> > >   static noinline void execute_location(void *dst, bool write)
> > >   {
> > > -    void (*func)(void) = dst;
> > > +    void (*func)(void);
> > > +    func_desc_t fdesc;
> > > +    void *do_nothing_text = dereference_function_descriptor(do_nothing);
> > > -    pr_info("attempting ok execution at %px\n", do_nothing);
> > > +    pr_info("attempting ok execution at %px\n", do_nothing_text);
> > >       do_nothing();
> > >       if (write = CODE_WRITE) {
> > > -        memcpy(dst, do_nothing, EXEC_SIZE);
> > > +        memcpy(dst, do_nothing_text, EXEC_SIZE);
> > >           flush_icache_range((unsigned long)dst,
> > >                      (unsigned long)dst + EXEC_SIZE);
> > >       }
> > > -    pr_info("attempting bad execution at %px\n", func);
> > > +    pr_info("attempting bad execution at %px\n", dst);
> > > +    func = setup_function_descriptor(&fdesc, dst);
> > >       func();
> > >       pr_err("FAIL: func returned\n");
> > >   }
> > > @@ -66,16 +81,19 @@ static void execute_user_location(void *dst)
> > >       int copied;
> > >       /* Intentionally crossing kernel/user memory boundary. */
> > > -    void (*func)(void) = dst;
> > > +    void (*func)(void);
> > > +    func_desc_t fdesc;
> > > +    void *do_nothing_text = dereference_function_descriptor(do_nothing);
> > > -    pr_info("attempting ok execution at %px\n", do_nothing);
> > > +    pr_info("attempting ok execution at %px\n", do_nothing_text);
> > >       do_nothing();
> > > -    copied = access_process_vm(current, (unsigned long)dst, do_nothing,
> > > +    copied = access_process_vm(current, (unsigned long)dst,
> > > do_nothing_text,
> > >                      EXEC_SIZE, FOLL_WRITE);
> > >       if (copied < EXEC_SIZE)
> > >           return;
> > > -    pr_info("attempting bad execution at %px\n", func);
> > > +    pr_info("attempting bad execution at %px\n", dst);
> > > +    func = setup_function_descriptor(&fdesc, dst);
> > >       func();
> > >       pr_err("FAIL: func returned\n");
> > >   }
> > > @@ -153,7 +171,8 @@ void lkdtm_EXEC_VMALLOC(void)
> > >   void lkdtm_EXEC_RODATA(void)
> > >   {
> > > -    execute_location(lkdtm_rodata_do_nothing, CODE_AS_IS);
> > > +    execute_location(dereference_function_descriptor(lkdtm_rodata_do_nothing),
> > > 
> > > +             CODE_AS_IS);
> > >   }
> > >   void lkdtm_EXEC_USERSPACE(void)
> > > 

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 99+ messages in thread

* Re: [PATCH v3 11/12] lkdtm: Fix execute_[user]_location()
@ 2022-01-19 22:00         ` Kees Cook
  0 siblings, 0 replies; 99+ messages in thread
From: Kees Cook @ 2022-01-19 22:00 UTC (permalink / raw)
  To: Christophe Leroy
  Cc: Helge Deller, Benjamin Herrenschmidt, Greg Kroah-Hartman,
	linux-kernel, Andrew Morton, linuxppc-dev, linux-ia64,
	linux-parisc, linux-arch, linux-mm, James E.J. Bottomley,
	Paul Mackerras, Arnd Bergmann, Michael Ellerman

On Wed, Jan 19, 2022 at 08:28:54PM +0100, Christophe Leroy wrote:
> Hi Kees,
> 
> 
> Le 17/12/2021 à 12:49, Christophe Leroy a écrit :
> > Hi Kees,
> > 
> > Le 17/10/2021 à 14:38, Christophe Leroy a écrit :
> > > execute_location() and execute_user_location() intent
> > > to copy do_nothing() text and execute it at a new location.
> > > However, at the time being it doesn't copy do_nothing() function
> > > but do_nothing() function descriptor which still points to the
> > > original text. So at the end it still executes do_nothing() at
> > > its original location allthough using a copied function descriptor.
> > > 
> > > So, fix that by really copying do_nothing() text and build a new
> > > function descriptor by copying do_nothing() function descriptor and
> > > updating the target address with the new location.
> > > 
> > > Also fix the displayed addresses by dereferencing do_nothing()
> > > function descriptor.
> > > 
> > > Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
> > 
> > Do you have any comment to this patch and to patch 12 ?
> > 
> > If not, is it ok to get your acked-by ?
> 
> Any feedback please, even if it's to say no feedback ?

Hi! Thanks for the ping; I haven't had time yet to look at this, but
with -rc1 coming, I should be able to task-switch back to LKDTM for the
dev cycle and I can give some feedback.

-Kees

> 
> Many thanks,
> Christophe
> 
> > 
> > Thanks
> > Christophe
> > 
> > > ---
> > >   drivers/misc/lkdtm/perms.c | 37 ++++++++++++++++++++++++++++---------
> > >   1 file changed, 28 insertions(+), 9 deletions(-)
> > > 
> > > diff --git a/drivers/misc/lkdtm/perms.c b/drivers/misc/lkdtm/perms.c
> > > index 035fcca441f0..1cf24c4a79e9 100644
> > > --- a/drivers/misc/lkdtm/perms.c
> > > +++ b/drivers/misc/lkdtm/perms.c
> > > @@ -44,19 +44,34 @@ static noinline void do_overwritten(void)
> > >       return;
> > >   }
> > > +static void *setup_function_descriptor(func_desc_t *fdesc, void *dst)
> > > +{
> > > +    if (!have_function_descriptors())
> > > +        return dst;
> > > +
> > > +    memcpy(fdesc, do_nothing, sizeof(*fdesc));
> > > +    fdesc->addr = (unsigned long)dst;
> > > +    barrier();
> > > +
> > > +    return fdesc;
> > > +}
> > > +
> > >   static noinline void execute_location(void *dst, bool write)
> > >   {
> > > -    void (*func)(void) = dst;
> > > +    void (*func)(void);
> > > +    func_desc_t fdesc;
> > > +    void *do_nothing_text = dereference_function_descriptor(do_nothing);
> > > -    pr_info("attempting ok execution at %px\n", do_nothing);
> > > +    pr_info("attempting ok execution at %px\n", do_nothing_text);
> > >       do_nothing();
> > >       if (write == CODE_WRITE) {
> > > -        memcpy(dst, do_nothing, EXEC_SIZE);
> > > +        memcpy(dst, do_nothing_text, EXEC_SIZE);
> > >           flush_icache_range((unsigned long)dst,
> > >                      (unsigned long)dst + EXEC_SIZE);
> > >       }
> > > -    pr_info("attempting bad execution at %px\n", func);
> > > +    pr_info("attempting bad execution at %px\n", dst);
> > > +    func = setup_function_descriptor(&fdesc, dst);
> > >       func();
> > >       pr_err("FAIL: func returned\n");
> > >   }
> > > @@ -66,16 +81,19 @@ static void execute_user_location(void *dst)
> > >       int copied;
> > >       /* Intentionally crossing kernel/user memory boundary. */
> > > -    void (*func)(void) = dst;
> > > +    void (*func)(void);
> > > +    func_desc_t fdesc;
> > > +    void *do_nothing_text = dereference_function_descriptor(do_nothing);
> > > -    pr_info("attempting ok execution at %px\n", do_nothing);
> > > +    pr_info("attempting ok execution at %px\n", do_nothing_text);
> > >       do_nothing();
> > > -    copied = access_process_vm(current, (unsigned long)dst, do_nothing,
> > > +    copied = access_process_vm(current, (unsigned long)dst,
> > > do_nothing_text,
> > >                      EXEC_SIZE, FOLL_WRITE);
> > >       if (copied < EXEC_SIZE)
> > >           return;
> > > -    pr_info("attempting bad execution at %px\n", func);
> > > +    pr_info("attempting bad execution at %px\n", dst);
> > > +    func = setup_function_descriptor(&fdesc, dst);
> > >       func();
> > >       pr_err("FAIL: func returned\n");
> > >   }
> > > @@ -153,7 +171,8 @@ void lkdtm_EXEC_VMALLOC(void)
> > >   void lkdtm_EXEC_RODATA(void)
> > >   {
> > > -    execute_location(lkdtm_rodata_do_nothing, CODE_AS_IS);
> > > +    execute_location(dereference_function_descriptor(lkdtm_rodata_do_nothing),
> > > 
> > > +             CODE_AS_IS);
> > >   }
> > >   void lkdtm_EXEC_USERSPACE(void)
> > > 

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 99+ messages in thread

* Re: [PATCH v3 11/12] lkdtm: Fix execute_[user]_location()
@ 2022-01-19 22:00         ` Kees Cook
  0 siblings, 0 replies; 99+ messages in thread
From: Kees Cook @ 2022-01-19 22:00 UTC (permalink / raw)
  To: Christophe Leroy
  Cc: linux-arch, linux-ia64, Arnd Bergmann, linux-parisc,
	Helge Deller, linux-kernel, James E.J. Bottomley, linux-mm,
	Paul Mackerras, Greg Kroah-Hartman, Andrew Morton, linuxppc-dev

On Wed, Jan 19, 2022 at 08:28:54PM +0100, Christophe Leroy wrote:
> Hi Kees,
> 
> 
> Le 17/12/2021 à 12:49, Christophe Leroy a écrit :
> > Hi Kees,
> > 
> > Le 17/10/2021 à 14:38, Christophe Leroy a écrit :
> > > execute_location() and execute_user_location() intent
> > > to copy do_nothing() text and execute it at a new location.
> > > However, at the time being it doesn't copy do_nothing() function
> > > but do_nothing() function descriptor which still points to the
> > > original text. So at the end it still executes do_nothing() at
> > > its original location allthough using a copied function descriptor.
> > > 
> > > So, fix that by really copying do_nothing() text and build a new
> > > function descriptor by copying do_nothing() function descriptor and
> > > updating the target address with the new location.
> > > 
> > > Also fix the displayed addresses by dereferencing do_nothing()
> > > function descriptor.
> > > 
> > > Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
> > 
> > Do you have any comment to this patch and to patch 12 ?
> > 
> > If not, is it ok to get your acked-by ?
> 
> Any feedback please, even if it's to say no feedback ?

Hi! Thanks for the ping; I haven't had time yet to look at this, but
with -rc1 coming, I should be able to task-switch back to LKDTM for the
dev cycle and I can give some feedback.

-Kees

> 
> Many thanks,
> Christophe
> 
> > 
> > Thanks
> > Christophe
> > 
> > > ---
> > >   drivers/misc/lkdtm/perms.c | 37 ++++++++++++++++++++++++++++---------
> > >   1 file changed, 28 insertions(+), 9 deletions(-)
> > > 
> > > diff --git a/drivers/misc/lkdtm/perms.c b/drivers/misc/lkdtm/perms.c
> > > index 035fcca441f0..1cf24c4a79e9 100644
> > > --- a/drivers/misc/lkdtm/perms.c
> > > +++ b/drivers/misc/lkdtm/perms.c
> > > @@ -44,19 +44,34 @@ static noinline void do_overwritten(void)
> > >       return;
> > >   }
> > > +static void *setup_function_descriptor(func_desc_t *fdesc, void *dst)
> > > +{
> > > +    if (!have_function_descriptors())
> > > +        return dst;
> > > +
> > > +    memcpy(fdesc, do_nothing, sizeof(*fdesc));
> > > +    fdesc->addr = (unsigned long)dst;
> > > +    barrier();
> > > +
> > > +    return fdesc;
> > > +}
> > > +
> > >   static noinline void execute_location(void *dst, bool write)
> > >   {
> > > -    void (*func)(void) = dst;
> > > +    void (*func)(void);
> > > +    func_desc_t fdesc;
> > > +    void *do_nothing_text = dereference_function_descriptor(do_nothing);
> > > -    pr_info("attempting ok execution at %px\n", do_nothing);
> > > +    pr_info("attempting ok execution at %px\n", do_nothing_text);
> > >       do_nothing();
> > >       if (write == CODE_WRITE) {
> > > -        memcpy(dst, do_nothing, EXEC_SIZE);
> > > +        memcpy(dst, do_nothing_text, EXEC_SIZE);
> > >           flush_icache_range((unsigned long)dst,
> > >                      (unsigned long)dst + EXEC_SIZE);
> > >       }
> > > -    pr_info("attempting bad execution at %px\n", func);
> > > +    pr_info("attempting bad execution at %px\n", dst);
> > > +    func = setup_function_descriptor(&fdesc, dst);
> > >       func();
> > >       pr_err("FAIL: func returned\n");
> > >   }
> > > @@ -66,16 +81,19 @@ static void execute_user_location(void *dst)
> > >       int copied;
> > >       /* Intentionally crossing kernel/user memory boundary. */
> > > -    void (*func)(void) = dst;
> > > +    void (*func)(void);
> > > +    func_desc_t fdesc;
> > > +    void *do_nothing_text = dereference_function_descriptor(do_nothing);
> > > -    pr_info("attempting ok execution at %px\n", do_nothing);
> > > +    pr_info("attempting ok execution at %px\n", do_nothing_text);
> > >       do_nothing();
> > > -    copied = access_process_vm(current, (unsigned long)dst, do_nothing,
> > > +    copied = access_process_vm(current, (unsigned long)dst,
> > > do_nothing_text,
> > >                      EXEC_SIZE, FOLL_WRITE);
> > >       if (copied < EXEC_SIZE)
> > >           return;
> > > -    pr_info("attempting bad execution at %px\n", func);
> > > +    pr_info("attempting bad execution at %px\n", dst);
> > > +    func = setup_function_descriptor(&fdesc, dst);
> > >       func();
> > >       pr_err("FAIL: func returned\n");
> > >   }
> > > @@ -153,7 +171,8 @@ void lkdtm_EXEC_VMALLOC(void)
> > >   void lkdtm_EXEC_RODATA(void)
> > >   {
> > > -    execute_location(lkdtm_rodata_do_nothing, CODE_AS_IS);
> > > +    execute_location(dereference_function_descriptor(lkdtm_rodata_do_nothing),
> > > 
> > > +             CODE_AS_IS);
> > >   }
> > >   void lkdtm_EXEC_USERSPACE(void)
> > > 

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 99+ messages in thread

* Re: [PATCH v3 08/12] asm-generic: Refactor dereference_[kernel]_function_descriptor()
  2021-10-17 12:38   ` Christophe Leroy
  (?)
@ 2022-02-10 10:30     ` Michael Ellerman
  -1 siblings, 0 replies; 99+ messages in thread
From: Michael Ellerman @ 2022-02-10 10:30 UTC (permalink / raw)
  To: Christophe Leroy, Benjamin Herrenschmidt, Paul Mackerras,
	Andrew Morton, James E.J. Bottomley, Helge Deller, Arnd Bergmann,
	Kees Cook, Greg Kroah-Hartman
  Cc: Christophe Leroy, linux-kernel, linuxppc-dev, linux-ia64,
	linux-parisc, linux-arch, linux-mm

Christophe Leroy <christophe.leroy@csgroup.eu> writes:
> diff --git a/kernel/extable.c b/kernel/extable.c
> index b0ea5eb0c3b4..1ef13789bea9 100644
> --- a/kernel/extable.c
> +++ b/kernel/extable.c
> @@ -159,12 +160,32 @@ int kernel_text_address(unsigned long addr)
>  }
>  
>  /*
> - * On some architectures (PPC64, IA64) function pointers
> + * On some architectures (PPC64, IA64, PARISC) function pointers
>   * are actually only tokens to some data that then holds the
>   * real function address. As a result, to find if a function
>   * pointer is part of the kernel text, we need to do some
>   * special dereferencing first.
>   */
> +#ifdef CONFIG_HAVE_FUNCTION_DESCRIPTORS
> +void *dereference_function_descriptor(void *ptr)
> +{
> +	func_desc_t *desc = ptr;
> +	void *p;
> +
> +	if (!get_kernel_nofault(p, (void *)&desc->addr))
> +		ptr = p;
> +	return ptr;
> +}

This needs an EXPORT_SYMBOL_GPL(), otherwise the build breaks after
patch 10 with CONFIG_LKDTM=m.

cheers

^ permalink raw reply	[flat|nested] 99+ messages in thread

* Re: [PATCH v3 08/12] asm-generic: Refactor dereference_[kernel]_function_descriptor()
@ 2022-02-10 10:30     ` Michael Ellerman
  0 siblings, 0 replies; 99+ messages in thread
From: Michael Ellerman @ 2022-02-10 10:30 UTC (permalink / raw)
  To: Christophe Leroy, Benjamin Herrenschmidt, Paul Mackerras,
	Andrew Morton, James E.J. Bottomley, Helge Deller, Arnd Bergmann,
	Kees Cook, Greg Kroah-Hartman
  Cc: linux-arch, linux-ia64, linux-parisc, linux-kernel, linux-mm,
	linuxppc-dev

Christophe Leroy <christophe.leroy@csgroup.eu> writes:
> diff --git a/kernel/extable.c b/kernel/extable.c
> index b0ea5eb0c3b4..1ef13789bea9 100644
> --- a/kernel/extable.c
> +++ b/kernel/extable.c
> @@ -159,12 +160,32 @@ int kernel_text_address(unsigned long addr)
>  }
>  
>  /*
> - * On some architectures (PPC64, IA64) function pointers
> + * On some architectures (PPC64, IA64, PARISC) function pointers
>   * are actually only tokens to some data that then holds the
>   * real function address. As a result, to find if a function
>   * pointer is part of the kernel text, we need to do some
>   * special dereferencing first.
>   */
> +#ifdef CONFIG_HAVE_FUNCTION_DESCRIPTORS
> +void *dereference_function_descriptor(void *ptr)
> +{
> +	func_desc_t *desc = ptr;
> +	void *p;
> +
> +	if (!get_kernel_nofault(p, (void *)&desc->addr))
> +		ptr = p;
> +	return ptr;
> +}

This needs an EXPORT_SYMBOL_GPL(), otherwise the build breaks after
patch 10 with CONFIG_LKDTM=m.

cheers

^ permalink raw reply	[flat|nested] 99+ messages in thread

* Re: [PATCH v3 08/12] asm-generic: Refactor dereference_[kernel]_function_descriptor()
@ 2022-02-10 10:30     ` Michael Ellerman
  0 siblings, 0 replies; 99+ messages in thread
From: Michael Ellerman @ 2022-02-10 10:30 UTC (permalink / raw)
  To: Christophe Leroy, Benjamin Herrenschmidt, Paul Mackerras,
	Andrew Morton, James E.J. Bottomley, Helge Deller, Arnd Bergmann,
	Kees Cook, Greg Kroah-Hartman
  Cc: Christophe Leroy, linux-kernel, linuxppc-dev, linux-ia64,
	linux-parisc, linux-arch, linux-mm

Christophe Leroy <christophe.leroy@csgroup.eu> writes:
> diff --git a/kernel/extable.c b/kernel/extable.c
> index b0ea5eb0c3b4..1ef13789bea9 100644
> --- a/kernel/extable.c
> +++ b/kernel/extable.c
> @@ -159,12 +160,32 @@ int kernel_text_address(unsigned long addr)
>  }
>  
>  /*
> - * On some architectures (PPC64, IA64) function pointers
> + * On some architectures (PPC64, IA64, PARISC) function pointers
>   * are actually only tokens to some data that then holds the
>   * real function address. As a result, to find if a function
>   * pointer is part of the kernel text, we need to do some
>   * special dereferencing first.
>   */
> +#ifdef CONFIG_HAVE_FUNCTION_DESCRIPTORS
> +void *dereference_function_descriptor(void *ptr)
> +{
> +	func_desc_t *desc = ptr;
> +	void *p;
> +
> +	if (!get_kernel_nofault(p, (void *)&desc->addr))
> +		ptr = p;
> +	return ptr;
> +}

This needs an EXPORT_SYMBOL_GPL(), otherwise the build breaks after
patch 10 with CONFIG_LKDTM=m.

cheers

^ permalink raw reply	[flat|nested] 99+ messages in thread

* Re: [PATCH v3 01/12] powerpc: Move and rename func_descr_t
  2021-10-17 12:38   ` Christophe Leroy
  (?)
@ 2022-02-11  0:51     ` Kees Cook
  -1 siblings, 0 replies; 99+ messages in thread
From: Kees Cook @ 2022-02-11  0:51 UTC (permalink / raw)
  To: Christophe Leroy
  Cc: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Andrew Morton, James E.J. Bottomley, Helge Deller, Arnd Bergmann,
	Greg Kroah-Hartman, linux-kernel, linuxppc-dev, linux-ia64,
	linux-parisc, linux-arch, linux-mm

On Sun, Oct 17, 2021 at 02:38:14PM +0200, Christophe Leroy wrote:
> There are three architectures with function descriptors, try to
> have common names for the address they contain in order to
> refactor some functions into generic functions later.
> 
> powerpc has 'entry'
> ia64 has 'ip'
> parisc has 'addr'
> 
> Vote for 'addr' and update 'func_descr_t' accordingly.
> 
> Move it in asm/elf.h to have it at the same place on all
> three architectures, remove the typedef which hides its real
> type, and change it to a smoother name 'struct func_desc'.
> 
> Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>

I like the name. :)

Reviewed-by: Kees Cook <keescook@chromium.org>

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 99+ messages in thread

* Re: [PATCH v3 01/12] powerpc: Move and rename func_descr_t
@ 2022-02-11  0:51     ` Kees Cook
  0 siblings, 0 replies; 99+ messages in thread
From: Kees Cook @ 2022-02-11  0:51 UTC (permalink / raw)
  To: Christophe Leroy
  Cc: linux-arch, linux-ia64, linux-parisc, Arnd Bergmann,
	Greg Kroah-Hartman, Helge Deller, linux-kernel,
	James E.J. Bottomley, linux-mm, Paul Mackerras, Andrew Morton,
	linuxppc-dev

On Sun, Oct 17, 2021 at 02:38:14PM +0200, Christophe Leroy wrote:
> There are three architectures with function descriptors, try to
> have common names for the address they contain in order to
> refactor some functions into generic functions later.
> 
> powerpc has 'entry'
> ia64 has 'ip'
> parisc has 'addr'
> 
> Vote for 'addr' and update 'func_descr_t' accordingly.
> 
> Move it in asm/elf.h to have it at the same place on all
> three architectures, remove the typedef which hides its real
> type, and change it to a smoother name 'struct func_desc'.
> 
> Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>

I like the name. :)

Reviewed-by: Kees Cook <keescook@chromium.org>

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 99+ messages in thread

* Re: [PATCH v3 01/12] powerpc: Move and rename func_descr_t
@ 2022-02-11  0:51     ` Kees Cook
  0 siblings, 0 replies; 99+ messages in thread
From: Kees Cook @ 2022-02-11  0:51 UTC (permalink / raw)
  To: Christophe Leroy
  Cc: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Andrew Morton, James E.J. Bottomley, Helge Deller, Arnd Bergmann,
	Greg Kroah-Hartman, linux-kernel, linuxppc-dev, linux-ia64,
	linux-parisc, linux-arch, linux-mm

On Sun, Oct 17, 2021 at 02:38:14PM +0200, Christophe Leroy wrote:
> There are three architectures with function descriptors, try to
> have common names for the address they contain in order to
> refactor some functions into generic functions later.
> 
> powerpc has 'entry'
> ia64 has 'ip'
> parisc has 'addr'
> 
> Vote for 'addr' and update 'func_descr_t' accordingly.
> 
> Move it in asm/elf.h to have it at the same place on all
> three architectures, remove the typedef which hides its real
> type, and change it to a smoother name 'struct func_desc'.
> 
> Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>

I like the name. :)

Reviewed-by: Kees Cook <keescook@chromium.org>

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 99+ messages in thread

* Re: [PATCH v3 04/12] powerpc: Prepare func_desc_t for refactorisation
  2021-10-17 12:38   ` Christophe Leroy
  (?)
@ 2022-02-11  0:54     ` Kees Cook
  -1 siblings, 0 replies; 99+ messages in thread
From: Kees Cook @ 2022-02-11  0:54 UTC (permalink / raw)
  To: Christophe Leroy
  Cc: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Andrew Morton, James E.J. Bottomley, Helge Deller, Arnd Bergmann,
	Greg Kroah-Hartman, linux-kernel, linuxppc-dev, linux-ia64,
	linux-parisc, linux-arch, linux-mm

On Sun, Oct 17, 2021 at 02:38:17PM +0200, Christophe Leroy wrote:
> In preparation of making func_desc_t generic, change the ELFv2
> version to a struct containing 'addr' element.
> 
> This allows using single helpers common to ELFv1 and ELFv2.
> 
> Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
> ---
>  arch/powerpc/kernel/module_64.c | 32 ++++++++++++++------------------
>  1 file changed, 14 insertions(+), 18 deletions(-)
> 
> diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c
> index a89da0ee25e2..b687ef88c4c4 100644
> --- a/arch/powerpc/kernel/module_64.c
> +++ b/arch/powerpc/kernel/module_64.c
> @@ -33,19 +33,13 @@
>  #ifdef PPC64_ELF_ABI_v2
>  
>  /* An address is simply the address of the function. */
> -typedef unsigned long func_desc_t;
> +typedef struct {
> +	unsigned long addr;
> +} func_desc_t;
>  
>  static func_desc_t func_desc(unsigned long addr)
>  {
> -	return addr;
> -}
> -static unsigned long func_addr(unsigned long addr)
> -{
> -	return addr;
> -}
> -static unsigned long stub_func_addr(func_desc_t func)
> -{
> -	return func;
> +	return (func_desc_t){addr};

There's only 1 element in the struct, so okay, but it hurt my eyes a
little. I would have been happier with:

	return (func_desc_t){ .addr = addr; };

But of course that also looks bonkers because it starts with "return".
So no matter what I do my eyes bug out. ;)

So it's fine either way. :)

Reviewed-by: Kees Cook <keescook@chromium.org>


>  }
>  
>  /* PowerPC64 specific values for the Elf64_Sym st_other field.  */
> @@ -70,14 +64,6 @@ static func_desc_t func_desc(unsigned long addr)
>  {
>  	return *(struct func_desc *)addr;
>  }
> -static unsigned long func_addr(unsigned long addr)
> -{
> -	return func_desc(addr).addr;
> -}
> -static unsigned long stub_func_addr(func_desc_t func)
> -{
> -	return func.addr;
> -}
>  static unsigned int local_entry_offset(const Elf64_Sym *sym)
>  {
>  	return 0;
> @@ -93,6 +79,16 @@ void *dereference_module_function_descriptor(struct module *mod, void *ptr)
>  }
>  #endif
>  
> +static unsigned long func_addr(unsigned long addr)
> +{
> +	return func_desc(addr).addr;
> +}
> +
> +static unsigned long stub_func_addr(func_desc_t func)
> +{
> +	return func.addr;
> +}
> +
>  #define STUB_MAGIC 0x73747562 /* stub */
>  
>  /* Like PPC32, we need little trampolines to do > 24-bit jumps (into
> -- 
> 2.31.1
> 

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 99+ messages in thread

* Re: [PATCH v3 04/12] powerpc: Prepare func_desc_t for refactorisation
@ 2022-02-11  0:54     ` Kees Cook
  0 siblings, 0 replies; 99+ messages in thread
From: Kees Cook @ 2022-02-11  0:54 UTC (permalink / raw)
  To: Christophe Leroy
  Cc: linux-arch, linux-ia64, linux-parisc, Arnd Bergmann,
	Greg Kroah-Hartman, Helge Deller, linux-kernel,
	James E.J. Bottomley, linux-mm, Paul Mackerras, Andrew Morton,
	linuxppc-dev

On Sun, Oct 17, 2021 at 02:38:17PM +0200, Christophe Leroy wrote:
> In preparation of making func_desc_t generic, change the ELFv2
> version to a struct containing 'addr' element.
> 
> This allows using single helpers common to ELFv1 and ELFv2.
> 
> Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
> ---
>  arch/powerpc/kernel/module_64.c | 32 ++++++++++++++------------------
>  1 file changed, 14 insertions(+), 18 deletions(-)
> 
> diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c
> index a89da0ee25e2..b687ef88c4c4 100644
> --- a/arch/powerpc/kernel/module_64.c
> +++ b/arch/powerpc/kernel/module_64.c
> @@ -33,19 +33,13 @@
>  #ifdef PPC64_ELF_ABI_v2
>  
>  /* An address is simply the address of the function. */
> -typedef unsigned long func_desc_t;
> +typedef struct {
> +	unsigned long addr;
> +} func_desc_t;
>  
>  static func_desc_t func_desc(unsigned long addr)
>  {
> -	return addr;
> -}
> -static unsigned long func_addr(unsigned long addr)
> -{
> -	return addr;
> -}
> -static unsigned long stub_func_addr(func_desc_t func)
> -{
> -	return func;
> +	return (func_desc_t){addr};

There's only 1 element in the struct, so okay, but it hurt my eyes a
little. I would have been happier with:

	return (func_desc_t){ .addr = addr; };

But of course that also looks bonkers because it starts with "return".
So no matter what I do my eyes bug out. ;)

So it's fine either way. :)

Reviewed-by: Kees Cook <keescook@chromium.org>


>  }
>  
>  /* PowerPC64 specific values for the Elf64_Sym st_other field.  */
> @@ -70,14 +64,6 @@ static func_desc_t func_desc(unsigned long addr)
>  {
>  	return *(struct func_desc *)addr;
>  }
> -static unsigned long func_addr(unsigned long addr)
> -{
> -	return func_desc(addr).addr;
> -}
> -static unsigned long stub_func_addr(func_desc_t func)
> -{
> -	return func.addr;
> -}
>  static unsigned int local_entry_offset(const Elf64_Sym *sym)
>  {
>  	return 0;
> @@ -93,6 +79,16 @@ void *dereference_module_function_descriptor(struct module *mod, void *ptr)
>  }
>  #endif
>  
> +static unsigned long func_addr(unsigned long addr)
> +{
> +	return func_desc(addr).addr;
> +}
> +
> +static unsigned long stub_func_addr(func_desc_t func)
> +{
> +	return func.addr;
> +}
> +
>  #define STUB_MAGIC 0x73747562 /* stub */
>  
>  /* Like PPC32, we need little trampolines to do > 24-bit jumps (into
> -- 
> 2.31.1
> 

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 99+ messages in thread

* Re: [PATCH v3 04/12] powerpc: Prepare func_desc_t for refactorisation
@ 2022-02-11  0:54     ` Kees Cook
  0 siblings, 0 replies; 99+ messages in thread
From: Kees Cook @ 2022-02-11  0:54 UTC (permalink / raw)
  To: Christophe Leroy
  Cc: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Andrew Morton, James E.J. Bottomley, Helge Deller, Arnd Bergmann,
	Greg Kroah-Hartman, linux-kernel, linuxppc-dev, linux-ia64,
	linux-parisc, linux-arch, linux-mm

On Sun, Oct 17, 2021 at 02:38:17PM +0200, Christophe Leroy wrote:
> In preparation of making func_desc_t generic, change the ELFv2
> version to a struct containing 'addr' element.
> 
> This allows using single helpers common to ELFv1 and ELFv2.
> 
> Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
> ---
>  arch/powerpc/kernel/module_64.c | 32 ++++++++++++++------------------
>  1 file changed, 14 insertions(+), 18 deletions(-)
> 
> diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c
> index a89da0ee25e2..b687ef88c4c4 100644
> --- a/arch/powerpc/kernel/module_64.c
> +++ b/arch/powerpc/kernel/module_64.c
> @@ -33,19 +33,13 @@
>  #ifdef PPC64_ELF_ABI_v2
>  
>  /* An address is simply the address of the function. */
> -typedef unsigned long func_desc_t;
> +typedef struct {
> +	unsigned long addr;
> +} func_desc_t;
>  
>  static func_desc_t func_desc(unsigned long addr)
>  {
> -	return addr;
> -}
> -static unsigned long func_addr(unsigned long addr)
> -{
> -	return addr;
> -}
> -static unsigned long stub_func_addr(func_desc_t func)
> -{
> -	return func;
> +	return (func_desc_t){addr};

There's only 1 element in the struct, so okay, but it hurt my eyes a
little. I would have been happier with:

	return (func_desc_t){ .addr = addr; };

But of course that also looks bonkers because it starts with "return".
So no matter what I do my eyes bug out. ;)

So it's fine either way. :)

Reviewed-by: Kees Cook <keescook@chromium.org>


>  }
>  
>  /* PowerPC64 specific values for the Elf64_Sym st_other field.  */
> @@ -70,14 +64,6 @@ static func_desc_t func_desc(unsigned long addr)
>  {
>  	return *(struct func_desc *)addr;
>  }
> -static unsigned long func_addr(unsigned long addr)
> -{
> -	return func_desc(addr).addr;
> -}
> -static unsigned long stub_func_addr(func_desc_t func)
> -{
> -	return func.addr;
> -}
>  static unsigned int local_entry_offset(const Elf64_Sym *sym)
>  {
>  	return 0;
> @@ -93,6 +79,16 @@ void *dereference_module_function_descriptor(struct module *mod, void *ptr)
>  }
>  #endif
>  
> +static unsigned long func_addr(unsigned long addr)
> +{
> +	return func_desc(addr).addr;
> +}
> +
> +static unsigned long stub_func_addr(func_desc_t func)
> +{
> +	return func.addr;
> +}
> +
>  #define STUB_MAGIC 0x73747562 /* stub */
>  
>  /* Like PPC32, we need little trampolines to do > 24-bit jumps (into
> -- 
> 2.31.1
> 

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 99+ messages in thread

* Re: [PATCH v3 08/12] asm-generic: Refactor dereference_[kernel]_function_descriptor()
  2022-02-10 10:30     ` Michael Ellerman
  (?)
@ 2022-02-11  0:56       ` Kees Cook
  -1 siblings, 0 replies; 99+ messages in thread
From: Kees Cook @ 2022-02-11  0:56 UTC (permalink / raw)
  To: Michael Ellerman
  Cc: Christophe Leroy, Benjamin Herrenschmidt, Paul Mackerras,
	Andrew Morton, James E.J. Bottomley, Helge Deller, Arnd Bergmann,
	Greg Kroah-Hartman, linux-kernel, linuxppc-dev, linux-ia64,
	linux-parisc, linux-arch, linux-mm

On Thu, Feb 10, 2022 at 09:30:43PM +1100, Michael Ellerman wrote:
> Christophe Leroy <christophe.leroy@csgroup.eu> writes:
> > diff --git a/kernel/extable.c b/kernel/extable.c
> > index b0ea5eb0c3b4..1ef13789bea9 100644
> > --- a/kernel/extable.c
> > +++ b/kernel/extable.c
> > @@ -159,12 +160,32 @@ int kernel_text_address(unsigned long addr)
> >  }
> >  
> >  /*
> > - * On some architectures (PPC64, IA64) function pointers
> > + * On some architectures (PPC64, IA64, PARISC) function pointers
> >   * are actually only tokens to some data that then holds the
> >   * real function address. As a result, to find if a function
> >   * pointer is part of the kernel text, we need to do some
> >   * special dereferencing first.
> >   */
> > +#ifdef CONFIG_HAVE_FUNCTION_DESCRIPTORS
> > +void *dereference_function_descriptor(void *ptr)
> > +{
> > +	func_desc_t *desc = ptr;
> > +	void *p;
> > +
> > +	if (!get_kernel_nofault(p, (void *)&desc->addr))
> > +		ptr = p;
> > +	return ptr;
> > +}
> 
> This needs an EXPORT_SYMBOL_GPL(), otherwise the build breaks after
> patch 10 with CONFIG_LKDTM=m.

Oh good catch!

(There have been a few cases of LKDTM=m being the only thing needed a
symbol, so I've pondered giving it a namespace or constructing a little
ifdef wrapper... but this seems ok to export...)

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 99+ messages in thread

* Re: [PATCH v3 08/12] asm-generic: Refactor dereference_[kernel]_function_descriptor()
@ 2022-02-11  0:56       ` Kees Cook
  0 siblings, 0 replies; 99+ messages in thread
From: Kees Cook @ 2022-02-11  0:56 UTC (permalink / raw)
  To: Michael Ellerman
  Cc: linux-arch, linux-ia64, linux-parisc, Arnd Bergmann,
	Helge Deller, linux-kernel, James E.J. Bottomley, linux-mm,
	Paul Mackerras, Greg Kroah-Hartman, Andrew Morton, linuxppc-dev

On Thu, Feb 10, 2022 at 09:30:43PM +1100, Michael Ellerman wrote:
> Christophe Leroy <christophe.leroy@csgroup.eu> writes:
> > diff --git a/kernel/extable.c b/kernel/extable.c
> > index b0ea5eb0c3b4..1ef13789bea9 100644
> > --- a/kernel/extable.c
> > +++ b/kernel/extable.c
> > @@ -159,12 +160,32 @@ int kernel_text_address(unsigned long addr)
> >  }
> >  
> >  /*
> > - * On some architectures (PPC64, IA64) function pointers
> > + * On some architectures (PPC64, IA64, PARISC) function pointers
> >   * are actually only tokens to some data that then holds the
> >   * real function address. As a result, to find if a function
> >   * pointer is part of the kernel text, we need to do some
> >   * special dereferencing first.
> >   */
> > +#ifdef CONFIG_HAVE_FUNCTION_DESCRIPTORS
> > +void *dereference_function_descriptor(void *ptr)
> > +{
> > +	func_desc_t *desc = ptr;
> > +	void *p;
> > +
> > +	if (!get_kernel_nofault(p, (void *)&desc->addr))
> > +		ptr = p;
> > +	return ptr;
> > +}
> 
> This needs an EXPORT_SYMBOL_GPL(), otherwise the build breaks after
> patch 10 with CONFIG_LKDTM=m.

Oh good catch!

(There have been a few cases of LKDTM=m being the only thing needed a
symbol, so I've pondered giving it a namespace or constructing a little
ifdef wrapper... but this seems ok to export...)

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 99+ messages in thread

* Re: [PATCH v3 08/12] asm-generic: Refactor dereference_[kernel]_function_descriptor()
@ 2022-02-11  0:56       ` Kees Cook
  0 siblings, 0 replies; 99+ messages in thread
From: Kees Cook @ 2022-02-11  0:56 UTC (permalink / raw)
  To: Michael Ellerman
  Cc: Christophe Leroy, Benjamin Herrenschmidt, Paul Mackerras,
	Andrew Morton, James E.J. Bottomley, Helge Deller, Arnd Bergmann,
	Greg Kroah-Hartman, linux-kernel, linuxppc-dev, linux-ia64,
	linux-parisc, linux-arch, linux-mm

On Thu, Feb 10, 2022 at 09:30:43PM +1100, Michael Ellerman wrote:
> Christophe Leroy <christophe.leroy@csgroup.eu> writes:
> > diff --git a/kernel/extable.c b/kernel/extable.c
> > index b0ea5eb0c3b4..1ef13789bea9 100644
> > --- a/kernel/extable.c
> > +++ b/kernel/extable.c
> > @@ -159,12 +160,32 @@ int kernel_text_address(unsigned long addr)
> >  }
> >  
> >  /*
> > - * On some architectures (PPC64, IA64) function pointers
> > + * On some architectures (PPC64, IA64, PARISC) function pointers
> >   * are actually only tokens to some data that then holds the
> >   * real function address. As a result, to find if a function
> >   * pointer is part of the kernel text, we need to do some
> >   * special dereferencing first.
> >   */
> > +#ifdef CONFIG_HAVE_FUNCTION_DESCRIPTORS
> > +void *dereference_function_descriptor(void *ptr)
> > +{
> > +	func_desc_t *desc = ptr;
> > +	void *p;
> > +
> > +	if (!get_kernel_nofault(p, (void *)&desc->addr))
> > +		ptr = p;
> > +	return ptr;
> > +}
> 
> This needs an EXPORT_SYMBOL_GPL(), otherwise the build breaks after
> patch 10 with CONFIG_LKDTM=m.

Oh good catch!

(There have been a few cases of LKDTM=m being the only thing needed a
symbol, so I've pondered giving it a namespace or constructing a little
ifdef wrapper... but this seems ok to export...)

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 99+ messages in thread

* Re: [PATCH v3 11/12] lkdtm: Fix execute_[user]_location()
  2021-10-17 12:38   ` Christophe Leroy
  (?)
@ 2022-02-11  1:01     ` Kees Cook
  -1 siblings, 0 replies; 99+ messages in thread
From: Kees Cook @ 2022-02-11  1:01 UTC (permalink / raw)
  To: Christophe Leroy
  Cc: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Andrew Morton, James E.J. Bottomley, Helge Deller, Arnd Bergmann,
	Greg Kroah-Hartman, linux-kernel, linuxppc-dev, linux-ia64,
	linux-parisc, linux-arch, linux-mm

On Sun, Oct 17, 2021 at 02:38:24PM +0200, Christophe Leroy wrote:
> execute_location() and execute_user_location() intent
> to copy do_nothing() text and execute it at a new location.
> However, at the time being it doesn't copy do_nothing() function
> but do_nothing() function descriptor which still points to the
> original text. So at the end it still executes do_nothing() at
> its original location allthough using a copied function descriptor.
> 
> So, fix that by really copying do_nothing() text and build a new
> function descriptor by copying do_nothing() function descriptor and
> updating the target address with the new location.
> 
> Also fix the displayed addresses by dereferencing do_nothing()
> function descriptor.
> 
> Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>

This looks good. I might rename variables in the future (e.g. to avoid
the churn from adding _text) but also, that does help keep it clear. :)

Acked-by: Kees Cook <keescook@chromium.org>

-Kees

> ---
>  drivers/misc/lkdtm/perms.c | 37 ++++++++++++++++++++++++++++---------
>  1 file changed, 28 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/misc/lkdtm/perms.c b/drivers/misc/lkdtm/perms.c
> index 035fcca441f0..1cf24c4a79e9 100644
> --- a/drivers/misc/lkdtm/perms.c
> +++ b/drivers/misc/lkdtm/perms.c
> @@ -44,19 +44,34 @@ static noinline void do_overwritten(void)
>  	return;
>  }
>  
> +static void *setup_function_descriptor(func_desc_t *fdesc, void *dst)
> +{
> +	if (!have_function_descriptors())
> +		return dst;
> +
> +	memcpy(fdesc, do_nothing, sizeof(*fdesc));
> +	fdesc->addr = (unsigned long)dst;
> +	barrier();
> +
> +	return fdesc;
> +}
> +
>  static noinline void execute_location(void *dst, bool write)
>  {
> -	void (*func)(void) = dst;
> +	void (*func)(void);
> +	func_desc_t fdesc;
> +	void *do_nothing_text = dereference_function_descriptor(do_nothing);
>  
> -	pr_info("attempting ok execution at %px\n", do_nothing);
> +	pr_info("attempting ok execution at %px\n", do_nothing_text);
>  	do_nothing();
>  
>  	if (write == CODE_WRITE) {
> -		memcpy(dst, do_nothing, EXEC_SIZE);
> +		memcpy(dst, do_nothing_text, EXEC_SIZE);
>  		flush_icache_range((unsigned long)dst,
>  				   (unsigned long)dst + EXEC_SIZE);
>  	}
> -	pr_info("attempting bad execution at %px\n", func);
> +	pr_info("attempting bad execution at %px\n", dst);
> +	func = setup_function_descriptor(&fdesc, dst);
>  	func();
>  	pr_err("FAIL: func returned\n");
>  }
> @@ -66,16 +81,19 @@ static void execute_user_location(void *dst)
>  	int copied;
>  
>  	/* Intentionally crossing kernel/user memory boundary. */
> -	void (*func)(void) = dst;
> +	void (*func)(void);
> +	func_desc_t fdesc;
> +	void *do_nothing_text = dereference_function_descriptor(do_nothing);
>  
> -	pr_info("attempting ok execution at %px\n", do_nothing);
> +	pr_info("attempting ok execution at %px\n", do_nothing_text);
>  	do_nothing();
>  
> -	copied = access_process_vm(current, (unsigned long)dst, do_nothing,
> +	copied = access_process_vm(current, (unsigned long)dst, do_nothing_text,
>  				   EXEC_SIZE, FOLL_WRITE);
>  	if (copied < EXEC_SIZE)
>  		return;
> -	pr_info("attempting bad execution at %px\n", func);
> +	pr_info("attempting bad execution at %px\n", dst);
> +	func = setup_function_descriptor(&fdesc, dst);
>  	func();
>  	pr_err("FAIL: func returned\n");
>  }
> @@ -153,7 +171,8 @@ void lkdtm_EXEC_VMALLOC(void)
>  
>  void lkdtm_EXEC_RODATA(void)
>  {
> -	execute_location(lkdtm_rodata_do_nothing, CODE_AS_IS);
> +	execute_location(dereference_function_descriptor(lkdtm_rodata_do_nothing),
> +			 CODE_AS_IS);
>  }
>  
>  void lkdtm_EXEC_USERSPACE(void)
> -- 
> 2.31.1
> 

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 99+ messages in thread

* Re: [PATCH v3 11/12] lkdtm: Fix execute_[user]_location()
@ 2022-02-11  1:01     ` Kees Cook
  0 siblings, 0 replies; 99+ messages in thread
From: Kees Cook @ 2022-02-11  1:01 UTC (permalink / raw)
  To: Christophe Leroy
  Cc: linux-arch, linux-ia64, linux-parisc, Arnd Bergmann,
	Greg Kroah-Hartman, Helge Deller, linux-kernel,
	James E.J. Bottomley, linux-mm, Paul Mackerras, Andrew Morton,
	linuxppc-dev

On Sun, Oct 17, 2021 at 02:38:24PM +0200, Christophe Leroy wrote:
> execute_location() and execute_user_location() intent
> to copy do_nothing() text and execute it at a new location.
> However, at the time being it doesn't copy do_nothing() function
> but do_nothing() function descriptor which still points to the
> original text. So at the end it still executes do_nothing() at
> its original location allthough using a copied function descriptor.
> 
> So, fix that by really copying do_nothing() text and build a new
> function descriptor by copying do_nothing() function descriptor and
> updating the target address with the new location.
> 
> Also fix the displayed addresses by dereferencing do_nothing()
> function descriptor.
> 
> Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>

This looks good. I might rename variables in the future (e.g. to avoid
the churn from adding _text) but also, that does help keep it clear. :)

Acked-by: Kees Cook <keescook@chromium.org>

-Kees

> ---
>  drivers/misc/lkdtm/perms.c | 37 ++++++++++++++++++++++++++++---------
>  1 file changed, 28 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/misc/lkdtm/perms.c b/drivers/misc/lkdtm/perms.c
> index 035fcca441f0..1cf24c4a79e9 100644
> --- a/drivers/misc/lkdtm/perms.c
> +++ b/drivers/misc/lkdtm/perms.c
> @@ -44,19 +44,34 @@ static noinline void do_overwritten(void)
>  	return;
>  }
>  
> +static void *setup_function_descriptor(func_desc_t *fdesc, void *dst)
> +{
> +	if (!have_function_descriptors())
> +		return dst;
> +
> +	memcpy(fdesc, do_nothing, sizeof(*fdesc));
> +	fdesc->addr = (unsigned long)dst;
> +	barrier();
> +
> +	return fdesc;
> +}
> +
>  static noinline void execute_location(void *dst, bool write)
>  {
> -	void (*func)(void) = dst;
> +	void (*func)(void);
> +	func_desc_t fdesc;
> +	void *do_nothing_text = dereference_function_descriptor(do_nothing);
>  
> -	pr_info("attempting ok execution at %px\n", do_nothing);
> +	pr_info("attempting ok execution at %px\n", do_nothing_text);
>  	do_nothing();
>  
>  	if (write == CODE_WRITE) {
> -		memcpy(dst, do_nothing, EXEC_SIZE);
> +		memcpy(dst, do_nothing_text, EXEC_SIZE);
>  		flush_icache_range((unsigned long)dst,
>  				   (unsigned long)dst + EXEC_SIZE);
>  	}
> -	pr_info("attempting bad execution at %px\n", func);
> +	pr_info("attempting bad execution at %px\n", dst);
> +	func = setup_function_descriptor(&fdesc, dst);
>  	func();
>  	pr_err("FAIL: func returned\n");
>  }
> @@ -66,16 +81,19 @@ static void execute_user_location(void *dst)
>  	int copied;
>  
>  	/* Intentionally crossing kernel/user memory boundary. */
> -	void (*func)(void) = dst;
> +	void (*func)(void);
> +	func_desc_t fdesc;
> +	void *do_nothing_text = dereference_function_descriptor(do_nothing);
>  
> -	pr_info("attempting ok execution at %px\n", do_nothing);
> +	pr_info("attempting ok execution at %px\n", do_nothing_text);
>  	do_nothing();
>  
> -	copied = access_process_vm(current, (unsigned long)dst, do_nothing,
> +	copied = access_process_vm(current, (unsigned long)dst, do_nothing_text,
>  				   EXEC_SIZE, FOLL_WRITE);
>  	if (copied < EXEC_SIZE)
>  		return;
> -	pr_info("attempting bad execution at %px\n", func);
> +	pr_info("attempting bad execution at %px\n", dst);
> +	func = setup_function_descriptor(&fdesc, dst);
>  	func();
>  	pr_err("FAIL: func returned\n");
>  }
> @@ -153,7 +171,8 @@ void lkdtm_EXEC_VMALLOC(void)
>  
>  void lkdtm_EXEC_RODATA(void)
>  {
> -	execute_location(lkdtm_rodata_do_nothing, CODE_AS_IS);
> +	execute_location(dereference_function_descriptor(lkdtm_rodata_do_nothing),
> +			 CODE_AS_IS);
>  }
>  
>  void lkdtm_EXEC_USERSPACE(void)
> -- 
> 2.31.1
> 

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 99+ messages in thread

* Re: [PATCH v3 11/12] lkdtm: Fix execute_[user]_location()
@ 2022-02-11  1:01     ` Kees Cook
  0 siblings, 0 replies; 99+ messages in thread
From: Kees Cook @ 2022-02-11  1:01 UTC (permalink / raw)
  To: Christophe Leroy
  Cc: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Andrew Morton, James E.J. Bottomley, Helge Deller, Arnd Bergmann,
	Greg Kroah-Hartman, linux-kernel, linuxppc-dev, linux-ia64,
	linux-parisc, linux-arch, linux-mm

On Sun, Oct 17, 2021 at 02:38:24PM +0200, Christophe Leroy wrote:
> execute_location() and execute_user_location() intent
> to copy do_nothing() text and execute it at a new location.
> However, at the time being it doesn't copy do_nothing() function
> but do_nothing() function descriptor which still points to the
> original text. So at the end it still executes do_nothing() at
> its original location allthough using a copied function descriptor.
> 
> So, fix that by really copying do_nothing() text and build a new
> function descriptor by copying do_nothing() function descriptor and
> updating the target address with the new location.
> 
> Also fix the displayed addresses by dereferencing do_nothing()
> function descriptor.
> 
> Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>

This looks good. I might rename variables in the future (e.g. to avoid
the churn from adding _text) but also, that does help keep it clear. :)

Acked-by: Kees Cook <keescook@chromium.org>

-Kees

> ---
>  drivers/misc/lkdtm/perms.c | 37 ++++++++++++++++++++++++++++---------
>  1 file changed, 28 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/misc/lkdtm/perms.c b/drivers/misc/lkdtm/perms.c
> index 035fcca441f0..1cf24c4a79e9 100644
> --- a/drivers/misc/lkdtm/perms.c
> +++ b/drivers/misc/lkdtm/perms.c
> @@ -44,19 +44,34 @@ static noinline void do_overwritten(void)
>  	return;
>  }
>  
> +static void *setup_function_descriptor(func_desc_t *fdesc, void *dst)
> +{
> +	if (!have_function_descriptors())
> +		return dst;
> +
> +	memcpy(fdesc, do_nothing, sizeof(*fdesc));
> +	fdesc->addr = (unsigned long)dst;
> +	barrier();
> +
> +	return fdesc;
> +}
> +
>  static noinline void execute_location(void *dst, bool write)
>  {
> -	void (*func)(void) = dst;
> +	void (*func)(void);
> +	func_desc_t fdesc;
> +	void *do_nothing_text = dereference_function_descriptor(do_nothing);
>  
> -	pr_info("attempting ok execution at %px\n", do_nothing);
> +	pr_info("attempting ok execution at %px\n", do_nothing_text);
>  	do_nothing();
>  
>  	if (write = CODE_WRITE) {
> -		memcpy(dst, do_nothing, EXEC_SIZE);
> +		memcpy(dst, do_nothing_text, EXEC_SIZE);
>  		flush_icache_range((unsigned long)dst,
>  				   (unsigned long)dst + EXEC_SIZE);
>  	}
> -	pr_info("attempting bad execution at %px\n", func);
> +	pr_info("attempting bad execution at %px\n", dst);
> +	func = setup_function_descriptor(&fdesc, dst);
>  	func();
>  	pr_err("FAIL: func returned\n");
>  }
> @@ -66,16 +81,19 @@ static void execute_user_location(void *dst)
>  	int copied;
>  
>  	/* Intentionally crossing kernel/user memory boundary. */
> -	void (*func)(void) = dst;
> +	void (*func)(void);
> +	func_desc_t fdesc;
> +	void *do_nothing_text = dereference_function_descriptor(do_nothing);
>  
> -	pr_info("attempting ok execution at %px\n", do_nothing);
> +	pr_info("attempting ok execution at %px\n", do_nothing_text);
>  	do_nothing();
>  
> -	copied = access_process_vm(current, (unsigned long)dst, do_nothing,
> +	copied = access_process_vm(current, (unsigned long)dst, do_nothing_text,
>  				   EXEC_SIZE, FOLL_WRITE);
>  	if (copied < EXEC_SIZE)
>  		return;
> -	pr_info("attempting bad execution at %px\n", func);
> +	pr_info("attempting bad execution at %px\n", dst);
> +	func = setup_function_descriptor(&fdesc, dst);
>  	func();
>  	pr_err("FAIL: func returned\n");
>  }
> @@ -153,7 +171,8 @@ void lkdtm_EXEC_VMALLOC(void)
>  
>  void lkdtm_EXEC_RODATA(void)
>  {
> -	execute_location(lkdtm_rodata_do_nothing, CODE_AS_IS);
> +	execute_location(dereference_function_descriptor(lkdtm_rodata_do_nothing),
> +			 CODE_AS_IS);
>  }
>  
>  void lkdtm_EXEC_USERSPACE(void)
> -- 
> 2.31.1
> 

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 99+ messages in thread

* Re: [PATCH v3 12/12] lkdtm: Add a test for function descriptors protection
  2021-10-17 12:38   ` Christophe Leroy
  (?)
@ 2022-02-11  1:09     ` Kees Cook
  -1 siblings, 0 replies; 99+ messages in thread
From: Kees Cook @ 2022-02-11  1:09 UTC (permalink / raw)
  To: Christophe Leroy
  Cc: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Andrew Morton, James E.J. Bottomley, Helge Deller, Arnd Bergmann,
	Greg Kroah-Hartman, linux-kernel, linuxppc-dev, linux-ia64,
	linux-parisc, linux-arch, linux-mm

On Sun, Oct 17, 2021 at 02:38:25PM +0200, Christophe Leroy wrote:
> Add WRITE_OPD to check that you can't modify function
> descriptors.
> 
> Gives the following result when function descriptors are
> not protected:
> 
> 	lkdtm: Performing direct entry WRITE_OPD
> 	lkdtm: attempting bad 16 bytes write at c00000000269b358
> 	lkdtm: FAIL: survived bad write
> 	lkdtm: do_nothing was hijacked!
> 
> Looks like a standard compiler barrier() is not enough to force
> GCC to use the modified function descriptor. Had to add a fake empty
> inline assembly to force GCC to reload the function descriptor.
> 
> Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
> ---
>  drivers/misc/lkdtm/core.c  |  1 +
>  drivers/misc/lkdtm/lkdtm.h |  1 +
>  drivers/misc/lkdtm/perms.c | 22 ++++++++++++++++++++++
>  3 files changed, 24 insertions(+)
> 
> diff --git a/drivers/misc/lkdtm/core.c b/drivers/misc/lkdtm/core.c
> index fe6fd34b8caf..de092aa03b5d 100644
> --- a/drivers/misc/lkdtm/core.c
> +++ b/drivers/misc/lkdtm/core.c
> @@ -148,6 +148,7 @@ static const struct crashtype crashtypes[] = {
>  	CRASHTYPE(WRITE_RO),
>  	CRASHTYPE(WRITE_RO_AFTER_INIT),
>  	CRASHTYPE(WRITE_KERN),
> +	CRASHTYPE(WRITE_OPD),
>  	CRASHTYPE(REFCOUNT_INC_OVERFLOW),
>  	CRASHTYPE(REFCOUNT_ADD_OVERFLOW),
>  	CRASHTYPE(REFCOUNT_INC_NOT_ZERO_OVERFLOW),
> diff --git a/drivers/misc/lkdtm/lkdtm.h b/drivers/misc/lkdtm/lkdtm.h
> index c212a253edde..188bd0fd6575 100644
> --- a/drivers/misc/lkdtm/lkdtm.h
> +++ b/drivers/misc/lkdtm/lkdtm.h
> @@ -105,6 +105,7 @@ void __init lkdtm_perms_init(void);
>  void lkdtm_WRITE_RO(void);
>  void lkdtm_WRITE_RO_AFTER_INIT(void);
>  void lkdtm_WRITE_KERN(void);
> +void lkdtm_WRITE_OPD(void);
>  void lkdtm_EXEC_DATA(void);
>  void lkdtm_EXEC_STACK(void);
>  void lkdtm_EXEC_KMALLOC(void);
> diff --git a/drivers/misc/lkdtm/perms.c b/drivers/misc/lkdtm/perms.c
> index 1cf24c4a79e9..2c6aba3ff32b 100644
> --- a/drivers/misc/lkdtm/perms.c
> +++ b/drivers/misc/lkdtm/perms.c
> @@ -44,6 +44,11 @@ static noinline void do_overwritten(void)
>  	return;
>  }
>  
> +static noinline void do_almost_nothing(void)
> +{
> +	pr_info("do_nothing was hijacked!\n");
> +}
> +
>  static void *setup_function_descriptor(func_desc_t *fdesc, void *dst)
>  {
>  	if (!have_function_descriptors())
> @@ -144,6 +149,23 @@ void lkdtm_WRITE_KERN(void)
>  	do_overwritten();
>  }
>  
> +void lkdtm_WRITE_OPD(void)
> +{
> +	size_t size = sizeof(func_desc_t);
> +	void (*func)(void) = do_nothing;
> +
> +	if (!have_function_descriptors()) {
> +		pr_info("XFAIL: Platform doesn't use function descriptors.\n");
> +		return;
> +	}
> +	pr_info("attempting bad %zu bytes write at %px\n", size, do_nothing);
> +	memcpy(do_nothing, do_almost_nothing, size);
> +	pr_err("FAIL: survived bad write\n");

Non-function-descriptor architectures would successfully crash at the
memcpy too, right? (i.e. for them this is just repeating WRITE_KERN)

I'm pondering the utility of the XFAIL vs just letting is succeed, but I
think it more accurate to say "hey, no OPD" as you have it.

> +
> +	asm("" : "=m"(func));
> +	func();
> +}
> +
>  void lkdtm_EXEC_DATA(void)
>  {
>  	execute_location(data_area, CODE_WRITE);
> -- 
> 2.31.1
> 

One tiny suggestion, since I think you need to respin for the
EXPORT_SYMBOL_GPL() anyway. Please update the selftests too:

diff --git a/tools/testing/selftests/lkdtm/tests.txt b/tools/testing/selftests/lkdtm/tests.txt
index 6b36b7f5dcf9..243c781f0780 100644
--- a/tools/testing/selftests/lkdtm/tests.txt
+++ b/tools/testing/selftests/lkdtm/tests.txt
@@ -44,6 +44,7 @@ ACCESS_NULL
 WRITE_RO
 WRITE_RO_AFTER_INIT
 WRITE_KERN
+WRITE_OPD
 REFCOUNT_INC_OVERFLOW
 REFCOUNT_ADD_OVERFLOW
 REFCOUNT_INC_NOT_ZERO_OVERFLOW

(Though for the future I've been considering making the selftests an
opt-out list so the "normal" stuff doesn't need to keep getting added
there.)

Thanks!

Acked-by: Kees Cook <keescook@chromium.org>

-Kees

-- 
Kees Cook

^ permalink raw reply related	[flat|nested] 99+ messages in thread

* Re: [PATCH v3 12/12] lkdtm: Add a test for function descriptors protection
@ 2022-02-11  1:09     ` Kees Cook
  0 siblings, 0 replies; 99+ messages in thread
From: Kees Cook @ 2022-02-11  1:09 UTC (permalink / raw)
  To: Christophe Leroy
  Cc: linux-arch, linux-ia64, linux-parisc, Arnd Bergmann,
	Greg Kroah-Hartman, Helge Deller, linux-kernel,
	James E.J. Bottomley, linux-mm, Paul Mackerras, Andrew Morton,
	linuxppc-dev

On Sun, Oct 17, 2021 at 02:38:25PM +0200, Christophe Leroy wrote:
> Add WRITE_OPD to check that you can't modify function
> descriptors.
> 
> Gives the following result when function descriptors are
> not protected:
> 
> 	lkdtm: Performing direct entry WRITE_OPD
> 	lkdtm: attempting bad 16 bytes write at c00000000269b358
> 	lkdtm: FAIL: survived bad write
> 	lkdtm: do_nothing was hijacked!
> 
> Looks like a standard compiler barrier() is not enough to force
> GCC to use the modified function descriptor. Had to add a fake empty
> inline assembly to force GCC to reload the function descriptor.
> 
> Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
> ---
>  drivers/misc/lkdtm/core.c  |  1 +
>  drivers/misc/lkdtm/lkdtm.h |  1 +
>  drivers/misc/lkdtm/perms.c | 22 ++++++++++++++++++++++
>  3 files changed, 24 insertions(+)
> 
> diff --git a/drivers/misc/lkdtm/core.c b/drivers/misc/lkdtm/core.c
> index fe6fd34b8caf..de092aa03b5d 100644
> --- a/drivers/misc/lkdtm/core.c
> +++ b/drivers/misc/lkdtm/core.c
> @@ -148,6 +148,7 @@ static const struct crashtype crashtypes[] = {
>  	CRASHTYPE(WRITE_RO),
>  	CRASHTYPE(WRITE_RO_AFTER_INIT),
>  	CRASHTYPE(WRITE_KERN),
> +	CRASHTYPE(WRITE_OPD),
>  	CRASHTYPE(REFCOUNT_INC_OVERFLOW),
>  	CRASHTYPE(REFCOUNT_ADD_OVERFLOW),
>  	CRASHTYPE(REFCOUNT_INC_NOT_ZERO_OVERFLOW),
> diff --git a/drivers/misc/lkdtm/lkdtm.h b/drivers/misc/lkdtm/lkdtm.h
> index c212a253edde..188bd0fd6575 100644
> --- a/drivers/misc/lkdtm/lkdtm.h
> +++ b/drivers/misc/lkdtm/lkdtm.h
> @@ -105,6 +105,7 @@ void __init lkdtm_perms_init(void);
>  void lkdtm_WRITE_RO(void);
>  void lkdtm_WRITE_RO_AFTER_INIT(void);
>  void lkdtm_WRITE_KERN(void);
> +void lkdtm_WRITE_OPD(void);
>  void lkdtm_EXEC_DATA(void);
>  void lkdtm_EXEC_STACK(void);
>  void lkdtm_EXEC_KMALLOC(void);
> diff --git a/drivers/misc/lkdtm/perms.c b/drivers/misc/lkdtm/perms.c
> index 1cf24c4a79e9..2c6aba3ff32b 100644
> --- a/drivers/misc/lkdtm/perms.c
> +++ b/drivers/misc/lkdtm/perms.c
> @@ -44,6 +44,11 @@ static noinline void do_overwritten(void)
>  	return;
>  }
>  
> +static noinline void do_almost_nothing(void)
> +{
> +	pr_info("do_nothing was hijacked!\n");
> +}
> +
>  static void *setup_function_descriptor(func_desc_t *fdesc, void *dst)
>  {
>  	if (!have_function_descriptors())
> @@ -144,6 +149,23 @@ void lkdtm_WRITE_KERN(void)
>  	do_overwritten();
>  }
>  
> +void lkdtm_WRITE_OPD(void)
> +{
> +	size_t size = sizeof(func_desc_t);
> +	void (*func)(void) = do_nothing;
> +
> +	if (!have_function_descriptors()) {
> +		pr_info("XFAIL: Platform doesn't use function descriptors.\n");
> +		return;
> +	}
> +	pr_info("attempting bad %zu bytes write at %px\n", size, do_nothing);
> +	memcpy(do_nothing, do_almost_nothing, size);
> +	pr_err("FAIL: survived bad write\n");

Non-function-descriptor architectures would successfully crash at the
memcpy too, right? (i.e. for them this is just repeating WRITE_KERN)

I'm pondering the utility of the XFAIL vs just letting is succeed, but I
think it more accurate to say "hey, no OPD" as you have it.

> +
> +	asm("" : "=m"(func));
> +	func();
> +}
> +
>  void lkdtm_EXEC_DATA(void)
>  {
>  	execute_location(data_area, CODE_WRITE);
> -- 
> 2.31.1
> 

One tiny suggestion, since I think you need to respin for the
EXPORT_SYMBOL_GPL() anyway. Please update the selftests too:

diff --git a/tools/testing/selftests/lkdtm/tests.txt b/tools/testing/selftests/lkdtm/tests.txt
index 6b36b7f5dcf9..243c781f0780 100644
--- a/tools/testing/selftests/lkdtm/tests.txt
+++ b/tools/testing/selftests/lkdtm/tests.txt
@@ -44,6 +44,7 @@ ACCESS_NULL
 WRITE_RO
 WRITE_RO_AFTER_INIT
 WRITE_KERN
+WRITE_OPD
 REFCOUNT_INC_OVERFLOW
 REFCOUNT_ADD_OVERFLOW
 REFCOUNT_INC_NOT_ZERO_OVERFLOW

(Though for the future I've been considering making the selftests an
opt-out list so the "normal" stuff doesn't need to keep getting added
there.)

Thanks!

Acked-by: Kees Cook <keescook@chromium.org>

-Kees

-- 
Kees Cook

^ permalink raw reply related	[flat|nested] 99+ messages in thread

* Re: [PATCH v3 12/12] lkdtm: Add a test for function descriptors protection
@ 2022-02-11  1:09     ` Kees Cook
  0 siblings, 0 replies; 99+ messages in thread
From: Kees Cook @ 2022-02-11  1:09 UTC (permalink / raw)
  To: Christophe Leroy
  Cc: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Andrew Morton, James E.J. Bottomley, Helge Deller, Arnd Bergmann,
	Greg Kroah-Hartman, linux-kernel, linuxppc-dev, linux-ia64,
	linux-parisc, linux-arch, linux-mm

On Sun, Oct 17, 2021 at 02:38:25PM +0200, Christophe Leroy wrote:
> Add WRITE_OPD to check that you can't modify function
> descriptors.
> 
> Gives the following result when function descriptors are
> not protected:
> 
> 	lkdtm: Performing direct entry WRITE_OPD
> 	lkdtm: attempting bad 16 bytes write at c00000000269b358
> 	lkdtm: FAIL: survived bad write
> 	lkdtm: do_nothing was hijacked!
> 
> Looks like a standard compiler barrier() is not enough to force
> GCC to use the modified function descriptor. Had to add a fake empty
> inline assembly to force GCC to reload the function descriptor.
> 
> Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
> ---
>  drivers/misc/lkdtm/core.c  |  1 +
>  drivers/misc/lkdtm/lkdtm.h |  1 +
>  drivers/misc/lkdtm/perms.c | 22 ++++++++++++++++++++++
>  3 files changed, 24 insertions(+)
> 
> diff --git a/drivers/misc/lkdtm/core.c b/drivers/misc/lkdtm/core.c
> index fe6fd34b8caf..de092aa03b5d 100644
> --- a/drivers/misc/lkdtm/core.c
> +++ b/drivers/misc/lkdtm/core.c
> @@ -148,6 +148,7 @@ static const struct crashtype crashtypes[] = {
>  	CRASHTYPE(WRITE_RO),
>  	CRASHTYPE(WRITE_RO_AFTER_INIT),
>  	CRASHTYPE(WRITE_KERN),
> +	CRASHTYPE(WRITE_OPD),
>  	CRASHTYPE(REFCOUNT_INC_OVERFLOW),
>  	CRASHTYPE(REFCOUNT_ADD_OVERFLOW),
>  	CRASHTYPE(REFCOUNT_INC_NOT_ZERO_OVERFLOW),
> diff --git a/drivers/misc/lkdtm/lkdtm.h b/drivers/misc/lkdtm/lkdtm.h
> index c212a253edde..188bd0fd6575 100644
> --- a/drivers/misc/lkdtm/lkdtm.h
> +++ b/drivers/misc/lkdtm/lkdtm.h
> @@ -105,6 +105,7 @@ void __init lkdtm_perms_init(void);
>  void lkdtm_WRITE_RO(void);
>  void lkdtm_WRITE_RO_AFTER_INIT(void);
>  void lkdtm_WRITE_KERN(void);
> +void lkdtm_WRITE_OPD(void);
>  void lkdtm_EXEC_DATA(void);
>  void lkdtm_EXEC_STACK(void);
>  void lkdtm_EXEC_KMALLOC(void);
> diff --git a/drivers/misc/lkdtm/perms.c b/drivers/misc/lkdtm/perms.c
> index 1cf24c4a79e9..2c6aba3ff32b 100644
> --- a/drivers/misc/lkdtm/perms.c
> +++ b/drivers/misc/lkdtm/perms.c
> @@ -44,6 +44,11 @@ static noinline void do_overwritten(void)
>  	return;
>  }
>  
> +static noinline void do_almost_nothing(void)
> +{
> +	pr_info("do_nothing was hijacked!\n");
> +}
> +
>  static void *setup_function_descriptor(func_desc_t *fdesc, void *dst)
>  {
>  	if (!have_function_descriptors())
> @@ -144,6 +149,23 @@ void lkdtm_WRITE_KERN(void)
>  	do_overwritten();
>  }
>  
> +void lkdtm_WRITE_OPD(void)
> +{
> +	size_t size = sizeof(func_desc_t);
> +	void (*func)(void) = do_nothing;
> +
> +	if (!have_function_descriptors()) {
> +		pr_info("XFAIL: Platform doesn't use function descriptors.\n");
> +		return;
> +	}
> +	pr_info("attempting bad %zu bytes write at %px\n", size, do_nothing);
> +	memcpy(do_nothing, do_almost_nothing, size);
> +	pr_err("FAIL: survived bad write\n");

Non-function-descriptor architectures would successfully crash at the
memcpy too, right? (i.e. for them this is just repeating WRITE_KERN)

I'm pondering the utility of the XFAIL vs just letting is succeed, but I
think it more accurate to say "hey, no OPD" as you have it.

> +
> +	asm("" : "=m"(func));
> +	func();
> +}
> +
>  void lkdtm_EXEC_DATA(void)
>  {
>  	execute_location(data_area, CODE_WRITE);
> -- 
> 2.31.1
> 

One tiny suggestion, since I think you need to respin for the
EXPORT_SYMBOL_GPL() anyway. Please update the selftests too:

diff --git a/tools/testing/selftests/lkdtm/tests.txt b/tools/testing/selftests/lkdtm/tests.txt
index 6b36b7f5dcf9..243c781f0780 100644
--- a/tools/testing/selftests/lkdtm/tests.txt
+++ b/tools/testing/selftests/lkdtm/tests.txt
@@ -44,6 +44,7 @@ ACCESS_NULL
 WRITE_RO
 WRITE_RO_AFTER_INIT
 WRITE_KERN
+WRITE_OPD
 REFCOUNT_INC_OVERFLOW
 REFCOUNT_ADD_OVERFLOW
 REFCOUNT_INC_NOT_ZERO_OVERFLOW

(Though for the future I've been considering making the selftests an
opt-out list so the "normal" stuff doesn't need to keep getting added
there.)

Thanks!

Acked-by: Kees Cook <keescook@chromium.org>

-Kees

-- 
Kees Cook

^ permalink raw reply related	[flat|nested] 99+ messages in thread

* Re: [PATCH v3 04/12] powerpc: Prepare func_desc_t for refactorisation
  2022-02-11  0:54     ` Kees Cook
  (?)
@ 2022-02-11  7:39       ` Segher Boessenkool
  -1 siblings, 0 replies; 99+ messages in thread
From: Segher Boessenkool @ 2022-02-11  7:39 UTC (permalink / raw)
  To: Kees Cook
  Cc: Christophe Leroy, linux-arch, linux-ia64, linux-parisc,
	Arnd Bergmann, Greg Kroah-Hartman, Helge Deller, linux-kernel,
	James E.J. Bottomley, linux-mm, Paul Mackerras, Andrew Morton,
	linuxppc-dev

On Thu, Feb 10, 2022 at 04:54:52PM -0800, Kees Cook wrote:
> On Sun, Oct 17, 2021 at 02:38:17PM +0200, Christophe Leroy wrote:
(edited:)
> > +typedef struct {
> > +	unsigned long addr;
> > +} func_desc_t;
> >  
> >  static func_desc_t func_desc(unsigned long addr)
> >  {
> > +	return (func_desc_t){addr};

> There's only 1 element in the struct, so okay, but it hurt my eyes a
> little. I would have been happier with:
> 
> 	return (func_desc_t){ .addr = addr; };
> 
> But of course that also looks bonkers because it starts with "return".
> So no matter what I do my eyes bug out. ;)

The usual way to avoid convoluted constructs is to name more factors.
So:

static func_desc_t func_desc(unsigned long addr)
{
	func_desc_t desc = {};
	desc.addr = addr;
	return desc;
}


Segher

^ permalink raw reply	[flat|nested] 99+ messages in thread

* Re: [PATCH v3 04/12] powerpc: Prepare func_desc_t for refactorisation
@ 2022-02-11  7:39       ` Segher Boessenkool
  0 siblings, 0 replies; 99+ messages in thread
From: Segher Boessenkool @ 2022-02-11  7:39 UTC (permalink / raw)
  To: Kees Cook
  Cc: linux-arch, linux-ia64, linux-parisc, Arnd Bergmann,
	Greg Kroah-Hartman, Helge Deller, linux-kernel,
	James E.J. Bottomley, linux-mm, Paul Mackerras, Andrew Morton,
	linuxppc-dev

On Thu, Feb 10, 2022 at 04:54:52PM -0800, Kees Cook wrote:
> On Sun, Oct 17, 2021 at 02:38:17PM +0200, Christophe Leroy wrote:
(edited:)
> > +typedef struct {
> > +	unsigned long addr;
> > +} func_desc_t;
> >  
> >  static func_desc_t func_desc(unsigned long addr)
> >  {
> > +	return (func_desc_t){addr};

> There's only 1 element in the struct, so okay, but it hurt my eyes a
> little. I would have been happier with:
> 
> 	return (func_desc_t){ .addr = addr; };
> 
> But of course that also looks bonkers because it starts with "return".
> So no matter what I do my eyes bug out. ;)

The usual way to avoid convoluted constructs is to name more factors.
So:

static func_desc_t func_desc(unsigned long addr)
{
	func_desc_t desc = {};
	desc.addr = addr;
	return desc;
}


Segher

^ permalink raw reply	[flat|nested] 99+ messages in thread

* Re: [PATCH v3 04/12] powerpc: Prepare func_desc_t for refactorisation
@ 2022-02-11  7:39       ` Segher Boessenkool
  0 siblings, 0 replies; 99+ messages in thread
From: Segher Boessenkool @ 2022-02-11  7:39 UTC (permalink / raw)
  To: Kees Cook
  Cc: Christophe Leroy, linux-arch, linux-ia64, linux-parisc,
	Arnd Bergmann, Greg Kroah-Hartman, Helge Deller, linux-kernel,
	James E.J. Bottomley, linux-mm, Paul Mackerras, Andrew Morton,
	linuxppc-dev

On Thu, Feb 10, 2022 at 04:54:52PM -0800, Kees Cook wrote:
> On Sun, Oct 17, 2021 at 02:38:17PM +0200, Christophe Leroy wrote:
(edited:)
> > +typedef struct {
> > +	unsigned long addr;
> > +} func_desc_t;
> >  
> >  static func_desc_t func_desc(unsigned long addr)
> >  {
> > +	return (func_desc_t){addr};

> There's only 1 element in the struct, so okay, but it hurt my eyes a
> little. I would have been happier with:
> 
> 	return (func_desc_t){ .addr = addr; };
> 
> But of course that also looks bonkers because it starts with "return".
> So no matter what I do my eyes bug out. ;)

The usual way to avoid convoluted constructs is to name more factors.
So:

static func_desc_t func_desc(unsigned long addr)
{
	func_desc_t desc = {};
	desc.addr = addr;
	return desc;
}


Segher

^ permalink raw reply	[flat|nested] 99+ messages in thread

* Re: [PATCH v3 04/12] powerpc: Prepare func_desc_t for refactorisation
  2022-02-11  0:54     ` Kees Cook
  (?)
@ 2022-02-14 10:30       ` Christophe Leroy
  -1 siblings, 0 replies; 99+ messages in thread
From: Christophe Leroy @ 2022-02-14 10:30 UTC (permalink / raw)
  To: Kees Cook
  Cc: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Andrew Morton, James E.J. Bottomley, Helge Deller, Arnd Bergmann,
	Greg Kroah-Hartman, linux-kernel, linuxppc-dev, linux-ia64,
	linux-parisc, linux-arch, linux-mm



Le 11/02/2022 à 01:54, Kees Cook a écrit :
> On Sun, Oct 17, 2021 at 02:38:17PM +0200, Christophe Leroy wrote:
>> In preparation of making func_desc_t generic, change the ELFv2
>> version to a struct containing 'addr' element.
>>
>> This allows using single helpers common to ELFv1 and ELFv2.
>>
>> Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
>> ---
>>   arch/powerpc/kernel/module_64.c | 32 ++++++++++++++------------------
>>   1 file changed, 14 insertions(+), 18 deletions(-)
>>
>> diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c
>> index a89da0ee25e2..b687ef88c4c4 100644
>> --- a/arch/powerpc/kernel/module_64.c
>> +++ b/arch/powerpc/kernel/module_64.c
>> @@ -33,19 +33,13 @@
>>   #ifdef PPC64_ELF_ABI_v2
>>   
>>   /* An address is simply the address of the function. */
>> -typedef unsigned long func_desc_t;
>> +typedef struct {
>> +	unsigned long addr;
>> +} func_desc_t;
>>   
>>   static func_desc_t func_desc(unsigned long addr)
>>   {
>> -	return addr;
>> -}
>> -static unsigned long func_addr(unsigned long addr)
>> -{
>> -	return addr;
>> -}
>> -static unsigned long stub_func_addr(func_desc_t func)
>> -{
>> -	return func;
>> +	return (func_desc_t){addr};
> 
> There's only 1 element in the struct, so okay, but it hurt my eyes a
> little. I would have been happier with:
> 
> 	return (func_desc_t){ .addr = addr; };
> 
> But of course that also looks bonkers because it starts with "return".
> So no matter what I do my eyes bug out. ;)
> 
> So it's fine either way. :)
> 
> Reviewed-by: Kees Cook <keescook@chromium.org>

I am going for:

  static func_desc_t func_desc(unsigned long addr)
  {
+       func_desc_t desc = {
+               .addr = addr,
+       };
+
+       return desc;
  }


Thanks
Christophe

^ permalink raw reply	[flat|nested] 99+ messages in thread

* Re: [PATCH v3 04/12] powerpc: Prepare func_desc_t for refactorisation
@ 2022-02-14 10:30       ` Christophe Leroy
  0 siblings, 0 replies; 99+ messages in thread
From: Christophe Leroy @ 2022-02-14 10:30 UTC (permalink / raw)
  To: Kees Cook
  Cc: linux-arch, linux-ia64, linux-parisc, Arnd Bergmann,
	Greg Kroah-Hartman, Helge Deller, linux-kernel,
	James E.J. Bottomley, linux-mm, Paul Mackerras, Andrew Morton,
	linuxppc-dev



Le 11/02/2022 à 01:54, Kees Cook a écrit :
> On Sun, Oct 17, 2021 at 02:38:17PM +0200, Christophe Leroy wrote:
>> In preparation of making func_desc_t generic, change the ELFv2
>> version to a struct containing 'addr' element.
>>
>> This allows using single helpers common to ELFv1 and ELFv2.
>>
>> Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
>> ---
>>   arch/powerpc/kernel/module_64.c | 32 ++++++++++++++------------------
>>   1 file changed, 14 insertions(+), 18 deletions(-)
>>
>> diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c
>> index a89da0ee25e2..b687ef88c4c4 100644
>> --- a/arch/powerpc/kernel/module_64.c
>> +++ b/arch/powerpc/kernel/module_64.c
>> @@ -33,19 +33,13 @@
>>   #ifdef PPC64_ELF_ABI_v2
>>   
>>   /* An address is simply the address of the function. */
>> -typedef unsigned long func_desc_t;
>> +typedef struct {
>> +	unsigned long addr;
>> +} func_desc_t;
>>   
>>   static func_desc_t func_desc(unsigned long addr)
>>   {
>> -	return addr;
>> -}
>> -static unsigned long func_addr(unsigned long addr)
>> -{
>> -	return addr;
>> -}
>> -static unsigned long stub_func_addr(func_desc_t func)
>> -{
>> -	return func;
>> +	return (func_desc_t){addr};
> 
> There's only 1 element in the struct, so okay, but it hurt my eyes a
> little. I would have been happier with:
> 
> 	return (func_desc_t){ .addr = addr; };
> 
> But of course that also looks bonkers because it starts with "return".
> So no matter what I do my eyes bug out. ;)
> 
> So it's fine either way. :)
> 
> Reviewed-by: Kees Cook <keescook@chromium.org>

I am going for:

  static func_desc_t func_desc(unsigned long addr)
  {
+       func_desc_t desc = {
+               .addr = addr,
+       };
+
+       return desc;
  }


Thanks
Christophe

^ permalink raw reply	[flat|nested] 99+ messages in thread

* Re: [PATCH v3 04/12] powerpc: Prepare func_desc_t for refactorisation
@ 2022-02-14 10:30       ` Christophe Leroy
  0 siblings, 0 replies; 99+ messages in thread
From: Christophe Leroy @ 2022-02-14 10:30 UTC (permalink / raw)
  To: Kees Cook
  Cc: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Andrew Morton, James E.J. Bottomley, Helge Deller, Arnd Bergmann,
	Greg Kroah-Hartman, linux-kernel, linuxppc-dev, linux-ia64,
	linux-parisc, linux-arch, linux-mm

DQoNCkxlIDExLzAyLzIwMjIgw6AgMDE6NTQsIEtlZXMgQ29vayBhIMOpY3JpdMKgOg0KPiBPbiBT
dW4sIE9jdCAxNywgMjAyMSBhdCAwMjozODoxN1BNICswMjAwLCBDaHJpc3RvcGhlIExlcm95IHdy
b3RlOg0KPj4gSW4gcHJlcGFyYXRpb24gb2YgbWFraW5nIGZ1bmNfZGVzY190IGdlbmVyaWMsIGNo
YW5nZSB0aGUgRUxGdjINCj4+IHZlcnNpb24gdG8gYSBzdHJ1Y3QgY29udGFpbmluZyAnYWRkcicg
ZWxlbWVudC4NCj4+DQo+PiBUaGlzIGFsbG93cyB1c2luZyBzaW5nbGUgaGVscGVycyBjb21tb24g
dG8gRUxGdjEgYW5kIEVMRnYyLg0KPj4NCj4+IFNpZ25lZC1vZmYtYnk6IENocmlzdG9waGUgTGVy
b3kgPGNocmlzdG9waGUubGVyb3lAY3Nncm91cC5ldT4NCj4+IC0tLQ0KPj4gICBhcmNoL3Bvd2Vy
cGMva2VybmVsL21vZHVsZV82NC5jIHwgMzIgKysrKysrKysrKysrKystLS0tLS0tLS0tLS0tLS0t
LS0NCj4+ICAgMSBmaWxlIGNoYW5nZWQsIDE0IGluc2VydGlvbnMoKyksIDE4IGRlbGV0aW9ucygt
KQ0KPj4NCj4+IGRpZmYgLS1naXQgYS9hcmNoL3Bvd2VycGMva2VybmVsL21vZHVsZV82NC5jIGIv
YXJjaC9wb3dlcnBjL2tlcm5lbC9tb2R1bGVfNjQuYw0KPj4gaW5kZXggYTg5ZGEwZWUyNWUyLi5i
Njg3ZWY4OGM0YzQgMTAwNjQ0DQo+PiAtLS0gYS9hcmNoL3Bvd2VycGMva2VybmVsL21vZHVsZV82
NC5jDQo+PiArKysgYi9hcmNoL3Bvd2VycGMva2VybmVsL21vZHVsZV82NC5jDQo+PiBAQCAtMzMs
MTkgKzMzLDEzIEBADQo+PiAgICNpZmRlZiBQUEM2NF9FTEZfQUJJX3YyDQo+PiAgIA0KPj4gICAv
KiBBbiBhZGRyZXNzIGlzIHNpbXBseSB0aGUgYWRkcmVzcyBvZiB0aGUgZnVuY3Rpb24uICovDQo+
PiAtdHlwZWRlZiB1bnNpZ25lZCBsb25nIGZ1bmNfZGVzY190Ow0KPj4gK3R5cGVkZWYgc3RydWN0
IHsNCj4+ICsJdW5zaWduZWQgbG9uZyBhZGRyOw0KPj4gK30gZnVuY19kZXNjX3Q7DQo+PiAgIA0K
Pj4gICBzdGF0aWMgZnVuY19kZXNjX3QgZnVuY19kZXNjKHVuc2lnbmVkIGxvbmcgYWRkcikNCj4+
ICAgew0KPj4gLQlyZXR1cm4gYWRkcjsNCj4+IC19DQo+PiAtc3RhdGljIHVuc2lnbmVkIGxvbmcg
ZnVuY19hZGRyKHVuc2lnbmVkIGxvbmcgYWRkcikNCj4+IC17DQo+PiAtCXJldHVybiBhZGRyOw0K
Pj4gLX0NCj4+IC1zdGF0aWMgdW5zaWduZWQgbG9uZyBzdHViX2Z1bmNfYWRkcihmdW5jX2Rlc2Nf
dCBmdW5jKQ0KPj4gLXsNCj4+IC0JcmV0dXJuIGZ1bmM7DQo+PiArCXJldHVybiAoZnVuY19kZXNj
X3Qpe2FkZHJ9Ow0KPiANCj4gVGhlcmUncyBvbmx5IDEgZWxlbWVudCBpbiB0aGUgc3RydWN0LCBz
byBva2F5LCBidXQgaXQgaHVydCBteSBleWVzIGENCj4gbGl0dGxlLiBJIHdvdWxkIGhhdmUgYmVl
biBoYXBwaWVyIHdpdGg6DQo+IA0KPiAJcmV0dXJuIChmdW5jX2Rlc2NfdCl7IC5hZGRyID0gYWRk
cjsgfTsNCj4gDQo+IEJ1dCBvZiBjb3Vyc2UgdGhhdCBhbHNvIGxvb2tzIGJvbmtlcnMgYmVjYXVz
ZSBpdCBzdGFydHMgd2l0aCAicmV0dXJuIi4NCj4gU28gbm8gbWF0dGVyIHdoYXQgSSBkbyBteSBl
eWVzIGJ1ZyBvdXQuIDspDQo+IA0KPiBTbyBpdCdzIGZpbmUgZWl0aGVyIHdheS4gOikNCj4gDQo+
IFJldmlld2VkLWJ5OiBLZWVzIENvb2sgPGtlZXNjb29rQGNocm9taXVtLm9yZz4NCg0KSSBhbSBn
b2luZyBmb3I6DQoNCiAgc3RhdGljIGZ1bmNfZGVzY190IGZ1bmNfZGVzYyh1bnNpZ25lZCBsb25n
IGFkZHIpDQogIHsNCisgICAgICAgZnVuY19kZXNjX3QgZGVzYyA9IHsNCisgICAgICAgICAgICAg
ICAuYWRkciA9IGFkZHIsDQorICAgICAgIH07DQorDQorICAgICAgIHJldHVybiBkZXNjOw0KICB9
DQoNCg0KVGhhbmtzDQpDaHJpc3RvcGhl

^ permalink raw reply	[flat|nested] 99+ messages in thread

* Re: [PATCH v3 08/12] asm-generic: Refactor dereference_[kernel]_function_descriptor()
  2022-02-11  0:56       ` Kees Cook
  (?)
@ 2022-02-14 10:32         ` Christophe Leroy
  -1 siblings, 0 replies; 99+ messages in thread
From: Christophe Leroy @ 2022-02-14 10:32 UTC (permalink / raw)
  To: Kees Cook, Michael Ellerman
  Cc: Benjamin Herrenschmidt, Paul Mackerras, Andrew Morton,
	James E.J. Bottomley, Helge Deller, Arnd Bergmann,
	Greg Kroah-Hartman, linux-kernel, linuxppc-dev, linux-ia64,
	linux-parisc, linux-arch, linux-mm



Le 11/02/2022 à 01:56, Kees Cook a écrit :
> On Thu, Feb 10, 2022 at 09:30:43PM +1100, Michael Ellerman wrote:
>> Christophe Leroy <christophe.leroy@csgroup.eu> writes:
>>> diff --git a/kernel/extable.c b/kernel/extable.c
>>> index b0ea5eb0c3b4..1ef13789bea9 100644
>>> --- a/kernel/extable.c
>>> +++ b/kernel/extable.c
>>> @@ -159,12 +160,32 @@ int kernel_text_address(unsigned long addr)
>>>   }
>>>   
>>>   /*
>>> - * On some architectures (PPC64, IA64) function pointers
>>> + * On some architectures (PPC64, IA64, PARISC) function pointers
>>>    * are actually only tokens to some data that then holds the
>>>    * real function address. As a result, to find if a function
>>>    * pointer is part of the kernel text, we need to do some
>>>    * special dereferencing first.
>>>    */
>>> +#ifdef CONFIG_HAVE_FUNCTION_DESCRIPTORS
>>> +void *dereference_function_descriptor(void *ptr)
>>> +{
>>> +	func_desc_t *desc = ptr;
>>> +	void *p;
>>> +
>>> +	if (!get_kernel_nofault(p, (void *)&desc->addr))
>>> +		ptr = p;
>>> +	return ptr;
>>> +}
>>
>> This needs an EXPORT_SYMBOL_GPL(), otherwise the build breaks after
>> patch 10 with CONFIG_LKDTM=m.
> 
> Oh good catch!
> 
> (There have been a few cases of LKDTM=m being the only thing needed a
> symbol, so I've pondered giving it a namespace or constructing a little
> ifdef wrapper... but this seems ok to export...)
> 

powerpc and ia64 had it as a static inline, but parisc had it as a plain 
function and didn't export it. So I guess the export is not required at 
this point. I will export it in patch 10 when it becomes necessary.

Christophe

^ permalink raw reply	[flat|nested] 99+ messages in thread

* Re: [PATCH v3 08/12] asm-generic: Refactor dereference_[kernel]_function_descriptor()
@ 2022-02-14 10:32         ` Christophe Leroy
  0 siblings, 0 replies; 99+ messages in thread
From: Christophe Leroy @ 2022-02-14 10:32 UTC (permalink / raw)
  To: Kees Cook, Michael Ellerman
  Cc: linux-arch, linux-ia64, linux-parisc, Arnd Bergmann,
	Helge Deller, linux-kernel, James E.J. Bottomley, linux-mm,
	Paul Mackerras, Greg Kroah-Hartman, Andrew Morton, linuxppc-dev



Le 11/02/2022 à 01:56, Kees Cook a écrit :
> On Thu, Feb 10, 2022 at 09:30:43PM +1100, Michael Ellerman wrote:
>> Christophe Leroy <christophe.leroy@csgroup.eu> writes:
>>> diff --git a/kernel/extable.c b/kernel/extable.c
>>> index b0ea5eb0c3b4..1ef13789bea9 100644
>>> --- a/kernel/extable.c
>>> +++ b/kernel/extable.c
>>> @@ -159,12 +160,32 @@ int kernel_text_address(unsigned long addr)
>>>   }
>>>   
>>>   /*
>>> - * On some architectures (PPC64, IA64) function pointers
>>> + * On some architectures (PPC64, IA64, PARISC) function pointers
>>>    * are actually only tokens to some data that then holds the
>>>    * real function address. As a result, to find if a function
>>>    * pointer is part of the kernel text, we need to do some
>>>    * special dereferencing first.
>>>    */
>>> +#ifdef CONFIG_HAVE_FUNCTION_DESCRIPTORS
>>> +void *dereference_function_descriptor(void *ptr)
>>> +{
>>> +	func_desc_t *desc = ptr;
>>> +	void *p;
>>> +
>>> +	if (!get_kernel_nofault(p, (void *)&desc->addr))
>>> +		ptr = p;
>>> +	return ptr;
>>> +}
>>
>> This needs an EXPORT_SYMBOL_GPL(), otherwise the build breaks after
>> patch 10 with CONFIG_LKDTM=m.
> 
> Oh good catch!
> 
> (There have been a few cases of LKDTM=m being the only thing needed a
> symbol, so I've pondered giving it a namespace or constructing a little
> ifdef wrapper... but this seems ok to export...)
> 

powerpc and ia64 had it as a static inline, but parisc had it as a plain 
function and didn't export it. So I guess the export is not required at 
this point. I will export it in patch 10 when it becomes necessary.

Christophe

^ permalink raw reply	[flat|nested] 99+ messages in thread

* Re: [PATCH v3 08/12] asm-generic: Refactor dereference_[kernel]_function_descriptor()
@ 2022-02-14 10:32         ` Christophe Leroy
  0 siblings, 0 replies; 99+ messages in thread
From: Christophe Leroy @ 2022-02-14 10:32 UTC (permalink / raw)
  To: Kees Cook, Michael Ellerman
  Cc: Benjamin Herrenschmidt, Paul Mackerras, Andrew Morton,
	James E.J. Bottomley, Helge Deller, Arnd Bergmann,
	Greg Kroah-Hartman, linux-kernel, linuxppc-dev, linux-ia64,
	linux-parisc, linux-arch, linux-mm

DQoNCkxlIDExLzAyLzIwMjIgw6AgMDE6NTYsIEtlZXMgQ29vayBhIMOpY3JpdMKgOg0KPiBPbiBU
aHUsIEZlYiAxMCwgMjAyMiBhdCAwOTozMDo0M1BNICsxMTAwLCBNaWNoYWVsIEVsbGVybWFuIHdy
b3RlOg0KPj4gQ2hyaXN0b3BoZSBMZXJveSA8Y2hyaXN0b3BoZS5sZXJveUBjc2dyb3VwLmV1PiB3
cml0ZXM6DQo+Pj4gZGlmZiAtLWdpdCBhL2tlcm5lbC9leHRhYmxlLmMgYi9rZXJuZWwvZXh0YWJs
ZS5jDQo+Pj4gaW5kZXggYjBlYTVlYjBjM2I0Li4xZWYxMzc4OWJlYTkgMTAwNjQ0DQo+Pj4gLS0t
IGEva2VybmVsL2V4dGFibGUuYw0KPj4+ICsrKyBiL2tlcm5lbC9leHRhYmxlLmMNCj4+PiBAQCAt
MTU5LDEyICsxNjAsMzIgQEAgaW50IGtlcm5lbF90ZXh0X2FkZHJlc3ModW5zaWduZWQgbG9uZyBh
ZGRyKQ0KPj4+ICAgfQ0KPj4+ICAgDQo+Pj4gICAvKg0KPj4+IC0gKiBPbiBzb21lIGFyY2hpdGVj
dHVyZXMgKFBQQzY0LCBJQTY0KSBmdW5jdGlvbiBwb2ludGVycw0KPj4+ICsgKiBPbiBzb21lIGFy
Y2hpdGVjdHVyZXMgKFBQQzY0LCBJQTY0LCBQQVJJU0MpIGZ1bmN0aW9uIHBvaW50ZXJzDQo+Pj4g
ICAgKiBhcmUgYWN0dWFsbHkgb25seSB0b2tlbnMgdG8gc29tZSBkYXRhIHRoYXQgdGhlbiBob2xk
cyB0aGUNCj4+PiAgICAqIHJlYWwgZnVuY3Rpb24gYWRkcmVzcy4gQXMgYSByZXN1bHQsIHRvIGZp
bmQgaWYgYSBmdW5jdGlvbg0KPj4+ICAgICogcG9pbnRlciBpcyBwYXJ0IG9mIHRoZSBrZXJuZWwg
dGV4dCwgd2UgbmVlZCB0byBkbyBzb21lDQo+Pj4gICAgKiBzcGVjaWFsIGRlcmVmZXJlbmNpbmcg
Zmlyc3QuDQo+Pj4gICAgKi8NCj4+PiArI2lmZGVmIENPTkZJR19IQVZFX0ZVTkNUSU9OX0RFU0NS
SVBUT1JTDQo+Pj4gK3ZvaWQgKmRlcmVmZXJlbmNlX2Z1bmN0aW9uX2Rlc2NyaXB0b3Iodm9pZCAq
cHRyKQ0KPj4+ICt7DQo+Pj4gKwlmdW5jX2Rlc2NfdCAqZGVzYyA9IHB0cjsNCj4+PiArCXZvaWQg
KnA7DQo+Pj4gKw0KPj4+ICsJaWYgKCFnZXRfa2VybmVsX25vZmF1bHQocCwgKHZvaWQgKikmZGVz
Yy0+YWRkcikpDQo+Pj4gKwkJcHRyID0gcDsNCj4+PiArCXJldHVybiBwdHI7DQo+Pj4gK30NCj4+
DQo+PiBUaGlzIG5lZWRzIGFuIEVYUE9SVF9TWU1CT0xfR1BMKCksIG90aGVyd2lzZSB0aGUgYnVp
bGQgYnJlYWtzIGFmdGVyDQo+PiBwYXRjaCAxMCB3aXRoIENPTkZJR19MS0RUTT1tLg0KPiANCj4g
T2ggZ29vZCBjYXRjaCENCj4gDQo+IChUaGVyZSBoYXZlIGJlZW4gYSBmZXcgY2FzZXMgb2YgTEtE
VE09bSBiZWluZyB0aGUgb25seSB0aGluZyBuZWVkZWQgYQ0KPiBzeW1ib2wsIHNvIEkndmUgcG9u
ZGVyZWQgZ2l2aW5nIGl0IGEgbmFtZXNwYWNlIG9yIGNvbnN0cnVjdGluZyBhIGxpdHRsZQ0KPiBp
ZmRlZiB3cmFwcGVyLi4uIGJ1dCB0aGlzIHNlZW1zIG9rIHRvIGV4cG9ydC4uLikNCj4gDQoNCnBv
d2VycGMgYW5kIGlhNjQgaGFkIGl0IGFzIGEgc3RhdGljIGlubGluZSwgYnV0IHBhcmlzYyBoYWQg
aXQgYXMgYSBwbGFpbiANCmZ1bmN0aW9uIGFuZCBkaWRuJ3QgZXhwb3J0IGl0LiBTbyBJIGd1ZXNz
IHRoZSBleHBvcnQgaXMgbm90IHJlcXVpcmVkIGF0IA0KdGhpcyBwb2ludC4gSSB3aWxsIGV4cG9y
dCBpdCBpbiBwYXRjaCAxMCB3aGVuIGl0IGJlY29tZXMgbmVjZXNzYXJ5Lg0KDQpDaHJpc3RvcGhl

^ permalink raw reply	[flat|nested] 99+ messages in thread

* Re: [PATCH v3 12/12] lkdtm: Add a test for function descriptors protection
  2022-02-11  1:09     ` Kees Cook
  (?)
@ 2022-02-14 10:34       ` Christophe Leroy
  -1 siblings, 0 replies; 99+ messages in thread
From: Christophe Leroy @ 2022-02-14 10:34 UTC (permalink / raw)
  To: Kees Cook
  Cc: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Andrew Morton, James E.J. Bottomley, Helge Deller, Arnd Bergmann,
	Greg Kroah-Hartman, linux-kernel, linuxppc-dev, linux-ia64,
	linux-parisc, linux-arch, linux-mm



Le 11/02/2022 à 02:09, Kees Cook a écrit :
> On Sun, Oct 17, 2021 at 02:38:25PM +0200, Christophe Leroy wrote:
>> Add WRITE_OPD to check that you can't modify function
>> descriptors.
>>
>> Gives the following result when function descriptors are
>> not protected:
>>
>> 	lkdtm: Performing direct entry WRITE_OPD
>> 	lkdtm: attempting bad 16 bytes write at c00000000269b358
>> 	lkdtm: FAIL: survived bad write
>> 	lkdtm: do_nothing was hijacked!
>>
>> Looks like a standard compiler barrier() is not enough to force
>> GCC to use the modified function descriptor. Had to add a fake empty
>> inline assembly to force GCC to reload the function descriptor.
>>
>> Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
>> ---
>>   drivers/misc/lkdtm/core.c  |  1 +
>>   drivers/misc/lkdtm/lkdtm.h |  1 +
>>   drivers/misc/lkdtm/perms.c | 22 ++++++++++++++++++++++
>>   3 files changed, 24 insertions(+)
>>
>> diff --git a/drivers/misc/lkdtm/core.c b/drivers/misc/lkdtm/core.c
>> index fe6fd34b8caf..de092aa03b5d 100644
>> --- a/drivers/misc/lkdtm/core.c
>> +++ b/drivers/misc/lkdtm/core.c
>> @@ -148,6 +148,7 @@ static const struct crashtype crashtypes[] = {
>>   	CRASHTYPE(WRITE_RO),
>>   	CRASHTYPE(WRITE_RO_AFTER_INIT),
>>   	CRASHTYPE(WRITE_KERN),
>> +	CRASHTYPE(WRITE_OPD),
>>   	CRASHTYPE(REFCOUNT_INC_OVERFLOW),
>>   	CRASHTYPE(REFCOUNT_ADD_OVERFLOW),
>>   	CRASHTYPE(REFCOUNT_INC_NOT_ZERO_OVERFLOW),
>> diff --git a/drivers/misc/lkdtm/lkdtm.h b/drivers/misc/lkdtm/lkdtm.h
>> index c212a253edde..188bd0fd6575 100644
>> --- a/drivers/misc/lkdtm/lkdtm.h
>> +++ b/drivers/misc/lkdtm/lkdtm.h
>> @@ -105,6 +105,7 @@ void __init lkdtm_perms_init(void);
>>   void lkdtm_WRITE_RO(void);
>>   void lkdtm_WRITE_RO_AFTER_INIT(void);
>>   void lkdtm_WRITE_KERN(void);
>> +void lkdtm_WRITE_OPD(void);
>>   void lkdtm_EXEC_DATA(void);
>>   void lkdtm_EXEC_STACK(void);
>>   void lkdtm_EXEC_KMALLOC(void);
>> diff --git a/drivers/misc/lkdtm/perms.c b/drivers/misc/lkdtm/perms.c
>> index 1cf24c4a79e9..2c6aba3ff32b 100644
>> --- a/drivers/misc/lkdtm/perms.c
>> +++ b/drivers/misc/lkdtm/perms.c
>> @@ -44,6 +44,11 @@ static noinline void do_overwritten(void)
>>   	return;
>>   }
>>   
>> +static noinline void do_almost_nothing(void)
>> +{
>> +	pr_info("do_nothing was hijacked!\n");
>> +}
>> +
>>   static void *setup_function_descriptor(func_desc_t *fdesc, void *dst)
>>   {
>>   	if (!have_function_descriptors())
>> @@ -144,6 +149,23 @@ void lkdtm_WRITE_KERN(void)
>>   	do_overwritten();
>>   }
>>   
>> +void lkdtm_WRITE_OPD(void)
>> +{
>> +	size_t size = sizeof(func_desc_t);
>> +	void (*func)(void) = do_nothing;
>> +
>> +	if (!have_function_descriptors()) {
>> +		pr_info("XFAIL: Platform doesn't use function descriptors.\n");
>> +		return;
>> +	}
>> +	pr_info("attempting bad %zu bytes write at %px\n", size, do_nothing);
>> +	memcpy(do_nothing, do_almost_nothing, size);
>> +	pr_err("FAIL: survived bad write\n");
> 
> Non-function-descriptor architectures would successfully crash at the
> memcpy too, right? (i.e. for them this is just repeating WRITE_KERN)

Yes it should. But not for the good reason.

> 
> I'm pondering the utility of the XFAIL vs just letting is succeed, but I
> think it more accurate to say "hey, no OPD" as you have it.
> 
>> +
>> +	asm("" : "=m"(func));
>> +	func();
>> +}
>> +
>>   void lkdtm_EXEC_DATA(void)
>>   {
>>   	execute_location(data_area, CODE_WRITE);
>> -- 
>> 2.31.1
>>
> 
> One tiny suggestion, since I think you need to respin for the
> EXPORT_SYMBOL_GPL() anyway. Please update the selftests too:
> 
> diff --git a/tools/testing/selftests/lkdtm/tests.txt b/tools/testing/selftests/lkdtm/tests.txt
> index 6b36b7f5dcf9..243c781f0780 100644
> --- a/tools/testing/selftests/lkdtm/tests.txt
> +++ b/tools/testing/selftests/lkdtm/tests.txt
> @@ -44,6 +44,7 @@ ACCESS_NULL
>   WRITE_RO
>   WRITE_RO_AFTER_INIT
>   WRITE_KERN
> +WRITE_OPD
>   REFCOUNT_INC_OVERFLOW
>   REFCOUNT_ADD_OVERFLOW
>   REFCOUNT_INC_NOT_ZERO_OVERFLOW
> 
> (Though for the future I've been considering making the selftests an
> opt-out list so the "normal" stuff doesn't need to keep getting added
> there.)
> 
> Thanks!
> 
> Acked-by: Kees Cook <keescook@chromium.org>
> 

Done.

Thanks
Christophe

^ permalink raw reply	[flat|nested] 99+ messages in thread

* Re: [PATCH v3 12/12] lkdtm: Add a test for function descriptors protection
@ 2022-02-14 10:34       ` Christophe Leroy
  0 siblings, 0 replies; 99+ messages in thread
From: Christophe Leroy @ 2022-02-14 10:34 UTC (permalink / raw)
  To: Kees Cook
  Cc: linux-arch, linux-ia64, linux-parisc, Arnd Bergmann,
	Greg Kroah-Hartman, Helge Deller, linux-kernel,
	James E.J. Bottomley, linux-mm, Paul Mackerras, Andrew Morton,
	linuxppc-dev



Le 11/02/2022 à 02:09, Kees Cook a écrit :
> On Sun, Oct 17, 2021 at 02:38:25PM +0200, Christophe Leroy wrote:
>> Add WRITE_OPD to check that you can't modify function
>> descriptors.
>>
>> Gives the following result when function descriptors are
>> not protected:
>>
>> 	lkdtm: Performing direct entry WRITE_OPD
>> 	lkdtm: attempting bad 16 bytes write at c00000000269b358
>> 	lkdtm: FAIL: survived bad write
>> 	lkdtm: do_nothing was hijacked!
>>
>> Looks like a standard compiler barrier() is not enough to force
>> GCC to use the modified function descriptor. Had to add a fake empty
>> inline assembly to force GCC to reload the function descriptor.
>>
>> Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
>> ---
>>   drivers/misc/lkdtm/core.c  |  1 +
>>   drivers/misc/lkdtm/lkdtm.h |  1 +
>>   drivers/misc/lkdtm/perms.c | 22 ++++++++++++++++++++++
>>   3 files changed, 24 insertions(+)
>>
>> diff --git a/drivers/misc/lkdtm/core.c b/drivers/misc/lkdtm/core.c
>> index fe6fd34b8caf..de092aa03b5d 100644
>> --- a/drivers/misc/lkdtm/core.c
>> +++ b/drivers/misc/lkdtm/core.c
>> @@ -148,6 +148,7 @@ static const struct crashtype crashtypes[] = {
>>   	CRASHTYPE(WRITE_RO),
>>   	CRASHTYPE(WRITE_RO_AFTER_INIT),
>>   	CRASHTYPE(WRITE_KERN),
>> +	CRASHTYPE(WRITE_OPD),
>>   	CRASHTYPE(REFCOUNT_INC_OVERFLOW),
>>   	CRASHTYPE(REFCOUNT_ADD_OVERFLOW),
>>   	CRASHTYPE(REFCOUNT_INC_NOT_ZERO_OVERFLOW),
>> diff --git a/drivers/misc/lkdtm/lkdtm.h b/drivers/misc/lkdtm/lkdtm.h
>> index c212a253edde..188bd0fd6575 100644
>> --- a/drivers/misc/lkdtm/lkdtm.h
>> +++ b/drivers/misc/lkdtm/lkdtm.h
>> @@ -105,6 +105,7 @@ void __init lkdtm_perms_init(void);
>>   void lkdtm_WRITE_RO(void);
>>   void lkdtm_WRITE_RO_AFTER_INIT(void);
>>   void lkdtm_WRITE_KERN(void);
>> +void lkdtm_WRITE_OPD(void);
>>   void lkdtm_EXEC_DATA(void);
>>   void lkdtm_EXEC_STACK(void);
>>   void lkdtm_EXEC_KMALLOC(void);
>> diff --git a/drivers/misc/lkdtm/perms.c b/drivers/misc/lkdtm/perms.c
>> index 1cf24c4a79e9..2c6aba3ff32b 100644
>> --- a/drivers/misc/lkdtm/perms.c
>> +++ b/drivers/misc/lkdtm/perms.c
>> @@ -44,6 +44,11 @@ static noinline void do_overwritten(void)
>>   	return;
>>   }
>>   
>> +static noinline void do_almost_nothing(void)
>> +{
>> +	pr_info("do_nothing was hijacked!\n");
>> +}
>> +
>>   static void *setup_function_descriptor(func_desc_t *fdesc, void *dst)
>>   {
>>   	if (!have_function_descriptors())
>> @@ -144,6 +149,23 @@ void lkdtm_WRITE_KERN(void)
>>   	do_overwritten();
>>   }
>>   
>> +void lkdtm_WRITE_OPD(void)
>> +{
>> +	size_t size = sizeof(func_desc_t);
>> +	void (*func)(void) = do_nothing;
>> +
>> +	if (!have_function_descriptors()) {
>> +		pr_info("XFAIL: Platform doesn't use function descriptors.\n");
>> +		return;
>> +	}
>> +	pr_info("attempting bad %zu bytes write at %px\n", size, do_nothing);
>> +	memcpy(do_nothing, do_almost_nothing, size);
>> +	pr_err("FAIL: survived bad write\n");
> 
> Non-function-descriptor architectures would successfully crash at the
> memcpy too, right? (i.e. for them this is just repeating WRITE_KERN)

Yes it should. But not for the good reason.

> 
> I'm pondering the utility of the XFAIL vs just letting is succeed, but I
> think it more accurate to say "hey, no OPD" as you have it.
> 
>> +
>> +	asm("" : "=m"(func));
>> +	func();
>> +}
>> +
>>   void lkdtm_EXEC_DATA(void)
>>   {
>>   	execute_location(data_area, CODE_WRITE);
>> -- 
>> 2.31.1
>>
> 
> One tiny suggestion, since I think you need to respin for the
> EXPORT_SYMBOL_GPL() anyway. Please update the selftests too:
> 
> diff --git a/tools/testing/selftests/lkdtm/tests.txt b/tools/testing/selftests/lkdtm/tests.txt
> index 6b36b7f5dcf9..243c781f0780 100644
> --- a/tools/testing/selftests/lkdtm/tests.txt
> +++ b/tools/testing/selftests/lkdtm/tests.txt
> @@ -44,6 +44,7 @@ ACCESS_NULL
>   WRITE_RO
>   WRITE_RO_AFTER_INIT
>   WRITE_KERN
> +WRITE_OPD
>   REFCOUNT_INC_OVERFLOW
>   REFCOUNT_ADD_OVERFLOW
>   REFCOUNT_INC_NOT_ZERO_OVERFLOW
> 
> (Though for the future I've been considering making the selftests an
> opt-out list so the "normal" stuff doesn't need to keep getting added
> there.)
> 
> Thanks!
> 
> Acked-by: Kees Cook <keescook@chromium.org>
> 

Done.

Thanks
Christophe

^ permalink raw reply	[flat|nested] 99+ messages in thread

* Re: [PATCH v3 12/12] lkdtm: Add a test for function descriptors protection
@ 2022-02-14 10:34       ` Christophe Leroy
  0 siblings, 0 replies; 99+ messages in thread
From: Christophe Leroy @ 2022-02-14 10:34 UTC (permalink / raw)
  To: Kees Cook
  Cc: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Andrew Morton, James E.J. Bottomley, Helge Deller, Arnd Bergmann,
	Greg Kroah-Hartman, linux-kernel, linuxppc-dev, linux-ia64,
	linux-parisc, linux-arch, linux-mm

DQoNCkxlIDExLzAyLzIwMjIgw6AgMDI6MDksIEtlZXMgQ29vayBhIMOpY3JpdMKgOg0KPiBPbiBT
dW4sIE9jdCAxNywgMjAyMSBhdCAwMjozODoyNVBNICswMjAwLCBDaHJpc3RvcGhlIExlcm95IHdy
b3RlOg0KPj4gQWRkIFdSSVRFX09QRCB0byBjaGVjayB0aGF0IHlvdSBjYW4ndCBtb2RpZnkgZnVu
Y3Rpb24NCj4+IGRlc2NyaXB0b3JzLg0KPj4NCj4+IEdpdmVzIHRoZSBmb2xsb3dpbmcgcmVzdWx0
IHdoZW4gZnVuY3Rpb24gZGVzY3JpcHRvcnMgYXJlDQo+PiBub3QgcHJvdGVjdGVkOg0KPj4NCj4+
IAlsa2R0bTogUGVyZm9ybWluZyBkaXJlY3QgZW50cnkgV1JJVEVfT1BEDQo+PiAJbGtkdG06IGF0
dGVtcHRpbmcgYmFkIDE2IGJ5dGVzIHdyaXRlIGF0IGMwMDAwMDAwMDI2OWIzNTgNCj4+IAlsa2R0
bTogRkFJTDogc3Vydml2ZWQgYmFkIHdyaXRlDQo+PiAJbGtkdG06IGRvX25vdGhpbmcgd2FzIGhp
amFja2VkIQ0KPj4NCj4+IExvb2tzIGxpa2UgYSBzdGFuZGFyZCBjb21waWxlciBiYXJyaWVyKCkg
aXMgbm90IGVub3VnaCB0byBmb3JjZQ0KPj4gR0NDIHRvIHVzZSB0aGUgbW9kaWZpZWQgZnVuY3Rp
b24gZGVzY3JpcHRvci4gSGFkIHRvIGFkZCBhIGZha2UgZW1wdHkNCj4+IGlubGluZSBhc3NlbWJs
eSB0byBmb3JjZSBHQ0MgdG8gcmVsb2FkIHRoZSBmdW5jdGlvbiBkZXNjcmlwdG9yLg0KPj4NCj4+
IFNpZ25lZC1vZmYtYnk6IENocmlzdG9waGUgTGVyb3kgPGNocmlzdG9waGUubGVyb3lAY3Nncm91
cC5ldT4NCj4+IC0tLQ0KPj4gICBkcml2ZXJzL21pc2MvbGtkdG0vY29yZS5jICB8ICAxICsNCj4+
ICAgZHJpdmVycy9taXNjL2xrZHRtL2xrZHRtLmggfCAgMSArDQo+PiAgIGRyaXZlcnMvbWlzYy9s
a2R0bS9wZXJtcy5jIHwgMjIgKysrKysrKysrKysrKysrKysrKysrKw0KPj4gICAzIGZpbGVzIGNo
YW5nZWQsIDI0IGluc2VydGlvbnMoKykNCj4+DQo+PiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9taXNj
L2xrZHRtL2NvcmUuYyBiL2RyaXZlcnMvbWlzYy9sa2R0bS9jb3JlLmMNCj4+IGluZGV4IGZlNmZk
MzRiOGNhZi4uZGUwOTJhYTAzYjVkIDEwMDY0NA0KPj4gLS0tIGEvZHJpdmVycy9taXNjL2xrZHRt
L2NvcmUuYw0KPj4gKysrIGIvZHJpdmVycy9taXNjL2xrZHRtL2NvcmUuYw0KPj4gQEAgLTE0OCw2
ICsxNDgsNyBAQCBzdGF0aWMgY29uc3Qgc3RydWN0IGNyYXNodHlwZSBjcmFzaHR5cGVzW10gPSB7
DQo+PiAgIAlDUkFTSFRZUEUoV1JJVEVfUk8pLA0KPj4gICAJQ1JBU0hUWVBFKFdSSVRFX1JPX0FG
VEVSX0lOSVQpLA0KPj4gICAJQ1JBU0hUWVBFKFdSSVRFX0tFUk4pLA0KPj4gKwlDUkFTSFRZUEUo
V1JJVEVfT1BEKSwNCj4+ICAgCUNSQVNIVFlQRShSRUZDT1VOVF9JTkNfT1ZFUkZMT1cpLA0KPj4g
ICAJQ1JBU0hUWVBFKFJFRkNPVU5UX0FERF9PVkVSRkxPVyksDQo+PiAgIAlDUkFTSFRZUEUoUkVG
Q09VTlRfSU5DX05PVF9aRVJPX09WRVJGTE9XKSwNCj4+IGRpZmYgLS1naXQgYS9kcml2ZXJzL21p
c2MvbGtkdG0vbGtkdG0uaCBiL2RyaXZlcnMvbWlzYy9sa2R0bS9sa2R0bS5oDQo+PiBpbmRleCBj
MjEyYTI1M2VkZGUuLjE4OGJkMGZkNjU3NSAxMDA2NDQNCj4+IC0tLSBhL2RyaXZlcnMvbWlzYy9s
a2R0bS9sa2R0bS5oDQo+PiArKysgYi9kcml2ZXJzL21pc2MvbGtkdG0vbGtkdG0uaA0KPj4gQEAg
LTEwNSw2ICsxMDUsNyBAQCB2b2lkIF9faW5pdCBsa2R0bV9wZXJtc19pbml0KHZvaWQpOw0KPj4g
ICB2b2lkIGxrZHRtX1dSSVRFX1JPKHZvaWQpOw0KPj4gICB2b2lkIGxrZHRtX1dSSVRFX1JPX0FG
VEVSX0lOSVQodm9pZCk7DQo+PiAgIHZvaWQgbGtkdG1fV1JJVEVfS0VSTih2b2lkKTsNCj4+ICt2
b2lkIGxrZHRtX1dSSVRFX09QRCh2b2lkKTsNCj4+ICAgdm9pZCBsa2R0bV9FWEVDX0RBVEEodm9p
ZCk7DQo+PiAgIHZvaWQgbGtkdG1fRVhFQ19TVEFDSyh2b2lkKTsNCj4+ICAgdm9pZCBsa2R0bV9F
WEVDX0tNQUxMT0Modm9pZCk7DQo+PiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9taXNjL2xrZHRtL3Bl
cm1zLmMgYi9kcml2ZXJzL21pc2MvbGtkdG0vcGVybXMuYw0KPj4gaW5kZXggMWNmMjRjNGE3OWU5
Li4yYzZhYmEzZmYzMmIgMTAwNjQ0DQo+PiAtLS0gYS9kcml2ZXJzL21pc2MvbGtkdG0vcGVybXMu
Yw0KPj4gKysrIGIvZHJpdmVycy9taXNjL2xrZHRtL3Blcm1zLmMNCj4+IEBAIC00NCw2ICs0NCwx
MSBAQCBzdGF0aWMgbm9pbmxpbmUgdm9pZCBkb19vdmVyd3JpdHRlbih2b2lkKQ0KPj4gICAJcmV0
dXJuOw0KPj4gICB9DQo+PiAgIA0KPj4gK3N0YXRpYyBub2lubGluZSB2b2lkIGRvX2FsbW9zdF9u
b3RoaW5nKHZvaWQpDQo+PiArew0KPj4gKwlwcl9pbmZvKCJkb19ub3RoaW5nIHdhcyBoaWphY2tl
ZCFcbiIpOw0KPj4gK30NCj4+ICsNCj4+ICAgc3RhdGljIHZvaWQgKnNldHVwX2Z1bmN0aW9uX2Rl
c2NyaXB0b3IoZnVuY19kZXNjX3QgKmZkZXNjLCB2b2lkICpkc3QpDQo+PiAgIHsNCj4+ICAgCWlm
ICghaGF2ZV9mdW5jdGlvbl9kZXNjcmlwdG9ycygpKQ0KPj4gQEAgLTE0NCw2ICsxNDksMjMgQEAg
dm9pZCBsa2R0bV9XUklURV9LRVJOKHZvaWQpDQo+PiAgIAlkb19vdmVyd3JpdHRlbigpOw0KPj4g
ICB9DQo+PiAgIA0KPj4gK3ZvaWQgbGtkdG1fV1JJVEVfT1BEKHZvaWQpDQo+PiArew0KPj4gKwlz
aXplX3Qgc2l6ZSA9IHNpemVvZihmdW5jX2Rlc2NfdCk7DQo+PiArCXZvaWQgKCpmdW5jKSh2b2lk
KSA9IGRvX25vdGhpbmc7DQo+PiArDQo+PiArCWlmICghaGF2ZV9mdW5jdGlvbl9kZXNjcmlwdG9y
cygpKSB7DQo+PiArCQlwcl9pbmZvKCJYRkFJTDogUGxhdGZvcm0gZG9lc24ndCB1c2UgZnVuY3Rp
b24gZGVzY3JpcHRvcnMuXG4iKTsNCj4+ICsJCXJldHVybjsNCj4+ICsJfQ0KPj4gKwlwcl9pbmZv
KCJhdHRlbXB0aW5nIGJhZCAlenUgYnl0ZXMgd3JpdGUgYXQgJXB4XG4iLCBzaXplLCBkb19ub3Ro
aW5nKTsNCj4+ICsJbWVtY3B5KGRvX25vdGhpbmcsIGRvX2FsbW9zdF9ub3RoaW5nLCBzaXplKTsN
Cj4+ICsJcHJfZXJyKCJGQUlMOiBzdXJ2aXZlZCBiYWQgd3JpdGVcbiIpOw0KPiANCj4gTm9uLWZ1
bmN0aW9uLWRlc2NyaXB0b3IgYXJjaGl0ZWN0dXJlcyB3b3VsZCBzdWNjZXNzZnVsbHkgY3Jhc2gg
YXQgdGhlDQo+IG1lbWNweSB0b28sIHJpZ2h0PyAoaS5lLiBmb3IgdGhlbSB0aGlzIGlzIGp1c3Qg
cmVwZWF0aW5nIFdSSVRFX0tFUk4pDQoNClllcyBpdCBzaG91bGQuIEJ1dCBub3QgZm9yIHRoZSBn
b29kIHJlYXNvbi4NCg0KPiANCj4gSSdtIHBvbmRlcmluZyB0aGUgdXRpbGl0eSBvZiB0aGUgWEZB
SUwgdnMganVzdCBsZXR0aW5nIGlzIHN1Y2NlZWQsIGJ1dCBJDQo+IHRoaW5rIGl0IG1vcmUgYWNj
dXJhdGUgdG8gc2F5ICJoZXksIG5vIE9QRCIgYXMgeW91IGhhdmUgaXQuDQo+IA0KPj4gKw0KPj4g
Kwlhc20oIiIgOiAiPW0iKGZ1bmMpKTsNCj4+ICsJZnVuYygpOw0KPj4gK30NCj4+ICsNCj4+ICAg
dm9pZCBsa2R0bV9FWEVDX0RBVEEodm9pZCkNCj4+ICAgew0KPj4gICAJZXhlY3V0ZV9sb2NhdGlv
bihkYXRhX2FyZWEsIENPREVfV1JJVEUpOw0KPj4gLS0gDQo+PiAyLjMxLjENCj4+DQo+IA0KPiBP
bmUgdGlueSBzdWdnZXN0aW9uLCBzaW5jZSBJIHRoaW5rIHlvdSBuZWVkIHRvIHJlc3BpbiBmb3Ig
dGhlDQo+IEVYUE9SVF9TWU1CT0xfR1BMKCkgYW55d2F5LiBQbGVhc2UgdXBkYXRlIHRoZSBzZWxm
dGVzdHMgdG9vOg0KPiANCj4gZGlmZiAtLWdpdCBhL3Rvb2xzL3Rlc3Rpbmcvc2VsZnRlc3RzL2xr
ZHRtL3Rlc3RzLnR4dCBiL3Rvb2xzL3Rlc3Rpbmcvc2VsZnRlc3RzL2xrZHRtL3Rlc3RzLnR4dA0K
PiBpbmRleCA2YjM2YjdmNWRjZjkuLjI0M2M3ODFmMDc4MCAxMDA2NDQNCj4gLS0tIGEvdG9vbHMv
dGVzdGluZy9zZWxmdGVzdHMvbGtkdG0vdGVzdHMudHh0DQo+ICsrKyBiL3Rvb2xzL3Rlc3Rpbmcv
c2VsZnRlc3RzL2xrZHRtL3Rlc3RzLnR4dA0KPiBAQCAtNDQsNiArNDQsNyBAQCBBQ0NFU1NfTlVM
TA0KPiAgIFdSSVRFX1JPDQo+ICAgV1JJVEVfUk9fQUZURVJfSU5JVA0KPiAgIFdSSVRFX0tFUk4N
Cj4gK1dSSVRFX09QRA0KPiAgIFJFRkNPVU5UX0lOQ19PVkVSRkxPVw0KPiAgIFJFRkNPVU5UX0FE
RF9PVkVSRkxPVw0KPiAgIFJFRkNPVU5UX0lOQ19OT1RfWkVST19PVkVSRkxPVw0KPiANCj4gKFRo
b3VnaCBmb3IgdGhlIGZ1dHVyZSBJJ3ZlIGJlZW4gY29uc2lkZXJpbmcgbWFraW5nIHRoZSBzZWxm
dGVzdHMgYW4NCj4gb3B0LW91dCBsaXN0IHNvIHRoZSAibm9ybWFsIiBzdHVmZiBkb2Vzbid0IG5l
ZWQgdG8ga2VlcCBnZXR0aW5nIGFkZGVkDQo+IHRoZXJlLikNCj4gDQo+IFRoYW5rcyENCj4gDQo+
IEFja2VkLWJ5OiBLZWVzIENvb2sgPGtlZXNjb29rQGNocm9taXVtLm9yZz4NCj4gDQoNCkRvbmUu
DQoNClRoYW5rcw0KQ2hyaXN0b3BoZQ=

^ permalink raw reply	[flat|nested] 99+ messages in thread

end of thread, other threads:[~2022-02-14 11:06 UTC | newest]

Thread overview: 99+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-10-17 12:38 [PATCH v3 00/12] Fix LKDTM for PPC64/IA64/PARISC Christophe Leroy
2021-10-17 12:38 ` Christophe Leroy
2021-10-17 12:38 ` Christophe Leroy
2021-10-17 12:38 ` [PATCH v3 01/12] powerpc: Move and rename func_descr_t Christophe Leroy
2021-10-17 12:38   ` Christophe Leroy
2021-10-17 12:38   ` Christophe Leroy
2021-10-18  5:58   ` Nicholas Piggin
2021-10-18  5:58     ` Nicholas Piggin
2021-10-18  5:58     ` Nicholas Piggin
2022-02-11  0:51   ` Kees Cook
2022-02-11  0:51     ` Kees Cook
2022-02-11  0:51     ` Kees Cook
2021-10-17 12:38 ` [PATCH v3 02/12] powerpc: Use 'struct func_desc' instead of 'struct ppc64_opd_entry' Christophe Leroy
2021-10-17 12:38   ` Christophe Leroy
2021-10-17 12:38   ` Christophe Leroy
2021-10-17 12:38 ` [PATCH v3 03/12] powerpc: Remove " Christophe Leroy
2021-10-17 12:38   ` Christophe Leroy
2021-10-17 12:38   ` Christophe Leroy
2021-10-17 12:38 ` [PATCH v3 04/12] powerpc: Prepare func_desc_t for refactorisation Christophe Leroy
2021-10-17 12:38   ` Christophe Leroy
2021-10-17 12:38   ` Christophe Leroy
2021-10-18  6:27   ` Nicholas Piggin
2021-10-18  6:27     ` Nicholas Piggin
2021-10-18  6:27     ` Nicholas Piggin
2021-10-18  7:08     ` Christophe Leroy
2021-10-18  7:08       ` Christophe Leroy
2021-10-18  7:08       ` Christophe Leroy
2022-02-11  0:54   ` Kees Cook
2022-02-11  0:54     ` Kees Cook
2022-02-11  0:54     ` Kees Cook
2022-02-11  7:39     ` Segher Boessenkool
2022-02-11  7:39       ` Segher Boessenkool
2022-02-11  7:39       ` Segher Boessenkool
2022-02-14 10:30     ` Christophe Leroy
2022-02-14 10:30       ` Christophe Leroy
2022-02-14 10:30       ` Christophe Leroy
2021-10-17 12:38 ` [PATCH v3 05/12] ia64: Rename 'ip' to 'addr' in 'struct fdesc' Christophe Leroy
2021-10-17 12:38   ` Christophe Leroy
2021-10-17 12:38   ` Christophe Leroy
2021-10-17 12:38 ` [PATCH v3 06/12] asm-generic: Define CONFIG_HAVE_FUNCTION_DESCRIPTORS Christophe Leroy
2021-10-17 12:38   ` Christophe Leroy
2021-10-17 12:38   ` Christophe Leroy
2021-10-17 12:38 ` [PATCH v3 07/12] asm-generic: Define 'func_desc_t' to commonly describe function descriptors Christophe Leroy
2021-10-17 12:38   ` Christophe Leroy
2021-10-17 12:38   ` Christophe Leroy
2021-10-18  6:29   ` Nicholas Piggin
2021-10-18  6:29     ` Nicholas Piggin
2021-10-18  6:29     ` Nicholas Piggin
2021-10-18  7:07     ` Christophe Leroy
2021-10-18  7:07       ` Christophe Leroy
2021-10-18  7:07       ` Christophe Leroy
2021-10-18  9:16       ` Nicholas Piggin
2021-10-18  9:16         ` Nicholas Piggin
2021-10-18  9:16         ` Nicholas Piggin
2021-10-17 12:38 ` [PATCH v3 08/12] asm-generic: Refactor dereference_[kernel]_function_descriptor() Christophe Leroy
2021-10-17 12:38   ` Christophe Leroy
2021-10-17 12:38   ` Christophe Leroy
2022-02-10 10:30   ` Michael Ellerman
2022-02-10 10:30     ` Michael Ellerman
2022-02-10 10:30     ` Michael Ellerman
2022-02-11  0:56     ` Kees Cook
2022-02-11  0:56       ` Kees Cook
2022-02-11  0:56       ` Kees Cook
2022-02-14 10:32       ` Christophe Leroy
2022-02-14 10:32         ` Christophe Leroy
2022-02-14 10:32         ` Christophe Leroy
2021-10-17 12:38 ` [PATCH v3 09/12] lkdtm: Force do_nothing() out of line Christophe Leroy
2021-10-17 12:38   ` Christophe Leroy
2021-10-17 12:38   ` Christophe Leroy
2021-10-17 12:38 ` [PATCH v3 10/12] lkdtm: Really write into kernel text in WRITE_KERN Christophe Leroy
2021-10-17 12:38   ` Christophe Leroy
2021-10-17 12:38   ` Christophe Leroy
2021-10-17 12:38 ` [PATCH v3 11/12] lkdtm: Fix execute_[user]_location() Christophe Leroy
2021-10-17 12:38   ` Christophe Leroy
2021-10-17 12:38   ` Christophe Leroy
2021-12-17 11:49   ` Christophe Leroy
2021-12-17 11:49     ` Christophe Leroy
2021-12-17 11:49     ` Christophe Leroy
2021-12-17 17:12     ` Helge Deller
2021-12-17 17:12       ` Helge Deller
2021-12-17 17:12       ` Helge Deller
2022-01-19 19:28     ` Christophe Leroy
2022-01-19 19:28       ` Christophe Leroy
2022-01-19 19:28       ` Christophe Leroy
2022-01-19 21:58       ` Kees Cook
2022-01-19 22:00         ` Kees Cook
2022-01-19 22:00         ` Kees Cook
2022-02-11  1:01   ` Kees Cook
2022-02-11  1:01     ` Kees Cook
2022-02-11  1:01     ` Kees Cook
2021-10-17 12:38 ` [PATCH v3 12/12] lkdtm: Add a test for function descriptors protection Christophe Leroy
2021-10-17 12:38   ` Christophe Leroy
2021-10-17 12:38   ` Christophe Leroy
2022-02-11  1:09   ` Kees Cook
2022-02-11  1:09     ` Kees Cook
2022-02-11  1:09     ` Kees Cook
2022-02-14 10:34     ` Christophe Leroy
2022-02-14 10:34       ` Christophe Leroy
2022-02-14 10:34       ` Christophe Leroy

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.