Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Aarch64/gcs #2725

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

Draft
svilenkov wants to merge 9 commits into checkpoint-restore:criu-dev
base: criu-dev
Choose a base branch
Loading
from svilenkov:aarch64/gcs
Draft

Conversation

@svilenkov
Copy link
Member

@svilenkov svilenkov commented Aug 31, 2025
edited
Loading

This PR adds initial support for the Arm64 Guarded Control Stack (GCS). This work is part of the Google Summer of Code 2025 projects.

Refactor user_fpregs_struct_t to wrap user_fpsimd_state in a
dedicated struct, preparing for future extending by just
adding new members
Signed-off-by: Igor Svilenkov Bozic <svilenkov@gmail.com>
Reviewed-by: Alexander Mikhalitsyn <aleksandr.mikhalitsyn@canonical.com>
Introduce ARM64 Guarded Control Stack (GCS) constants and macros
in a new uapi header for use in both CRIU and compel.
Includes:
 - NT_ARM_GCS type
 - prctl(2) constants for GCS enable/write/push modes
 - Capability token helpers (GCS_CAP, GCS_SIGNAL_CAP)
 - HWCAP_GCS definition
These are based on upstream Linux definitions
Signed-off-by: Igor Svilenkov Bozic <svilenkov@gmail.com>
Add basic prerequisites for Guarded Control Stack (GCS) state on AArch64.
This adds a gcs_context to the signal frame and extends user_fpregs_struct_t to
carry GCS metadata, preparing the groundwork for GCS in the parasite.
For now, the GCS fields are zeroed during compel_get_task_regs(), technically
ignoring GCS since it does not reach the control logic yet; that will be
introduced in the next commit.
The code path is gated and does not affect normal tests. Can be explicitly
enabled and tested via:
  make -C infect GCS_ENABLE=1 && make -C infect run
Signed-off-by: Igor Svilenkov Bozic <svilenkov@gmail.com>
When GCS is enabled, the kernel expects a capability token at GCSPR_EL0-8
and sa_restorer at GCSPR_EL0-16 on rt_sigreturn. The sigframe must be
consistent with the kernel’s expectations, with GCSPR_EL0 advanced by -8
having it point to the token on signal entry. On rt_sigreturn, the kernel
verifies the cap at GCSPR_EL0, invalidates it and increments GCSPR_EL0 by 8
at the end of gcs_restore_signal() .
Implement parasite_setup_gcs() to:
- read NT_ARM_GCS via
- write (via ptrace) the computed capability token and restorer address
- update GCSPR_EL0 to point to the token's location
Call parasite_setup_gcs() into parasite_start_daemon() so the sigreturn
frame satisfies kernel's expectation
Tests with GCS remain opt‐in:
	make -C compel/test/infect GCS_ENABLE=1 && make -C compel/test/infect run
Signed-off-by: Igor Svilenkov Bozic <svilenkov@gmail.com>
Introduce an opt-in mode for building and running compel tests
with Guarded Control Stack (GCS) enabled on AArch64.
Changes:
 - Extend compel/test/infect to support `GCS_ENABLE=1` builds,
 adding `-mbranch-protection=standard` and
 `-z experimental-gcs=check` to CFLAGS/LDFLAGS.
 - Export required GLIBC_TUNABLES at runtime via `TEST_ENV`.
Usage:
 make -C compel/test/infect GCS_ENABLE=1
 make -C compel/test/infect GCS_ENABLE=1 run
By default (`GCS_ENABLE` unset or 0), builds and runs are unchanged.
Signed-off-by: Igor Svilenkov Bozic <svilenkov@gmail.com>
 - Define user_aarch64_gcs_entry in core-aarch64.proto to store
 Guarded Control Stack state (gcspr_el0, features_enabled).
 - Extend thread_info_aarch64 with an optional gcs field
Also extend thread_info_aarch64 with an optional gcs field
Signed-off-by: Igor Svilenkov Bozic <svilenkov@gmail.com>
Add debug and info messages to log Guarded Control Stack state when
dumping AArch64 threads. This includes the following values:
 - gcspr_el0
 - features_enabled
Signed-off-by: Igor Svilenkov Bozic <svilenkov@gmail.com>
This commit finalizes AArch64 Guarded Control Stack (GCS)
support by wiring the full dump and restore flow.
The restore path adds the following steps:
 - Define shared AArch64 GCS types and constants in a dedicated header
 for both compel and CRIU inclusion
 - compel: add get/set NT_ARM_GCS via ptrace, enabling user-space
 GCS state save and restore.
 - During restore switch to the new GCS (via GCSSTR) to place capability
 token sa_restorer address
 - arch_shstk_trampoline() — We enable GCS in a trampoline that using
 prctl(PR_SET_SHADOW_STACK_STATUS, ...) via inline SVC. The trampoline
 ineeded because we can’t RET without a valid GCS.
 - restorer: map the recorded GCS VMA, populate contents top-down with
 GCSSTR, write the signal capability at GCSPR_EL0 and the valid token at
 GCSPR_EL0-8, then switch to the rebuilt GCS (GCSSS1)
 - Save and restore registers via ptrace
 - Extend restorer argument structures to carry GCS state
 into post-restore execution
