diff mbox series

[v6,4/6] x86/cet: Check feature_1 in TCB for active IBT and SHSTK

Message ID 20231229164354.182594-5-hjl.tools@gmail.com
State New
Headers show
Series x86/cet: Update CET kernel interface | expand

Commit Message

H.J. Lu Dec. 29, 2023, 4:43 p.m. UTC
Initially, IBT and SHSTK are marked as active when CPU supports them
and CET are enabled in glibc.  They can be disabled early by tunables
before relocation.  Since after relocation, GLRO(dl_x86_cpu_features)
becomes read-only, we can't update GLRO(dl_x86_cpu_features) to mark
IBT and SHSTK as inactive.  Instead, check the feature_1 field in TCB
to decide if IBT and SHST are active.
---
 sysdeps/x86/bits/platform/x86.h      |  8 ++++++++
 sysdeps/x86/get-cpuid-feature-leaf.c | 11 ++++++++++-
 sysdeps/x86/sys/platform/x86.h       | 17 +++++++++++++++++
 3 files changed, 35 insertions(+), 1 deletion(-)

Comments

Joseph Myers Jan. 10, 2024, 1:17 p.m. UTC | #1
On Fri, 29 Dec 2023, H.J. Lu wrote:

> diff --git a/sysdeps/x86/get-cpuid-feature-leaf.c b/sysdeps/x86/get-cpuid-feature-leaf.c
> index 9317a6b494..f69936b31e 100644
> --- a/sysdeps/x86/get-cpuid-feature-leaf.c
> +++ b/sysdeps/x86/get-cpuid-feature-leaf.c
> @@ -15,9 +15,18 @@
>     License along with the GNU C Library; if not, see
>     <https://www.gnu.org/licenses/>.  */
>  
> -
> +#include <assert.h>
> +#include <tcb-offsets.h>
>  #include <ldsodefs.h>
>  
> +#ifdef __x86_64__
> +# ifdef __LP64__
> +_Static_assert (FEATURE_1_OFFSET == 72, "FEATURE_1_OFFSET != 72");
> +# else
> +_Static_assert (FEATURE_1_OFFSET == 40, "FEATURE_1_OFFSET != 40");
> +# endif
> +#endif

I think this has broken the build for x86_64-gnu (Hurd).

In file included from ../include/features.h:503,
                 from ../assert/assert.h:35,
                 from ../include/assert.h:1,
                 from ../sysdeps/x86/get-cpuid-feature-leaf.c:18:
../sysdeps/x86/get-cpuid-feature-leaf.c:24:17: error: ‘FEATURE_1_OFFSET’ undeclared here (not in a function)
   24 | _Static_assert (FEATURE_1_OFFSET == 72, "FEATURE_1_OFFSET != 72");
      |                 ^~~~~~~~~~~~~~~~
../include/sys/cdefs.h:7:59: note: in definition of macro ‘_Static_assert’
    7 | # define _Static_assert(expr, diagnostic) _Static_assert (expr, diagnostic)
      |                                                           ^~~~
../sysdeps/x86/get-cpuid-feature-leaf.c:24:17: error: expression in static assertion is not an integer
   24 | _Static_assert (FEATURE_1_OFFSET == 72, "FEATURE_1_OFFSET != 72");
      |                 ^~~~~~~~~~~~~~~~
../include/sys/cdefs.h:7:59: note: in definition of macro ‘_Static_assert’
    7 | # define _Static_assert(expr, diagnostic) _Static_assert (expr, diagnostic)
      |                                                           ^~~~

