diff --git a/content/learning-paths/servers-and-cloud-computing/openjdk-pacbti-azure/_index.md b/content/learning-paths/servers-and-cloud-computing/openjdk-pacbti-azure/_index.md new file mode 100644 index 0000000000..9a441b2e5f --- /dev/null +++ b/content/learning-paths/servers-and-cloud-computing/openjdk-pacbti-azure/_index.md @@ -0,0 +1,66 @@ +--- +title: Build an OpenJDK JVM with PAC/BTI on Azure Cobalt 100 + +description: Learn how to compile OpenJDK with branch protection on an Azure Cobalt 100 Arm VM and verify PAC/BTI support in the resulting JVM. + +draft: true +cascade: + draft: true + +minutes_to_complete: 30 + +who_is_this_for: This Learning Path is for developers who want to build and validate an OpenJDK JVM with PAC/BTI support on Azure Cobalt 100 Arm-based virtual machines. + +learning_objectives: + - Provision an Azure Cobalt 100 Arm-based virtual machine with Ubuntu Pro 24.04 LTS. + - Build OpenJDK on Arm64 with branch protection support enabled. + - Verify PAC/BTI readiness in the installed JVM runtime. + +prerequisites: + - A [Microsoft Azure](https://azure.microsoft.com/) account with access to Cobalt 100 based instances (Dpsv6) + + +author: Doug Anson + +### Tags +skilllevels: Introductory +subjects: Performance and Architecture +cloud_service_providers: + - Microsoft Azure + +armips: + - Neoverse + +tools_software_languages: + - Java + - OpenJDK + - Bash + +operatingsystems: + - Linux + +further_reading: + - resource: + title: Azure Virtual Machines documentation + link: https://learn.microsoft.com/en-us/azure/virtual-machines/ + type: documentation + - resource: + title: OpenJDK build documentation + link: https://openjdk.org/groups/build/doc/building.html + type: documentation + - resource: + title: OpenJDK source repository + link: https://github.com/openjdk/jdk + type: documentation + - resource: + title: Arm A64 instruction reference + link: https://developer.arm.com/documentation/100076/latest/ + type: documentation + + +### FIXED, DO NOT MODIFY +# ================================================================================ +weight: 1 # _index.md always has weight of 1 to order correctly +layout: "learningpathall" # All files under learning paths have this same wrapper +learning_path_main_page: "yes" # This should be surfaced when looking for related content. Only set for _index.md of learning path content. +--- diff --git a/content/learning-paths/servers-and-cloud-computing/openjdk-pacbti-azure/_next-steps.md b/content/learning-paths/servers-and-cloud-computing/openjdk-pacbti-azure/_next-steps.md new file mode 100644 index 0000000000..c3db0de5a2 --- /dev/null +++ b/content/learning-paths/servers-and-cloud-computing/openjdk-pacbti-azure/_next-steps.md @@ -0,0 +1,8 @@ +--- +# ================================================================================ +# FIXED, DO NOT MODIFY THIS FILE +# ================================================================================ +weight: 21 # Set to always be larger than the content in this path to be at the end of the navigation. +title: "Next Steps" # Always the same, html page title. +layout: "learningpathall" # All files under learning paths have this same wrapper for Hugo processing. +--- diff --git a/content/learning-paths/servers-and-cloud-computing/openjdk-pacbti-azure/background.md b/content/learning-paths/servers-and-cloud-computing/openjdk-pacbti-azure/background.md new file mode 100644 index 0000000000..eaa73c2f4f --- /dev/null +++ b/content/learning-paths/servers-and-cloud-computing/openjdk-pacbti-azure/background.md @@ -0,0 +1,25 @@ +--- +title: Understand Azure Cobalt 100, OpenJDK, and Armv9 PAC/BTI + +weight: 2 + +layout: "learningpathall" +--- + +## Azure Cobalt 100 Arm-based processor + +Azure’s Cobalt 100 is Microsoft’s first-generation, in-house Arm-based processor. Built on Arm Neoverse N2, Cobalt 100 is a 64-bit CPU that delivers strong performance and energy efficiency for cloud-native, scale-out Linux workloads such as web and application servers, data analytics, open-source databases, and caching systems. Running at 3.4 GHz, Cobalt 100 allocates a dedicated physical core for each vCPU, which helps ensure consistent and predictable performance. + +To learn more, see the Microsoft blog [Announcing the preview of new Azure VMs based on the Azure Cobalt 100 processor](https://techcommunity.microsoft.com/blog/azurecompute/announcing-the-preview-of-new-azure-vms-based-on-the-azure-cobalt-100-processor/4146353). + +## OpenJDK and the PAC/BTI Arm v9 instructions + +OpenJDK is the open-source reference implementation of Java Platform, Standard Edition (Java SE). It provides the core compiler, runtime, and class libraries you use to build and run Java applications across operating systems and hardware platforms. OpenJDK forms the basis for most modern Java distributions, while different vendors package and support their own builds. + +Armv9 Pointer Authentication (PAC) and Branch Target Identification (BTI) are security features designed to make control-flow attacks harder. PAC helps protect return addresses and pointers by adding a cryptographic signature that is checked before the pointer is used, which can detect tampering such as return-oriented programming attempts. BTI complements this by restricting where indirect branches are allowed to land, helping prevent attackers from jumping into unintended instruction sequences. Together, PAC and BTI strengthen software defenses at the instruction-set level, especially for modern operating systems, hypervisors, and applications that need improved resistance to memory-corruption exploits. + +## What you've learned and what's next + +You now have the background on Azure Cobalt 100, OpenJDK, and Armv9 PAC/BTI features. + +Next, you'll create an Arm-based Azure VM, build OpenJDK with branch protection, and validate PAC/BTI readiness in the installed JVM. diff --git a/content/learning-paths/servers-and-cloud-computing/openjdk-pacbti-azure/images/final-vm.png b/content/learning-paths/servers-and-cloud-computing/openjdk-pacbti-azure/images/final-vm.png new file mode 100644 index 0000000000..5207abfb41 Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/openjdk-pacbti-azure/images/final-vm.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/openjdk-pacbti-azure/images/instance.png b/content/learning-paths/servers-and-cloud-computing/openjdk-pacbti-azure/images/instance.png new file mode 100644 index 0000000000..285cd764a5 Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/openjdk-pacbti-azure/images/instance.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/openjdk-pacbti-azure/images/instance1.png b/content/learning-paths/servers-and-cloud-computing/openjdk-pacbti-azure/images/instance1.png new file mode 100644 index 0000000000..b9d22c352d Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/openjdk-pacbti-azure/images/instance1.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/openjdk-pacbti-azure/images/instance4.png b/content/learning-paths/servers-and-cloud-computing/openjdk-pacbti-azure/images/instance4.png new file mode 100644 index 0000000000..2a0ff1e3b0 Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/openjdk-pacbti-azure/images/instance4.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/openjdk-pacbti-azure/images/ubuntu-pro.png b/content/learning-paths/servers-and-cloud-computing/openjdk-pacbti-azure/images/ubuntu-pro.png new file mode 100644 index 0000000000..d54bd75ca6 Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/openjdk-pacbti-azure/images/ubuntu-pro.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/openjdk-pacbti-azure/instance.md b/content/learning-paths/servers-and-cloud-computing/openjdk-pacbti-azure/instance.md new file mode 100644 index 0000000000..f1788a0b8c --- /dev/null +++ b/content/learning-paths/servers-and-cloud-computing/openjdk-pacbti-azure/instance.md @@ -0,0 +1,72 @@ +--- +title: Create an Azure Cobalt 100 Arm64 virtual machine +weight: 3 + +### FIXED, DO NOT MODIFY +layout: learningpathall +--- + +## Prerequisites and setup + +There are several common ways to create an Arm-based Cobalt 100 virtual machine, and you can choose the method that best fits your workflow or requirements: + +- The Azure Portal +- The Azure CLI +- An infrastructure as code (IaC) tool + +In this section, you'll launch the Azure Portal to create a virtual machine with the Arm-based Azure Cobalt 100 processor. + +This Learning Path focuses on general-purpose virtual machines in the Dpsv6 series. For more information, see the [Microsoft Azure guide for the Dpsv6 size series](https://learn.microsoft.com/en-us/azure/virtual-machines/sizes/general-purpose/dpsv6-series). + +While the steps to create this instance are included here for convenience, you can also refer to the [Deploy a Cobalt 100 virtual machine on Azure Learning Path](/learning-paths/servers-and-cloud-computing/cobalt/). + +## Create an Arm-based Azure virtual machine + +Creating a virtual machine based on Azure Cobalt 100 is no different from creating any other virtual machine in Azure. To create an Azure virtual machine: + +- Launch the Azure portal and navigate to **Virtual Machines**. +- Select **Create**, and select **Virtual Machine** from the drop-down list. +- Inside the **Basic** tab, fill in the instance details such as **Virtual machine name** and **Region**. +- Select the image for your virtual machine (for example, Ubuntu Pro 24.04 LTS) and select **Arm64** as the VM architecture. +- In the **Size** field, select **See all sizes** and select the D-Series v6 family of virtual machines. +- Select **D4ps_v6** from the list as shown in the diagram below: + +![Azure Portal showing D-Series v6 VM size selection with D4ps_v6 highlighted#center](images/instance.png "Select D4ps_v6 from the D-Series v6 family") + +- For **Authentication type**, select **SSH public key**. + +{{% notice Note %}} +Azure can generate an SSH key pair for you and lets you save it for future use. +{{% /notice %}} + +- Fill in the **Administrator username** for your VM. +- Select **Generate new key pair**, and select **RSA SSH Format** as the SSH Key Type. + +{{% notice Note %}} +RSA offers better security with keys longer than 3072 bits. +{{% /notice %}} + +- Give your SSH key a key pair name. +- In the **Inbound port rules**, select **HTTP (80)** and **SSH (22)** as the inbound ports, as shown below: + +![Azure Portal showing inbound port rules with HTTP (80) and SSH (22) selected#center](images/instance1.png "Configure inbound port rules for HTTP and SSH access") + +- Now select the **Review + Create** tab and review the configuration for your virtual machine. It should look like the following: + +![Azure Portal Review + Create tab showing VM configuration summary ready for deployment#center](images/ubuntu-pro.png "Review VM configuration before creation") + +- When you're happy with your selection, select the **Create** button and then **Download Private key and Create Resource** button. + +![Azure Portal showing Create button and SSH key download dialog#center](images/instance4.png "Download SSH key and create the virtual machine") + +Your virtual machine should be ready and running in a few minutes. You can SSH into the virtual machine using the private key, along with the public IP details. + +![Azure Portal showing successful VM deployment with confirmation details#center](images/final-vm.png "Successful VM deployment confirmation") + +{{% notice Note %}}To learn more about Arm-based virtual machines in Azure, see "Getting Started with Microsoft Azure" in [Get started with Arm-based cloud instances](/learning-paths/servers-and-cloud-computing/csp/azure/).{{% /notice %}} + +## What you've learned and what's next + +You've created an Azure Cobalt 100 Arm64 virtual machine running Ubuntu 24.04 LTS with SSH authentication configured. The virtual machine is now ready for compiling and installing OpenJDK with PAC/BTI support. + +Next, you'll download and compile OpenJDK on the VM, register the resulting JVM runtime, and run validation checks for PAC/BTI support. diff --git a/content/learning-paths/servers-and-cloud-computing/openjdk-pacbti-azure/jvm-compile.md b/content/learning-paths/servers-and-cloud-computing/openjdk-pacbti-azure/jvm-compile.md new file mode 100644 index 0000000000..42ff00e03a --- /dev/null +++ b/content/learning-paths/servers-and-cloud-computing/openjdk-pacbti-azure/jvm-compile.md @@ -0,0 +1,75 @@ +--- +title: Compile the OpenJDK JVM source +weight: 4 + +### FIXED, DO NOT MODIFY +layout: learningpathall +--- + +### Install build prerequisites + +Install these prerequisites in an SSH shell on your Cobalt 100 VM. Also install a bootstrap JVM to build the PAC/BTI-enabled JVM: + +```bash +sudo apt update +sudo apt install -y zip git build-essential wget curl autoconf +sudo apt install -y libcups2-dev libasound2-dev libfontconfig1-dev alsa-ucm-conf ubuntu-drivers-common +sudo apt install -y libx11-dev libxext-dev libxrender-dev libxrandr-dev libxtst-dev libxt-dev +sudo apt install -y openjdk-25-jdk +``` + +### Download the OpenJDK source + +Download OpenJDK. Since the bootstrap JVM is v25, build v26 with PAC/BTI support enabled: + +```bash +cd $HOME +git clone https://github.com/openjdk/jdk +cd jdk +git checkout jdk-26+35 +``` + +### Configure the OpenJDK source build + +Configure the OpenJDK source build and enable branch protection support: + +```bash +bash configure --enable-branch-protection +``` + +### Build the JVM + +Run the build to create the JVM. This process can take more than 30 minutes: + +```bash +make images +``` + +### Register the JVM with the system + +Run the following commands to register the newly created JDK/JVM with the system: + +```bash +cd $HOME/jdk +WD=$(pwd)/build/linux-aarch64-server-release +cd /usr/lib/jvm +sudo ln -s ${WD}/jdk ./java-26-openjdk-arm64 +sudo update-alternatives --install /usr/bin/java java /usr/lib/jvm/java-26-openjdk-arm64/bin/java 3000 +cd +``` + +Confirm the newly installed JVM: + +```bash +java --version +``` + +Output should be similar to: + +```output +openjdk 26-internal 2026-03-17 +OpenJDK Runtime Environment (build 26-internal-adhoc.ubuntu.jdk) +OpenJDK 64-Bit Server VM (build 26-internal-adhoc.ubuntu.jdk, mixed mode) +``` + +Next, run a script to confirm PAC/BTI readiness in the JVM you just built and installed. diff --git a/content/learning-paths/servers-and-cloud-computing/openjdk-pacbti-azure/jvm-testing.md b/content/learning-paths/servers-and-cloud-computing/openjdk-pacbti-azure/jvm-testing.md new file mode 100644 index 0000000000..10ad37b999 --- /dev/null +++ b/content/learning-paths/servers-and-cloud-computing/openjdk-pacbti-azure/jvm-testing.md @@ -0,0 +1,62 @@ +--- +title: Test the installed JVM for PAC/BTI enablement +weight: 5 + +### FIXED, DO NOT MODIFY +layout: learningpathall +--- + + +### Setup the test script + +Clone this repo and set execute permissions for the downloaded test script: + +```bash +git clone https://github.com/DougAnsonAustinTx/pac-bti-jdk-assets +cd pac-bti-jdk-assets +chmod 755 ./test-pacbti.sh +``` + +### Run the test script + +Run the test script to confirm PAC/BTI enablement: + +```bash +./test-pacbti.sh --java /usr/bin/java +``` + +Output should resemble: + +```output +== JVM PAC/BTI check == +java executable : /home/ubuntu/jdk/build/linux-aarch64-server-release/jdk/bin/java +libjvm : /home/ubuntu/jdk/build/linux-aarch64-server-release/jdk/lib/server/libjvm.so + +-- Host support (auxv/hwcaps) -- +PAC APIA/generic support : yes (PACA=yes PACG=yes) +BTI support : yes + +-- JVM support/config -- +UseBranchProtection flag : yes +JVM default flag value : {default} + +-- Binary instruction scan -- +java contains PAC instr : yes +java contains BTI instr : yes +libjvm contains PAC instr: no +libjvm contains BTI instr: no + +-- Verdict -- +PAC status : possible-but-not-proven +BTI status : yes + +Interpretation: + PAC-capable build detected, but no running JVM cmdline was checked. + BTI is likely enabled in the runtime binaries. +``` + +### What you've learned + +Some OpenJDK builds are not distributed with PAC/BTI enabled by default because they must remain compatible with older Arm platforms. When you need these protections, you can build and register your own JVM with branch protection support. + +When a PAC/BTI-enabled JVM runs on a platform that supports these features, Java workloads gain additional control-flow protection.