Tested with:
 GCS_ENABLE=1 ./zdtm.py run -t zdtm/static/env00
Signed-off-by: Igor Svilenkov Bozic <svilenkov@gmail.com>
Introduce an opt-in mode for building and running ZDTM static tests
with Guarded Control Stack (GCS) enabled on AArch64.
Changes:
 - Support `GCS_ENABLE=1` builds, adding `-mbranch-protection=standard`
 and `-z experimental-gcs=check` to CFLAGS/LDFLAGS.
 - Export required GLIBC_TUNABLES at runtime via `TEST_ENV`.
 - %.pid rules to prefix test binaries with `$(TEST_ENV)`
 so the tunables are set when running tests.
 - Makefile rules for selectively enabling GCS in tests
Usage:
 # Build and run with GCS enabled
 make -C zdtm/static GCS_ENABLE=1 posix_timers
 GCS_ENABLE=1 ./zdtm.py run --keep-img=always \
 -t zdtm/static/posix_timers
By default (`GCS_ENABLE` unset or 0), test builds and runs are
unchanged.
NOTE: This assumes that the test victim was compiled also using
 GCS_ENABLE=1 so that the proper GCS AArch64 ELF headers are present
Signed-off-by: Igor Svilenkov Bozic <svilenkov@gmail.com>
Reviewed-by: Alexander Mikhalitsyn aleksandr.mikhalitsyn@canonical.com
#include "infect-priv.h"
#include "asm/breakpoints.h"
#include "asm/gcs-types.h
#include "asm/gcs-types.h"
Copy link
Member

@rst0git rst0git Sep 1, 2025
edited
Loading

Choose a reason for hiding this comment

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

Could you fix this in the previous patch that introduced this include line?

When dividing your change into a series of commits, take special care to ensure that CRIU builds and runs properly after each commit in the series. Developers using git bisect to track down a problem can end up splitting your patch series at any point; they will not thank you if you introduce bugs in the middle.

https://github.com/checkpoint-restore/criu/blob/criu-dev/CONTRIBUTING.md

svilenkov reacted with thumbs up emoji
Copy link
Member

@rppt rppt left a comment

Choose a reason for hiding this comment

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

Acked-by: Mike Rapoport rppt@kernel.org

@@ -0,0 +1,39 @@
#ifndef NT_ARM_GCS
Copy link
Member

Choose a reason for hiding this comment

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

Please add a global guard for the header

svilenkov reacted with thumbs up emoji
#include "infect.h"
#include "infect-priv.h"
#include "asm/breakpoints.h"
#include "asm/gcs-types.h
Copy link
Member

Choose a reason for hiding this comment

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

what @rst0git said :)

svilenkov reacted with thumbs up emoji
#endif

#ifndef compel_gcs_enabled
static inline bool compel_gcs_enabled(struct user_gcs *gcs)
Copy link
Member

Choose a reason for hiding this comment

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

It looks like we don't need neither compel_gcs_enabled() nor compel_shstk_enabled().
The both only appear in arch/ code and it seems better to just define no underscore version in compel/arch//src/lib/include/uapi/asm/infect-types.h and drop the global stubs.

goto err;
}

memset(&fpsimd->gcs, 0, sizeof(fpsimd->gcs));
Copy link
Member

Choose a reason for hiding this comment

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

we don't memset(0) other register structs, why there is a need to clear fpsimd->gcs?

Copy link
Member Author

@svilenkov svilenkov Sep 4, 2025

Choose a reason for hiding this comment

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

I've explicitly zeroed out to be sure GCS fields won't contain garbage values that would falsely indicate it's enabled

Copy link
Member

@rppt rppt left a comment
edited
Loading

Choose a reason for hiding this comment

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

Implement parasite_setup_gcs() to:

  • read NT_ARM_GCS via

ptrace I presume? ;)

.iov_base = &fpsimd->gcs,
.iov_len = sizeof(fpsimd->gcs),
};

Copy link
Member

Choose a reason for hiding this comment

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

why do we need a separate gcs_iov and cannot reuse iov as other PTRACE_GERREGSET calls?

pr_debug("sigframe gcspr=%llx features_enabled=%llx\n", fpregs->gcs.gcspr_el0 - 8, fpregs->gcs.features_enabled);
} else {
pr_debug("sigframe gcspr=[disabled]");
pr_debug("sigframe gcspr=[disabled]\n");
Copy link
Member

Choose a reason for hiding this comment

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

It'd be nice to fix this in the commit that introduce the pr_debug here :)

svilenkov reacted with thumbs up emoji
rppt

This comment was marked as off-topic.

Copy link
Member

rppt commented Sep 4, 2025

This PR adds initial support for the Arm64 Guarded Control Stack (GCS). This work is part of the Google Summer of Code 2025 projects.

Great work @svilenkov !

svilenkov reacted with hooray emoji

Copy link

github-actions bot commented Oct 5, 2025

A friendly reminder that this PR had no activity for 30 days.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@rst0git rst0git rst0git left review comments

@rppt rppt rppt left review comments

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

AltStyle によって変換されたページ (->オリジナル) /