Note that FEATURE_1_OFFSET is defined in 
sysdeps/x86_64/nptl/tcb-offsets.sym - which is NPTL-specific, so not used 
for Hurd.
H.J. Lu Jan. 10, 2024, 4:32 p.m. UTC | #2
On Wed, Jan 10, 2024 at 5:20 AM Joseph Myers <josmyers@redhat.com> wrote:
>
> On Fri, 29 Dec 2023, H.J. Lu wrote:
>
> > diff --git a/sysdeps/x86/get-cpuid-feature-leaf.c b/sysdeps/x86/get-cpuid-feature-leaf.c
> > index 9317a6b494..f69936b31e 100644
> > --- a/sysdeps/x86/get-cpuid-feature-leaf.c
> > +++ b/sysdeps/x86/get-cpuid-feature-leaf.c
> > @@ -15,9 +15,18 @@
> >     License along with the GNU C Library; if not, see
> >     <https://www.gnu.org/licenses/>.  */
> >
> > -
> > +#include <assert.h>
> > +#include <tcb-offsets.h>
> >  #include <ldsodefs.h>
> >
> > +#ifdef __x86_64__
> > +# ifdef __LP64__
> > +_Static_assert (FEATURE_1_OFFSET == 72, "FEATURE_1_OFFSET != 72");
> > +# else
> > +_Static_assert (FEATURE_1_OFFSET == 40, "FEATURE_1_OFFSET != 40");
> > +# endif
> > +#endif
>
> I think this has broken the build for x86_64-gnu (Hurd).
>
> In file included from ../include/features.h:503,
>                  from ../assert/assert.h:35,
>                  from ../include/assert.h:1,
>                  from ../sysdeps/x86/get-cpuid-feature-leaf.c:18:
> ../sysdeps/x86/get-cpuid-feature-leaf.c:24:17: error: ‘FEATURE_1_OFFSET’ undeclared here (not in a function)
>    24 | _Static_assert (FEATURE_1_OFFSET == 72, "FEATURE_1_OFFSET != 72");
>       |                 ^~~~~~~~~~~~~~~~
> ../include/sys/cdefs.h:7:59: note: in definition of macro ‘_Static_assert’
>     7 | # define _Static_assert(expr, diagnostic) _Static_assert (expr, diagnostic)
>       |                                                           ^~~~
> ../sysdeps/x86/get-cpuid-feature-leaf.c:24:17: error: expression in static assertion is not an integer
>    24 | _Static_assert (FEATURE_1_OFFSET == 72, "FEATURE_1_OFFSET != 72");
>       |                 ^~~~~~~~~~~~~~~~
> ../include/sys/cdefs.h:7:59: note: in definition of macro ‘_Static_assert’
>     7 | # define _Static_assert(expr, diagnostic) _Static_assert (expr, diagnostic)
>       |                                                           ^~~~
>
> Note that FEATURE_1_OFFSET is defined in
> sysdeps/x86_64/nptl/tcb-offsets.sym - which is NPTL-specific, so not used
> for Hurd.
>

Testing a fix.

Thanks.
H.J. Lu Jan. 10, 2024, 4:50 p.m. UTC | #3
On Wed, Jan 10, 2024 at 8:32 AM H.J. Lu <hjl.tools@gmail.com> wrote:
>
> On Wed, Jan 10, 2024 at 5:20 AM Joseph Myers <josmyers@redhat.com> wrote:
> >
> > On Fri, 29 Dec 2023, H.J. Lu wrote:
> >
> > > diff --git a/sysdeps/x86/get-cpuid-feature-leaf.c b/sysdeps/x86/get-cpuid-feature-leaf.c
> > > index 9317a6b494..f69936b31e 100644
> > > --- a/sysdeps/x86/get-cpuid-feature-leaf.c
> > > +++ b/sysdeps/x86/get-cpuid-feature-leaf.c
> > > @@ -15,9 +15,18 @@
> > >     License along with the GNU C Library; if not, see
> > >     <https://www.gnu.org/licenses/>.  */
> > >
> > > -
> > > +#include <assert.h>
> > > +#include <tcb-offsets.h>
> > >  #include <ldsodefs.h>
> > >
> > > +#ifdef __x86_64__
> > > +# ifdef __LP64__
> > > +_Static_assert (FEATURE_1_OFFSET == 72, "FEATURE_1_OFFSET != 72");
> > > +# else
> > > +_Static_assert (FEATURE_1_OFFSET == 40, "FEATURE_1_OFFSET != 40");
> > > +# endif
> > > +#endif
> >
> > I think this has broken the build for x86_64-gnu (Hurd).
> >
> > In file included from ../include/features.h:503,
> >                  from ../assert/assert.h:35,
> >                  from ../include/assert.h:1,
> >                  from ../sysdeps/x86/get-cpuid-feature-leaf.c:18:
> > ../sysdeps/x86/get-cpuid-feature-leaf.c:24:17: error: ‘FEATURE_1_OFFSET’ undeclared here (not in a function)
> >    24 | _Static_assert (FEATURE_1_OFFSET == 72, "FEATURE_1_OFFSET != 72");
> >       |                 ^~~~~~~~~~~~~~~~
> > ../include/sys/cdefs.h:7:59: note: in definition of macro ‘_Static_assert’
> >     7 | # define _Static_assert(expr, diagnostic) _Static_assert (expr, diagnostic)
> >       |                                                           ^~~~
> > ../sysdeps/x86/get-cpuid-feature-leaf.c:24:17: error: expression in static assertion is not an integer
> >    24 | _Static_assert (FEATURE_1_OFFSET == 72, "FEATURE_1_OFFSET != 72");
> >       |                 ^~~~~~~~~~~~~~~~
> > ../include/sys/cdefs.h:7:59: note: in definition of macro ‘_Static_assert’
> >     7 | # define _Static_assert(expr, diagnostic) _Static_assert (expr, diagnostic)
> >       |                                                           ^~~~
> >
> > Note that FEATURE_1_OFFSET is defined in
> > sysdeps/x86_64/nptl/tcb-offsets.sym - which is NPTL-specific, so not used
> > for Hurd.
> >
>
> Testing a fix.
>

