Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PAC][clang] Add signed GOT cc1 flag #96160

Merged
merged 1 commit into from
Nov 19, 2024

Conversation

kovdan01
Copy link
Contributor

@kovdan01 kovdan01 commented Jun 20, 2024

Add -fptrauth-elf-got clang cc1 flag and set ptrauth_elf_got preprocessor feature and PointerAuthELFGOT LangOption correspondingly. No additional checks like ensuring OS binary format is ELF are performed: it should be done on clang driver level when a pauth-enabled environment implying signed GOT enabled is requested.

If the cc1 flag is passed, "ptrauth-elf-got" IR module flag is set.

@kovdan01 kovdan01 self-assigned this Jun 20, 2024
@kovdan01 kovdan01 requested review from damyanp, MaskRay, sudonatalie, asl and smithp35 and removed request for damyanp and MaskRay June 20, 2024 11:25
@kovdan01 kovdan01 marked this pull request as ready for review June 20, 2024 11:25
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Jun 20, 2024
@llvmbot
Copy link
Member

llvmbot commented Jun 20, 2024

@llvm/pr-subscribers-clang-codegen
@llvm/pr-subscribers-llvm-binary-utilities
@llvm/pr-subscribers-backend-aarch64
@llvm/pr-subscribers-clang-driver

@llvm/pr-subscribers-clang

Author: Daniil Kovalev (kovdan01)

Changes

Depends on #96159

Add -fptrauth-elf-got clang driver flag and set ptrauth_elf_got preprocessor feature and PointerAuthELFGOT LangOption correspondingly. For non-ELF triples, the driver flag is ignored and a warning is emitted.


Full diff: https://github.com/llvm/llvm-project/pull/96160.diff

8 Files Affected:

  • (modified) clang/include/clang/Basic/DiagnosticDriverKinds.td (+4)
  • (modified) clang/include/clang/Basic/Features.def (+1)
  • (modified) clang/include/clang/Driver/Options.td (+1)
  • (modified) clang/lib/Driver/ToolChains/Clang.cpp (+7)
  • (modified) clang/lib/Frontend/CompilerInvocation.cpp (+4)
  • (modified) clang/test/CodeGen/aarch64-elf-pauthabi.c (+9-2)
  • (modified) clang/test/Driver/aarch64-ptrauth.c (+8-1)
  • (modified) clang/test/Preprocessor/ptrauth_feature.c (+38-14)
diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index 1ca2cb85565a1..28667b1eb239e 100644
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -742,6 +742,10 @@ def warn_drv_fjmc_for_elf_only : Warning<
   "-fjmc works only for ELF; option ignored">,
   InGroup<OptionIgnored>;
 
+def warn_drv_ptrauth_elf_got_for_elf_only : Warning<
+  "-fptrauth-elf-got works only for ELF; option ignored">,
+  InGroup<OptionIgnored>;
+
 def warn_target_override_arm64ec : Warning<
   "/arm64EC has been overridden by specified target: %0; option ignored">,
   InGroup<OptionIgnored>;
diff --git a/clang/include/clang/Basic/Features.def b/clang/include/clang/Basic/Features.def
index 53f410d3cb4bd..569f4e1715af5 100644
--- a/clang/include/clang/Basic/Features.def
+++ b/clang/include/clang/Basic/Features.def
@@ -110,6 +110,7 @@ FEATURE(ptrauth_vtable_pointer_address_discrimination, LangOpts.PointerAuthVTPtr
 FEATURE(ptrauth_vtable_pointer_type_discrimination, LangOpts.PointerAuthVTPtrTypeDiscrimination)
 FEATURE(ptrauth_member_function_pointer_type_discrimination, LangOpts.PointerAuthCalls)
 FEATURE(ptrauth_init_fini, LangOpts.PointerAuthInitFini)
+FEATURE(ptrauth_elf_got, LangOpts.PointerAuthELFGOT)
 EXTENSION(swiftcc,
   PP.getTargetInfo().checkCallingConvention(CC_Swift) ==
   clang::TargetInfo::CCCR_OK)
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 112eb286eb075..e16c1a0d06a1b 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -4222,6 +4222,7 @@ defm ptrauth_vtable_pointer_address_discrimination :
 defm ptrauth_vtable_pointer_type_discrimination :
   OptInCC1FFlag<"ptrauth-vtable-pointer-type-discrimination", "Enable type discrimination of vtable pointers">;
 defm ptrauth_init_fini : OptInCC1FFlag<"ptrauth-init-fini", "Enable signing of function pointers in init/fini arrays">;
+defm ptrauth_elf_got : OptInCC1FFlag<"ptrauth-elf-got", "Enable authentication of pointers from GOT (ELF only)">;
 }
 
 def fenable_matrix : Flag<["-"], "fenable-matrix">, Group<f_Group>,
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 331cf6e713d89..5f55e79ec206b 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -1788,6 +1788,13 @@ void Clang::AddAArch64TargetArgs(const ArgList &Args,
       options::OPT_fno_ptrauth_vtable_pointer_type_discrimination);
   Args.addOptInFlag(CmdArgs, options::OPT_fptrauth_init_fini,
                     options::OPT_fno_ptrauth_init_fini);