Here is the patch:

https://patchwork.sourceware.org/project/glibc/patch/20240110164847.3304707-1-hjl.tools@gmail.com/
diff mbox series

Patch

diff --git a/sysdeps/x86/bits/platform/x86.h b/sysdeps/x86/bits/platform/x86.h
index 1e23d53ba2..1575ae53fb 100644
--- a/sysdeps/x86/bits/platform/x86.h
+++ b/sysdeps/x86/bits/platform/x86.h
@@ -337,3 +337,11 @@  enum
   x86_cpu_AVX10_YMM = x86_cpu_index_24_ecx_0_ebx + 17,
   x86_cpu_AVX10_ZMM = x86_cpu_index_24_ecx_0_ebx + 18,
 };
+
+/* Bits in the feature_1 field in TCB.  */
+
+enum
+{
+  x86_feature_1_ibt		= 1U << 0,
+  x86_feature_1_shstk		= 1U << 1
+};
diff --git a/sysdeps/x86/get-cpuid-feature-leaf.c b/sysdeps/x86/get-cpuid-feature-leaf.c
index 9317a6b494..f69936b31e 100644
--- a/sysdeps/x86/get-cpuid-feature-leaf.c
+++ b/sysdeps/x86/get-cpuid-feature-leaf.c
@@ -15,9 +15,18 @@ 
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-
+#include <assert.h>
+#include <tcb-offsets.h>
 #include <ldsodefs.h>
 
+#ifdef __x86_64__
+# ifdef __LP64__
+_Static_assert (FEATURE_1_OFFSET == 72, "FEATURE_1_OFFSET != 72");
+# else
+_Static_assert (FEATURE_1_OFFSET == 40, "FEATURE_1_OFFSET != 40");
+# endif
+#endif
+
 const struct cpuid_feature *
 __x86_get_cpuid_feature_leaf (unsigned int leaf)
 {
diff --git a/sysdeps/x86/sys/platform/x86.h b/sysdeps/x86/sys/platform/x86.h
index 1ea2c5fc0b..89b1b16f22 100644
--- a/sysdeps/x86/sys/platform/x86.h
+++ b/sysdeps/x86/sys/platform/x86.h
@@ -45,6 +45,23 @@  x86_cpu_present (unsigned int __index)
 static __inline__ _Bool
 x86_cpu_active (unsigned int __index)
 {
+  if (__index == x86_cpu_IBT || __index == x86_cpu_SHSTK)
+    {
+#ifdef __x86_64__
+      unsigned int __feature_1;
+# ifdef __LP64__
+      __asm__ ("mov %%fs:72, %0" : "=r" (__feature_1));
+# else
+      __asm__ ("mov %%fs:40, %0" : "=r" (__feature_1));
+# endif
+      if (__index == x86_cpu_IBT)
+	return __feature_1 & x86_feature_1_ibt;
+      else
+	return __feature_1 & x86_feature_1_shstk;
+#else
+      return false;
+#endif
+    }
   const struct cpuid_feature *__ptr = __x86_get_cpuid_feature_leaf
     (__index / (8 * sizeof (unsigned int) * 4));
   unsigned int __reg