+
+  Args.addOptInFlag(CmdArgs, options::OPT_fptrauth_elf_got,
+                    options::OPT_fno_ptrauth_elf_got);
+
+  if (Args.hasArg(options::OPT_fptrauth_elf_got))
+    getToolChain().getDriver().Diag(
+        diag::warn_drv_ptrauth_elf_got_for_elf_only);
 }
 
 void Clang::AddLoongArchTargetArgs(const ArgList &Args,
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 58694e5399d58..97a5408a4c1e0 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -3361,6 +3361,8 @@ static void GeneratePointerAuthArgs(const LangOptions &Opts,
     GenerateArg(Consumer, OPT_fptrauth_vtable_pointer_type_discrimination);
   if (Opts.PointerAuthInitFini)
     GenerateArg(Consumer, OPT_fptrauth_init_fini);
+  if (Opts.PointerAuthELFGOT)
+    GenerateArg(Consumer, OPT_fptrauth_elf_got);
 }
 
 static void ParsePointerAuthArgs(LangOptions &Opts, ArgList &Args,
@@ -3374,6 +3376,7 @@ static void ParsePointerAuthArgs(LangOptions &Opts, ArgList &Args,
   Opts.PointerAuthVTPtrTypeDiscrimination =
       Args.hasArg(OPT_fptrauth_vtable_pointer_type_discrimination);
   Opts.PointerAuthInitFini = Args.hasArg(OPT_fptrauth_init_fini);
+  Opts.PointerAuthELFGOT = Args.hasArg(OPT_fptrauth_elf_got);
 }
 
 /// Check if input file kind and language standard are compatible.
@@ -4728,6 +4731,7 @@ bool CompilerInvocation::CreateFromArgsImpl(
   ParseAPINotesArgs(Res.getAPINotesOpts(), Args, Diags);
 
   ParsePointerAuthArgs(LangOpts, Args, Diags);
+  LangOpts.PointerAuthELFGOT &= T.isOSBinFormatELF();
 
   ParseLangArgs(LangOpts, Args, DashX, T, Res.getPreprocessorOpts().Includes,
                 Diags);
diff --git a/clang/test/CodeGen/aarch64-elf-pauthabi.c b/clang/test/CodeGen/aarch64-elf-pauthabi.c
index aa83ee3e0d7b0..df675563b331f 100644
--- a/clang/test/CodeGen/aarch64-elf-pauthabi.c
+++ b/clang/test/CodeGen/aarch64-elf-pauthabi.c
@@ -5,7 +5,8 @@
 // RUN:   -fptrauth-auth-traps \
 // RUN:   -fptrauth-vtable-pointer-address-discrimination \
 // RUN:   -fptrauth-vtable-pointer-type-discrimination \
-// RUN:   -fptrauth-init-fini %s | \
+// RUN:   -fptrauth-init-fini \
+// RUN:   -fptrauth-elf-got %s | \
 // RUN:   FileCheck %s --check-prefix=ALL
 
 // RUN: %clang_cc1 -triple aarch64-linux -emit-llvm -o - \
@@ -32,8 +33,11 @@
 // RUN:   -fptrauth-calls -fptrauth-init-fini %s | \
 // RUN:   FileCheck %s --check-prefix=INITFINI
 
+// RUN: %clang --target=aarch64-linux -S -emit-llvm -o - \
+// RUN:   -fptrauth-elf-got %s | FileCheck %s --check-prefix=ELFGOT
+
 // ALL: !{i32 1, !"aarch64-elf-pauthabi-platform", i32 268435458}
-// ALL: !{i32 1, !"aarch64-elf-pauthabi-version", i32 127}
+// ALL: !{i32 1, !"aarch64-elf-pauthabi-version", i32 255}
 
 // INTRIN: !{i32 1, !"aarch64-elf-pauthabi-platform", i32 268435458}
 // INTRIN: !{i32 1, !"aarch64-elf-pauthabi-version", i32 1}
@@ -56,4 +60,7 @@
 // INITFINI: !{i32 1, !"aarch64-elf-pauthabi-platform", i32 268435458}
 // INITFINI: !{i32 1, !"aarch64-elf-pauthabi-version", i32 66}
 
+// ELFGOT: !{i32 1, !"aarch64-elf-pauthabi-platform", i32 268435458}
+// ELFGOT: !{i32 1, !"aarch64-elf-pauthabi-version", i32 128}
+
 void foo() {}
diff --git a/clang/test/Driver/aarch64-ptrauth.c b/clang/test/Driver/aarch64-ptrauth.c
index fa0125f4b22a9..e568ea4843e9b 100644
--- a/clang/test/Driver/aarch64-ptrauth.c
+++ b/clang/test/Driver/aarch64-ptrauth.c
@@ -13,9 +13,15 @@
 // RUN:   %s 2>&1 | FileCheck %s --check-prefix=ALL
 // ALL: "-cc1"{{.*}} "-fptrauth-intrinsics" "-fptrauth-calls" "-fptrauth-returns" "-fptrauth-auth-traps" "-fptrauth-vtable-pointer-address-discrimination" "-fptrauth-vtable-pointer-type-discrimination" "-fptrauth-init-fini"
 
+// RUN: %clang -### -c --target=aarch64-elf -fno-ptrauth-elf-got -fptrauth-elf-got %s 2>&1 | FileCheck %s --check-prefix=ELFGOT
+// ELFGOT: "-cc1"{{.*}} "-fptrauth-elf-got"
+
+// RUN: %clang -### -c --target=aarch64-darwin -fptrauth-elf-got %s 2>&1 | FileCheck %s --check-prefix=NOELFGOT
+// NOELFGOT: warning: -fptrauth-elf-got works only for ELF; option ignored [-Woption-ignored]
+
 // RUN: not %clang -### -c --target=x86_64 -fptrauth-intrinsics -fptrauth-calls -fptrauth-returns -fptrauth-auth-traps \
 // RUN:   -fptrauth-vtable-pointer-address-discrimination -fptrauth-vtable-pointer-type-discrimination \
-// RUN:   -fptrauth-init-fini %s 2>&1 | FileCheck %s --check-prefix=ERR
+// RUN:   -fptrauth-init-fini -fptrauth-elf-got %s 2>&1 | FileCheck %s --check-prefix=ERR
 // ERR:      error: unsupported option '-fptrauth-intrinsics' for target '{{.*}}'
 // ERR-NEXT: error: unsupported option '-fptrauth-calls' for target '{{.*}}'
 // ERR-NEXT: error: unsupported option '-fptrauth-returns' for target '{{.*}}'
@@ -23,3 +29,4 @@
 // ERR-NEXT: error: unsupported option '-fptrauth-vtable-pointer-address-discrimination' for target '{{.*}}'
 // ERR-NEXT: error: unsupported option '-fptrauth-vtable-pointer-type-discrimination' for target '{{.*}}'
 // ERR-NEXT: error: unsupported option '-fptrauth-init-fini' for target '{{.*}}'
+// ERR-NEXT: error: unsupported option '-fptrauth-elf-got' for target '{{.*}}'
diff --git a/clang/test/Preprocessor/ptrauth_feature.c b/clang/test/Preprocessor/ptrauth_feature.c
index 80e239110ffc7..ba256384199fe 100644
--- a/clang/test/Preprocessor/ptrauth_feature.c
+++ b/clang/test/Preprocessor/ptrauth_feature.c
@@ -4,56 +4,72 @@
 // RUN:   -fptrauth-returns \
 // RUN:   -fptrauth-vtable-pointer-address-discrimination \
 // RUN:   -fptrauth-vtable-pointer-type-discrimination \
-// RUN:   -fptrauth-init-fini | \
-// RUN:   FileCheck %s --check-prefixes=INTRIN,CALLS,RETS,VPTR_ADDR_DISCR,VPTR_TYPE_DISCR,INITFINI
+// RUN:   -fptrauth-init-fini \
+// RUN:   -fptrauth-elf-got | \
+// RUN:   FileCheck %s --check-prefixes=INTRIN,CALLS,RETS,VPTR_ADDR_DISCR,VPTR_TYPE_DISCR,INITFINI,ELFGOT
 
 // RUN: %clang_cc1 -E %s -triple=aarch64 \
 // RUN:   -fptrauth-calls \
 // RUN:   -fptrauth-returns \
 // RUN:   -fptrauth-vtable-pointer-address-discrimination \
 // RUN:   -fptrauth-vtable-pointer-type-discrimination \
-// RUN:   -fptrauth-init-fini | \
-// RUN:   FileCheck %s --check-prefixes=NOINTRIN,CALLS,RETS,VPTR_ADDR_DISCR,VPTR_TYPE_DISCR,INITFINI
+// RUN:   -fptrauth-init-fini \
+// RUN:   -fptrauth-elf-got | \
+// RUN:   FileCheck %s --check-prefixes=NOINTRIN,CALLS,RETS,VPTR_ADDR_DISCR,VPTR_TYPE_DISCR,INITFINI,ELFGOT
 
 // RUN: %clang_cc1 -E %s -triple=aarch64 \
 // RUN:   -fptrauth-intrinsics \
 // RUN:   -fptrauth-returns \
 // RUN:   -fptrauth-vtable-pointer-address-discrimination \
 // RUN:   -fptrauth-vtable-pointer-type-discrimination \
-// RUN:   -fptrauth-init-fini | \
-// RUN:   FileCheck %s --check-prefixes=INTRIN,NOCALLS,RETS,VPTR_ADDR_DISCR,VPTR_TYPE_DISCR,INITFINI
+// RUN:   -fptrauth-init-fini \
+// RUN:   -fptrauth-elf-got | \
+// RUN:   FileCheck %s --check-prefixes=INTRIN,NOCALLS,RETS,VPTR_ADDR_DISCR,VPTR_TYPE_DISCR,INITFINI,ELFGOT
 
 // RUN: %clang_cc1 -E %s -triple=aarch64 \
 // RUN:   -fptrauth-intrinsics \
 // RUN:   -fptrauth-calls \
 // RUN:   -fptrauth-vtable-pointer-address-discrimination \
 // RUN:   -fptrauth-vtable-pointer-type-discrimination \
-// RUN:   -fptrauth-init-fini | \
-// RUN:   FileCheck %s --check-prefixes=INTRIN,CALLS,NORETS,VPTR_ADDR_DISCR,VPTR_TYPE_DISCR,INITFINI
+// RUN:   -fptrauth-init-fini \
+// RUN:   -fptrauth-elf-got | \
+// RUN:   FileCheck %s --check-prefixes=INTRIN,CALLS,NORETS,VPTR_ADDR_DISCR,VPTR_TYPE_DISCR,INITFINI,ELFGOT
 
 // RUN: %clang_cc1 -E %s -triple=aarch64 \
 // RUN:   -fptrauth-intrinsics \
 // RUN:   -fptrauth-calls \
 // RUN:   -fptrauth-returns \
 // RUN:   -fptrauth-vtable-pointer-type-discrimination \
-// RUN:   -fptrauth-init-fini | \
-// RUN:   FileCheck %s --check-prefixes=INTRIN,CALLS,RETS,NOVPTR_ADDR_DISCR,VPTR_TYPE_DISCR,INITFINI
+// RUN:   -fptrauth-init-fini \
+// RUN:   -fptrauth-elf-got | \
+// RUN:   FileCheck %s --check-prefixes=INTRIN,CALLS,RETS,NOVPTR_ADDR_DISCR,VPTR_TYPE_DISCR,INITFINI,ELFGOT
 
 // RUN: %clang_cc1 -E %s -triple=aarch64 \
 // RUN:   -fptrauth-intrinsics \
 // RUN:   -fptrauth-calls \
 // RUN:   -fptrauth-returns \
 // RUN:   -fptrauth-vtable-pointer-address-discrimination \
-// RUN:   -fptrauth-init-fini | \
-// RUN:   FileCheck %s --check-prefixes=INTRIN,CALLS,RETS,VPTR_ADDR_DISCR,NOVPTR_TYPE_DISCR,INITFINI
+// RUN:   -fptrauth-init-fini \
+// RUN:   -fptrauth-elf-got | \
+// RUN:   FileCheck %s --check-prefixes=INTRIN,CALLS,RETS,VPTR_ADDR_DISCR,NOVPTR_TYPE_DISCR,INITFINI,ELFGOT
+
+// RUN: %clang_cc1 -E %s -triple=aarch64 \
+// RUN:   -fptrauth-intrinsics \
+// RUN:   -fptrauth-calls \
+// RUN:   -fptrauth-returns \
+// RUN:   -fptrauth-vtable-pointer-address-discrimination \
+// RUN:   -fptrauth-vtable-pointer-type-discrimination \
+// RUN:   -fptrauth-elf-got | \
+// RUN:   FileCheck %s --check-prefixes=INTRIN,CALLS,RETS,VPTR_ADDR_DISCR,VPTR_TYPE_DISCR,NOINITFINI,ELFGOT
 
 // RUN: %clang_cc1 -E %s -triple=aarch64 \
 // RUN:   -fptrauth-intrinsics \
 // RUN:   -fptrauth-calls \
 // RUN:   -fptrauth-returns \
 // RUN:   -fptrauth-vtable-pointer-address-discrimination \
-// RUN:   -fptrauth-vtable-pointer-type-discrimination | \
-// RUN:   FileCheck %s --check-prefixes=INTRIN,CALLS,RETS,VPTR_ADDR_DISCR,VPTR_TYPE_DISCR,NOINITFINI
+// RUN:   -fptrauth-vtable-pointer-type-discrimination \
+// RUN:   -fptrauth-init-fini | \
+// RUN:   FileCheck %s --check-prefixes=INTRIN,CALLS,RETS,VPTR_ADDR_DISCR,VPTR_TYPE_DISCR,INITFINI,NOELFGOT
 
 #if __has_feature(ptrauth_intrinsics)
 // INTRIN: has_ptrauth_intrinsics
@@ -111,3 +127,11 @@ void has_ptrauth_init_fini() {}
 // NOINITFINI: no_ptrauth_init_fini
 void no_ptrauth_init_fini() {}
 #endif
+
+#if __has_feature(ptrauth_elf_got)
+// ELFGOT: has_ptrauth_elf_got
+void has_ptrauth_elf_got() {}
+#else
+// NOELFGOT: no_ptrauth_elf_got
+void no_ptrauth_elf_got() {}
+#endif

@MaskRay
Copy link
Member

MaskRay commented Jun 21, 2024

Do we want a lot of -fptrauth-xxx instead of -fptrauth-something=xxx,yyy,zzz?

@asl
Copy link
Collaborator

asl commented Jun 21, 2024

Do we want a lot of -fptrauth-xxx instead of -fptrauth-something=xxx,yyy,zzz?

I would lean towards a single flag. However, I do not know how this would affect Apple downstream and what are preferences there.

Tagging @ahmedbougacha @ahatanak @ojhunt

@damyanp damyanp removed their request for review June 21, 2024 20:06
@kovdan01 kovdan01 added this to the LLVM 19.X Release milestone Jun 24, 2024
@ahmedbougacha
Copy link
Member

ahmedbougacha commented Jun 26, 2024

Do we want a lot of -fptrauth-xxx instead of -fptrauth-something=xxx,yyy,zzz?

I would lean towards a single flag.

Comma-separated flags generally seem less user-friendly (for, e.g., grepping, modifying, reading). To some extent we can mitigate that with the obvious cleverness (e.g., negatives, repetition), at the cost of a lot more driver logic, and even that would only go so far.

Is there a compelling argument for them?

However, I do not know how this would affect Apple downstream and what are preferences there.

Yeah, we do already support the long spellings, but we can change these here if we have consensus, and it should be doable to support the long spellings on top of these.

I should mention that in our world we generally don't expect these to be common (other than in cc1 invocations), and they're generally used for overriding default ABI behavior inferred from triples and deployment targets and whatnot.
@asl I don't know what you folks have in mind for users; if they're expected to pass these separately, that might be a worth a separate mechanism to define a set of these for a given ABI. Having that mechanism be comma-separated (rather than some sort of meaningful name) seems inconvenient for the reasons above.

@kovdan01
Copy link
Contributor Author

kovdan01 commented Jul 1, 2024

@ahmedbougacha

I should mention that in our world we generally don't expect these to be common (other than in cc1 invocations), and they're generally used for overriding default ABI behavior inferred from triples and deployment targets and whatnot.

We also don't expect usage of these options to be common - instead, we propose -mbranch-protection=pauthabi option which enables a pre-defined set of ptrauth flags, see #97237.

I think that the main rationale for using comma-separated flags instead of a bunch of different flags is that it'll reduce unneeded -fptrauth- duplication - such duplication is probably undesirable even in cc1 invocations.

and it should be doable to support the long spellings on top of these.

Regarding that: I'm not sure if it's a good idea to support both -fptrauth-xxx -fptrauth-yyy and -fptrauth=xxx,yyy. It'll result in additional logic for handling conflicts if the same flags are defined in different ways. It's probably not too complex, but it'll make things more messy, and I don't think it's what we are trying to achive.

@kovdan01
Copy link
Contributor Author

kovdan01 commented Jul 1, 2024

@MaskRay @ahmedbougacha @asl I suggest to move the discussion on comma-separated flags/current flags to an issue #97320. This PR is intended to introduce the signed GOT flag, and we already have a bunch of similar ptrauth flags, so, if we want to change the flags to a single comma-separated value, we need to do that as a separate refactoring PR but not here. As for this PR, I suggest to stick with old convention not to make this a blocker.

@MaskRay please let me know if you have other issues with proposed changes except suggestion to use comma-separated flags.

@kovdan01
Copy link
Contributor Author

kovdan01 commented Jul 5, 2024

Ping: would be glad to see feedback on the changes from those who are interested.

1 similar comment
@kovdan01
Copy link
Contributor Author

Ping: would be glad to see feedback on the changes from those who are interested.

@kovdan01
Copy link
Contributor Author

Ping: would be glad to see feedback on the changes from those who are interested.

@kovdan01
Copy link
Contributor Author

Ping: would be glad to see feedback on the changes from those who are interested.

Tagging @MaskRay @smithp35

Copy link
Collaborator

@smithp35 smithp35 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this need a clang command line option at this point? Would it be possible to live with a {{-mllvm}} option to turn on signed GOT? I would expect signed GOT (or not) would be part of a higher-level signing schema and not toggled at a low-level via clang.

I know that there are existing command-line options for other signing schema affecting options, but I'm not sure if we want to add more to them.

@kovdan01
Copy link
Contributor Author

Does this need a clang command line option at this point? Would it be possible to live with a {{-mllvm}} option to turn on signed GOT? I would expect signed GOT (or not) would be part of a higher-level signing schema and not toggled at a low-level via clang.

I know that there are existing command-line options for other signing schema affecting options, but I'm not sure if we want to add more to them.

@smithp35 Theoretically, we can use -mllvm and it was actually used for some time during downstream implementation and testing. I agree that a ton of -fptrauth-* flags is pretty annoying (and there was already a discussion in this PR which I've transformed into an issue #97320).

However, as you correctly mentioned, we already have other similar flags and they are also not intended to be used manually and, instead, should be a part of high-level signing schema. As for me, it's better to keep things consistent at each moment - if we use clang driver flags, we use them everywhere, and if we want to refactor that and move to -mllvm, we want to do that for all the ptrauth flags as well.

So, if it's not a very huge concern right now, I'd prefer to introduce -fptrauth-elf-got flag in this PR and, after further discussion, probably refactor all the flags logic in subsequent PRs (either move to comma-separeted flags as discussed above or use -mllvm or, maybe, we'll find other ways to enhance this - it's still needs to be discussed).

@kovdan01 kovdan01 requested a review from smithp35 July 22, 2024 11:53
@MaskRay
Copy link
Member

MaskRay commented Jul 22, 2024

Sorry, I haven't spent a lot of time on the review and the user interface. -mllvm and -Xclang options are for internal testing and might change names or disappear in the future. Driver options offer more stability for users.

Given the complexity of the feature and lack of upstream runtime linker (rtld) support, it might be wise to delay exposing it through driver options until it's more mature. What do you think?

@kovdan01
Copy link
Contributor Author

and lack of upstream runtime linker (rtld) support

@MaskRay We actually have proof-of-concept support for musl access-softek/musl@cbf25fb (probably not ready for meaningful production usage though), and the signed GOT implementation which is submitted to upstream via multiple PRs (including this one) is actually working: I'm able to run binaries compiled and linked with signed GOT (and also -z pac-plt for signed PLT GOT, but it's a different story).

So, as for me we can expose the flag right now.

@MaskRay
Copy link
Member

MaskRay commented Jul 22, 2024

and lack of upstream runtime linker (rtld) support

@MaskRay We actually have proof-of-concept support for musl access-softek/musl@cbf25fb (probably not ready for meaningful production usage though), and the signed GOT implementation which is submitted to upstream via multiple PRs (including this one) is actually working: I'm able to run binaries compiled and linked with signed GOT (and also -z pac-plt for signed PLT GOT, but it's a different story).

So, as for me we can expose the flag right now.

Yes, I know there is a musl fork, but it's not the official upstream. musl project tends to be cautious when accepting hardening features. Additionally, deployment experience might be limited.

There are many examples we don't expose driver options:

  • There are many Intel JCC Erratum options but few are ever customized by uses. The very few users just specify -mbranches-within-32B-boundaries
  • address sanitizer has a lot of internal options customization instrumentation. We would probably not be comfortable exposing many of them.

@kovdan01 kovdan01 force-pushed the pauth-signed-got-clang-driver branch from aeedd6b to 1ca6cf8 Compare August 6, 2024 17:03
@kovdan01
Copy link
Contributor Author

Given the complexity of the feature and lack of upstream runtime linker (rtld) support, it might be wise to delay exposing it through driver options until it's more mature. What do you think?

@MaskRay I suppose that if exposing this to driver options is considered undesirable at the moment, we can just add cc1 option. A cc1 option is actually needed to construct pauth-enabled environments - currently, it is done by adding a predefined set of -fptrauth-* flags, see handlePAuthABI function.

If we only add cc1 flag and postpone adding driver flag, would it be OK?

@kovdan01
Copy link
Contributor Author

@MaskRay Would be glad to see your answer on the question above:

If we only add cc1 flag and postpone adding driver flag, would it be OK?

@MaskRay
Copy link
Member

MaskRay commented Nov 11, 2024

Sorry, I made a mistake by approving #85235, which added a lot of driver options. It's not clear who are the initial ELF ptrauth users, but I am not sure with a very small user base, there are a lot of demands to customize the protection in such a fine-grained manner.

Using cc1 options looks fine.

@kovdan01
Copy link
Contributor Author

Using cc1 options looks fine.

Thanks!

Sorry, I made a mistake by approving #85235, which added a lot of driver options. It's not clear who are the initial ELF ptrauth users, but I am not sure with a very small user base, there are a lot of demands to customize the protection in such a fine-grained manner.

I personally am OK with deleting those driver flags and only leaving cc1 flags - I'll prepare a corresponding PR for that. Also tagging @ahmedbougacha

@kovdan01 kovdan01 changed the title [PAC][clang][Driver] Add signed GOT flag [PAC][clang] Add signed GOT cc1 flag Nov 13, 2024
@kovdan01 kovdan01 force-pushed the pauth-signed-got-clang-driver branch 2 times, most recently from a97866b to 3a5ae01 Compare November 15, 2024 07:48
@kovdan01
Copy link
Contributor Author

Rebased on top of current main with fixing conflicts.
@MaskRay Would be glad if you give your feedback on this so the PR could be finally merged if no issues are left.

Add `-fptrauth-elf-got` clang cc1 flag and set `ptrauth_elf_got` preprocessor
feature and `PointerAuthELFGOT` LangOption correspondingly. No additional
checks like ensuring OS binary format is ELF are performed: it should be done
on clang driver level when a pauth-enabled environment implying signed GOT
enabled is requested.

If the cc1 flag is passed, "ptrauth-elf-got" IR module flag is set.
@kovdan01 kovdan01 force-pushed the pauth-signed-got-clang-driver branch from 3a5ae01 to fd3919e Compare November 18, 2024 16:56
@kovdan01 kovdan01 merged commit 3b162f7 into llvm:main Nov 19, 2024
8 checks passed
swatheesh-mcw pushed a commit to swatheesh-mcw/llvm-project that referenced this pull request Nov 20, 2024
Add `-fptrauth-elf-got` clang cc1 flag and set `ptrauth_elf_got`
preprocessor feature and `PointerAuthELFGOT` LangOption correspondingly.
No additional checks like ensuring OS binary format is ELF are
performed: it should be done on clang driver level when a pauth-enabled
environment implying signed GOT enabled is requested.

If the cc1 flag is passed, "ptrauth-elf-got" IR module flag is set.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend:AArch64 clang:codegen clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category llvm:binary-utilities
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

6 participants