€•’yŒsphinx.addnodes”Œdocument”“”)”}”(Œ rawsource”Œ”Œchildren”]”(Œ translations”Œ LanguagesNode”“”)”}”(hhh]”(hŒ pending_xref”“”)”}”(hhh]”Œdocutils.nodes”ŒText”“”ŒChinese (Simplified)”…””}”Œparent”hsbaŒ attributes”}”(Œids”]”Œclasses”]”Œnames”]”Œdupnames”]”Œbackrefs”]”Œ refdomain”Œstd”Œreftype”Œdoc”Œ reftarget”Œ&/translations/zh_CN/arch/riscv/zicfilp”Œmodname”NŒ classname”NŒ refexplicit”ˆuŒtagname”hhh ubh)”}”(hhh]”hŒChinese (Traditional)”…””}”hh2sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ&/translations/zh_TW/arch/riscv/zicfilp”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒItalian”…””}”hhFsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ&/translations/it_IT/arch/riscv/zicfilp”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒJapanese”…””}”hhZsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ&/translations/ja_JP/arch/riscv/zicfilp”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒKorean”…””}”hhnsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ&/translations/ko_KR/arch/riscv/zicfilp”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒPortuguese (Brazilian)”…””}”hh‚sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ&/translations/pt_BR/arch/riscv/zicfilp”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒSpanish”…””}”hh–sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ&/translations/sp_SP/arch/riscv/zicfilp”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubeh}”(h]”h ]”h"]”h$]”h&]”Œcurrent_language”ŒEnglish”uh1h hhŒ _document”hŒsource”NŒline”NubhŒcomment”“”)”}”(hŒ SPDX-License-Identifier: GPL-2.0”h]”hŒ SPDX-License-Identifier: GPL-2.0”…””}”hh·sbah}”(h]”h ]”h"]”h$]”h&]”Œ xml:space”Œpreserve”uh1hµhhh²hh³Œ@/var/lib/git/docbuild/linux/Documentation/arch/riscv/zicfilp.rst”h´KubhŒsection”“”)”}”(hhh]”(hŒtitle”“”)”}”(hŒ3Tracking indirect control transfers on RISC-V Linux”h]”hŒ3Tracking indirect control transfers on RISC-V Linux”…””}”(hhÏh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhhÊh²hh³hÇh´KubhŒ paragraph”“”)”}”(hŒ•This document briefly describes the interface provided to userspace by Linux to enable indirect branch tracking for user mode applications on RISC-V.”h]”hŒ•This document briefly describes the interface provided to userspace by Linux to enable indirect branch tracking for user mode applications on RISC-V.”…””}”(hhßh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K hhÊh²hubhÉ)”}”(hhh]”(hÎ)”}”(hŒ1. Feature Overview”h]”hŒ1. Feature Overview”…””}”(hhðh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhhíh²hh³hÇh´KubhÞ)”}”(hŒ•Memory corruption issues usually result in crashes. However, in the hands of a creative adversary, these can result in a variety of security issues.”h]”hŒ•Memory corruption issues usually result in crashes. However, in the hands of a creative adversary, these can result in a variety of security issues.”…””}”(hhþh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Khhíh²hubhÞ)”}”(hXSome of those security issues can be code re-use attacks, where an adversary can use corrupt function pointers, chaining them together to perform jump oriented programming (JOP) or call oriented programming (COP) and thus compromise control flow integrity (CFI) of the program.”h]”hXSome of those security issues can be code re-use attacks, where an adversary can use corrupt function pointers, chaining them together to perform jump oriented programming (JOP) or call oriented programming (COP) and thus compromise control flow integrity (CFI) of the program.”…””}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Khhíh²hubhÞ)”}”(hŒøFunction pointers live in read-write memory and thus are susceptible to corruption. This can allow an adversary to control the program counter (PC) value. On RISC-V, the zicfilp extension enforces a restriction on such indirect control transfers:”h]”hŒøFunction pointers live in read-write memory and thus are susceptible to corruption. This can allow an adversary to control the program counter (PC) value. On RISC-V, the zicfilp extension enforces a restriction on such indirect control transfers:”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Khhíh²hubhŒ bullet_list”“”)”}”(hhh]”hŒ list_item”“”)”}”(hXOIndirect control transfers must land on a landing pad instruction ``lpad``. There are two exceptions to this rule: - rs1 = x1 or rs1 = x5, i.e. a return from a function and returns are protected using shadow stack (see zicfiss.rst) - rs1 = x7. On RISC-V, the compiler usually does the following to reach a function which is beyond the offset of possible J-type instruction:: auipc x7, jalr (x7) This form of indirect control transfer is immutable and doesn't rely on memory. Thus rs1=x7 is exempted from tracking and these are considered software guarded jumps. ”h]”(hÞ)”}”(hŒrIndirect control transfers must land on a landing pad instruction ``lpad``. There are two exceptions to this rule:”h]”(hŒBIndirect control transfers must land on a landing pad instruction ”…””}”(hj3h²hh³Nh´NubhŒliteral”“”)”}”(hŒ``lpad``”h]”hŒlpad”…””}”(hj=h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j;hj3ubhŒ(. There are two exceptions to this rule:”…””}”(hj3h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Khj/ubj))”}”(hhh]”(j.)”}”(hŒsrs1 = x1 or rs1 = x5, i.e. a return from a function and returns are protected using shadow stack (see zicfiss.rst) ”h]”hÞ)”}”(hŒrrs1 = x1 or rs1 = x5, i.e. a return from a function and returns are protected using shadow stack (see zicfiss.rst)”h]”hŒrrs1 = x1 or rs1 = x5, i.e. a return from a function and returns are protected using shadow stack (see zicfiss.rst)”…””}”(hj\h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K!hjXubah}”(h]”h ]”h"]”h$]”h&]”uh1j-hjUubj.)”}”(hXUrs1 = x7. On RISC-V, the compiler usually does the following to reach a function which is beyond the offset of possible J-type instruction:: auipc x7, jalr (x7) This form of indirect control transfer is immutable and doesn't rely on memory. Thus rs1=x7 is exempted from tracking and these are considered software guarded jumps. ”h]”(hÞ)”}”(hŒŒrs1 = x7. On RISC-V, the compiler usually does the following to reach a function which is beyond the offset of possible J-type instruction::”h]”hŒ‹rs1 = x7. On RISC-V, the compiler usually does the following to reach a function which is beyond the offset of possible J-type instruction:”…””}”(hjth²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K$hjpubhŒ literal_block”“”)”}”(hŒauipc x7, jalr (x7)”h]”hŒauipc x7, jalr (x7)”…””}”hj„sbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1j‚h³hÇh´K'hjpubhÞ)”}”(hŒ§This form of indirect control transfer is immutable and doesn't rely on memory. Thus rs1=x7 is exempted from tracking and these are considered software guarded jumps.”h]”hŒ©This form of indirect control transfer is immutable and doesn’t rely on memory. Thus rs1=x7 is exempted from tracking and these are considered software guarded jumps.”…””}”(hj’h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K*hjpubeh}”(h]”h ]”h"]”h$]”h&]”uh1j-hjUubeh}”(h]”h ]”h"]”h$]”h&]”Œbullet”Œ-”uh1j(h³hÇh´K!hj/ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j-hj*h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”j¬j­uh1j(h³hÇh´Khhíh²hubhÞ)”}”(hX®The ``lpad`` instruction is a pseudo-op of ``auipc rd, `` with ``rd=x0``. This is a HINT op. The ``lpad`` instruction must be aligned on a 4 byte boundary. It compares the 20 bit immediate with x7. If ``imm_20bit`` == 0, the CPU doesn't perform any comparison with ``x7``. If ``imm_20bit`` != 0, then ``imm_20bit`` must match ``x7`` else CPU will raise ``software check exception`` (``cause=18``) with ``*tval = 2``.”h]”(hŒThe ”…””}”(hjºh²hh³Nh´Nubj<)”}”(hŒ``lpad``”h]”hŒlpad”…””}”(hjÂh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j;hjºubhŒ instruction is a pseudo-op of ”…””}”(hjºh²hh³Nh´Nubj<)”}”(hŒ``auipc rd, ``”h]”hŒauipc rd, ”…””}”(hjÔh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j;hjºubhŒ with ”…””}”(hjºh²hh³Nh´Nubj<)”}”(hŒ ``rd=x0``”h]”hŒrd=x0”…””}”(hjæh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j;hjºubhŒ. This is a HINT op. The ”…””}”(hjºh²hh³Nh´Nubj<)”}”(hŒ``lpad``”h]”hŒlpad”…””}”(hjøh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j;hjºubhŒa instruction must be aligned on a 4 byte boundary. It compares the 20 bit immediate with x7. If ”…””}”(hjºh²hh³Nh´Nubj<)”}”(hŒ ``imm_20bit``”h]”hŒ imm_20bit”…””}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j;hjºubhŒ5 == 0, the CPU doesn’t perform any comparison with ”…””}”(hjºh²hh³Nh´Nubj<)”}”(hŒ``x7``”h]”hŒx7”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j;hjºubhŒ. If ”…””}”(hjºh²hh³Nh´Nubj<)”}”(hŒ ``imm_20bit``”h]”hŒ imm_20bit”…””}”(hj.h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j;hjºubhŒ != 0, then ”…””}”(hjºh²hh³Nh´Nubj<)”}”(hŒ ``imm_20bit``”h]”hŒ imm_20bit”…””}”(hj@h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j;hjºubhŒ must match ”…””}”(hjºh²hh³Nh´Nubj<)”}”(hŒ``x7``”h]”hŒx7”…””}”(hjRh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j;hjºubhŒ else CPU will raise ”…””}”(hjºh²hh³Nh´Nubj<)”}”(hŒ``software check exception``”h]”hŒsoftware check exception”…””}”(hjdh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j;hjºubhŒ (”…””}”(hjºh²hh³Nh´Nubj<)”}”(hŒ ``cause=18``”h]”hŒcause=18”…””}”(hjvh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j;hjºubhŒ) with ”…””}”(hjºh²hh³Nh´Nubj<)”}”(hŒ ``*tval = 2``”h]”hŒ *tval = 2”…””}”(hjˆh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j;hjºubhŒ.”…””}”(hjºh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K.hhíh²hubhÞ)”}”(hX&The compiler can generate a hash over function signatures and set them up (truncated to 20 bits) in x7 at callsites. Function prologues can have ``lpad`` instructions encoded with the same function hash. This further reduces the number of valid program counter addresses a call site can reach.”h]”(hŒ’The compiler can generate a hash over function signatures and set them up (truncated to 20 bits) in x7 at callsites. Function prologues can have ”…””}”(hj h²hh³Nh´Nubj<)”}”(hŒ``lpad``”h]”hŒlpad”…””}”(hj¨h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j;hj ubhŒŒ instructions encoded with the same function hash. This further reduces the number of valid program counter addresses a call site can reach.”…””}”(hj h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K6hhíh²hubeh}”(h]”Œfeature-overview”ah ]”h"]”Œ1. feature overview”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´KubhÉ)”}”(hhh]”(hÎ)”}”(hŒ2. ELF and psABI”h]”hŒ2. ELF and psABI”…””}”(hjËh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhjÈh²hh³hÇh´K=ubhÞ)”}”(hŒ¤The toolchain sets up :c:macro:`GNU_PROPERTY_RISCV_FEATURE_1_FCFI` for property :c:macro:`GNU_PROPERTY_RISCV_FEATURE_1_AND` in the notes section of the object file.”h]”(hŒThe toolchain sets up ”…””}”(hjÙh²hh³Nh´Nubh)”}”(hŒ,:c:macro:`GNU_PROPERTY_RISCV_FEATURE_1_FCFI`”h]”j<)”}”(hjãh]”hŒ!GNU_PROPERTY_RISCV_FEATURE_1_FCFI”…””}”(hjåh²hh³Nh´Nubah}”(h]”h ]”(Œxref”Œc”Œc-macro”eh"]”h$]”h&]”uh1j;hjáubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”Œarch/riscv/zicfilp”Œ refdomain”jðŒreftype”Œmacro”Œ refexplicit”‰Œrefwarn”‰Œ reftarget”Œ!GNU_PROPERTY_RISCV_FEATURE_1_FCFI”uh1hh³hÇh´K?hjÙubhŒ for property ”…””}”(hjÙh²hh³Nh´Nubh)”}”(hŒ+:c:macro:`GNU_PROPERTY_RISCV_FEATURE_1_AND`”h]”j<)”}”(hj h]”hŒ GNU_PROPERTY_RISCV_FEATURE_1_AND”…””}”(hj h²hh³Nh´Nubah}”(h]”h ]”(jïjðŒc-macro”eh"]”h$]”h&]”uh1j;hjubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”jüŒ refdomain”jðŒreftype”Œmacro”Œ refexplicit”‰Œrefwarn”‰jŒ GNU_PROPERTY_RISCV_FEATURE_1_AND”uh1hh³hÇh´K?hjÙubhŒ) in the notes section of the object file.”…””}”(hjÙh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K?hjÈh²hubeh}”(h]”Œ elf-and-psabi”ah ]”h"]”Œ2. elf and psabi”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´K=ubhÉ)”}”(hhh]”(hÎ)”}”(hŒ3. Linux enabling”h]”hŒ3. Linux enabling”…””}”(hj<h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhj9h²hh³hÇh´KDubhÞ)”}”(hXUser space programs can have multiple shared objects loaded in their address spaces. It's a difficult task to make sure all the dependencies have been compiled with indirect branch support. Thus it's left to the dynamic loader to enable indirect branch tracking for the program.”h]”hXUser space programs can have multiple shared objects loaded in their address spaces. It’s a difficult task to make sure all the dependencies have been compiled with indirect branch support. Thus it’s left to the dynamic loader to enable indirect branch tracking for the program.”…””}”(hjJh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KFhj9h²hubeh}”(h]”Œlinux-enabling”ah ]”h"]”Œ3. linux enabling”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´KDubhÉ)”}”(hhh]”(hÎ)”}”(hŒ4. prctl() enabling”h]”hŒ4. prctl() enabling”…””}”(hjch²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhj`h²hh³hÇh´KMubhÞ)”}”(hX[Per-task indirect branch tracking state can be monitored and controlled via the :c:macro:`PR_GET_CFI` and :c:macro:`PR_SET_CFI` ``prctl()` arguments (respectively), by supplying :c:macro:`PR_CFI_BRANCH_LANDING_PADS` as the second argument. These are architecture-agnostic, and will return -EINVAL if the underlying functionality is not supported.”h]”(hŒPPer-task indirect branch tracking state can be monitored and controlled via the ”…””}”(hjqh²hh³Nh´Nubh)”}”(hŒ:c:macro:`PR_GET_CFI`”h]”j<)”}”(hj{h]”hŒ PR_GET_CFI”…””}”(hj}h²hh³Nh´Nubah}”(h]”h ]”(jïjðŒc-macro”eh"]”h$]”h&]”uh1j;hjyubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”jüŒ refdomain”jðŒreftype”Œmacro”Œ refexplicit”‰Œrefwarn”‰jŒ PR_GET_CFI”uh1hh³hÇh´KOhjqubhŒ and ”…””}”(hjqh²hh³Nh´Nubh)”}”(hŒ:c:macro:`PR_SET_CFI`”h]”j<)”}”(hjžh]”hŒ PR_SET_CFI”…””}”(hj h²hh³Nh´Nubah}”(h]”h ]”(jïjðŒc-macro”eh"]”h$]”h&]”uh1j;hjœubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”jüŒ refdomain”jðŒreftype”Œmacro”Œ refexplicit”‰Œrefwarn”‰jŒ PR_SET_CFI”uh1hh³hÇh´KOhjqubhŒ ”…””}”(hjqh²hh³Nh´NubhŒ problematic”“”)”}”(hŒ``”h]”hŒ``”…””}”(hjÁh²hh³Nh´Nubah}”(h]”Œid2”ah ]”h"]”h$]”h&]”Œrefid”Œid1”uh1j¿hjqubhŒ0prctl()` arguments (respectively), by supplying ”…””}”(hjqh²hh³Nh´Nubh)”}”(hŒ%:c:macro:`PR_CFI_BRANCH_LANDING_PADS`”h]”j<)”}”(hjØh]”hŒPR_CFI_BRANCH_LANDING_PADS”…””}”(hjÚh²hh³Nh´Nubah}”(h]”h ]”(jïjðŒc-macro”eh"]”h$]”h&]”uh1j;hjÖubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”jüŒ refdomain”jðŒreftype”Œmacro”Œ refexplicit”‰Œrefwarn”‰jŒPR_CFI_BRANCH_LANDING_PADS”uh1hh³hÇh´KOhjqubhŒ„ as the second argument. These are architecture-agnostic, and will return -EINVAL if the underlying functionality is not supported.”…””}”(hjqh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KOhj`h²hubj))”}”(hhh]”j.)”}”(hŒWprctl(:c:macro:`PR_SET_CFI`, :c:macro:`PR_CFI_BRANCH_LANDING_PADS`, unsigned long arg) ”h]”hÞ)”}”(hŒVprctl(:c:macro:`PR_SET_CFI`, :c:macro:`PR_CFI_BRANCH_LANDING_PADS`, unsigned long arg)”h]”(hŒprctl(”…””}”(hjh²hh³Nh´Nubh)”}”(hŒ:c:macro:`PR_SET_CFI`”h]”j<)”}”(hjh]”hŒ PR_SET_CFI”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”(jïjðŒc-macro”eh"]”h$]”h&]”uh1j;hjubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”jüŒ refdomain”jðŒreftype”Œmacro”Œ refexplicit”‰Œrefwarn”‰jŒ PR_SET_CFI”uh1hh³hÇh´KVhjubhŒ, ”…””}”(hjh²hh³Nh´Nubh)”}”(hŒ%:c:macro:`PR_CFI_BRANCH_LANDING_PADS`”h]”j<)”}”(hj3h]”hŒPR_CFI_BRANCH_LANDING_PADS”…””}”(hj5h²hh³Nh´Nubah}”(h]”h ]”(jïjðŒc-macro”eh"]”h$]”h&]”uh1j;hj1ubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”jüŒ refdomain”jðŒreftype”Œmacro”Œ refexplicit”‰Œrefwarn”‰jŒPR_CFI_BRANCH_LANDING_PADS”uh1hh³hÇh´KVhjubhŒ, unsigned long arg)”…””}”(hjh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KVhjubah}”(h]”h ]”h"]”h$]”h&]”uh1j-hjÿh²hh³hÇh´Nubah}”(h]”h ]”h"]”h$]”h&]”j¬Œ*”uh1j(h³hÇh´KVhj`h²hubhÞ)”}”(hŒarg is a bitmask.”h]”hŒarg is a bitmask.”…””}”(hjgh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KXhj`h²hubhÞ)”}”(hX(If :c:macro:`PR_CFI_ENABLE` is set in arg, and the CPU supports ``zicfilp``, then the kernel will enable indirect branch tracking for the task. The dynamic loader can issue this ``prctl()`` once it has determined that all the objects loaded in the address space support indirect branch tracking.”h]”(hŒIf ”…””}”(hjuh²hh³Nh´Nubh)”}”(hŒ:c:macro:`PR_CFI_ENABLE`”h]”j<)”}”(hjh]”hŒ PR_CFI_ENABLE”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”(jïjðŒc-macro”eh"]”h$]”h&]”uh1j;hj}ubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”jüŒ refdomain”jðŒreftype”Œmacro”Œ refexplicit”‰Œrefwarn”‰jŒ PR_CFI_ENABLE”uh1hh³hÇh´KZhjuubhŒ% is set in arg, and the CPU supports ”…””}”(hjuh²hh³Nh´Nubj<)”}”(hŒ ``zicfilp``”h]”hŒzicfilp”…””}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j;hjuubhŒh, then the kernel will enable indirect branch tracking for the task. The dynamic loader can issue this ”…””}”(hjuh²hh³Nh´Nubj<)”}”(hŒ ``prctl()``”h]”hŒprctl()”…””}”(hj²h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j;hjuubhŒj once it has determined that all the objects loaded in the address space support indirect branch tracking.”…””}”(hjuh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KZhj`h²hubhÞ)”}”(hXÌIndirect branch tracking state can also be locked once enabled. This prevents the task from subsequently disabling it. This is done by setting the bit :c:macro:`PR_CFI_LOCK` in arg. Either indirect branch tracking must already be enabled for the task, or the bit :c:macro:`PR_CFI_ENABLE` must also be set in arg. This is intended for environments that wish to run with a strict security posture that do not wish to load objects without ``zicfilp`` support.”h]”(hŒ™Indirect branch tracking state can also be locked once enabled. This prevents the task from subsequently disabling it. This is done by setting the bit ”…””}”(hjÊh²hh³Nh´Nubh)”}”(hŒ:c:macro:`PR_CFI_LOCK`”h]”j<)”}”(hjÔh]”hŒ PR_CFI_LOCK”…””}”(hjÖh²hh³Nh´Nubah}”(h]”h ]”(jïjðŒc-macro”eh"]”h$]”h&]”uh1j;hjÒubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”jüŒ refdomain”jðŒreftype”Œmacro”Œ refexplicit”‰Œrefwarn”‰jŒ PR_CFI_LOCK”uh1hh³hÇh´K`hjÊubhŒ[ in arg. Either indirect branch tracking must already be enabled for the task, or the bit ”…””}”(hjÊh²hh³Nh´Nubh)”}”(hŒ:c:macro:`PR_CFI_ENABLE`”h]”j<)”}”(hj÷h]”hŒ PR_CFI_ENABLE”…””}”(hjùh²hh³Nh´Nubah}”(h]”h ]”(jïjðŒc-macro”eh"]”h$]”h&]”uh1j;hjõubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”jüŒ refdomain”jðŒreftype”Œmacro”Œ refexplicit”‰Œrefwarn”‰jŒ PR_CFI_ENABLE”uh1hh³hÇh´K`hjÊubhŒ– must also be set in arg. This is intended for environments that wish to run with a strict security posture that do not wish to load objects without ”…””}”(hjÊh²hh³Nh´Nubj<)”}”(hŒ ``zicfilp``”h]”hŒzicfilp”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j;hjÊubhŒ support.”…””}”(hjÊh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K`hj`h²hubhÞ)”}”(hX‘Indirect branch tracking can also be disabled for the task, assuming that it has not previously been enabled and locked. If there is a ``dlopen()`` to an object which wasn't compiled with ``zicfilp``, the dynamic loader can issue this ``prctl()`` with arg set to :c:macro:`PR_CFI_DISABLE`. Disabling indirect branch tracking for the task is not possible if it has previously been enabled and locked.”h]”(hŒˆIndirect branch tracking can also be disabled for the task, assuming that it has not previously been enabled and locked. If there is a ”…””}”(hj0h²hh³Nh´Nubj<)”}”(hŒ ``dlopen()``”h]”hŒdlopen()”…””}”(hj8h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j;hj0ubhŒ+ to an object which wasn’t compiled with ”…””}”(hj0h²hh³Nh´Nubj<)”}”(hŒ ``zicfilp``”h]”hŒzicfilp”…””}”(hjJh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j;hj0ubhŒ$, the dynamic loader can issue this ”…””}”(hj0h²hh³Nh´Nubj<)”}”(hŒ ``prctl()``”h]”hŒprctl()”…””}”(hj\h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j;hj0ubhŒ with arg set to ”…””}”(hj0h²hh³Nh´Nubh)”}”(hŒ:c:macro:`PR_CFI_DISABLE`”h]”j<)”}”(hjph]”hŒPR_CFI_DISABLE”…””}”(hjrh²hh³Nh´Nubah}”(h]”h ]”(jïjðŒc-macro”eh"]”h$]”h&]”uh1j;hjnubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”jüŒ refdomain”jðŒreftype”Œmacro”Œ refexplicit”‰Œrefwarn”‰jŒPR_CFI_DISABLE”uh1hh³hÇh´Khhj0ubhŒp. Disabling indirect branch tracking for the task is not possible if it has previously been enabled and locked.”…””}”(hj0h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Khhj`h²hubj))”}”(hhh]”j.)”}”(hŒYprctl(:c:macro:`PR_GET_CFI`, :c:macro:`PR_CFI_BRANCH_LANDING_PADS`, unsigned long * arg) ”h]”hÞ)”}”(hŒXprctl(:c:macro:`PR_GET_CFI`, :c:macro:`PR_CFI_BRANCH_LANDING_PADS`, unsigned long * arg)”h]”(hŒprctl(”…””}”(hjžh²hh³Nh´Nubh)”}”(hŒ:c:macro:`PR_GET_CFI`”h]”j<)”}”(hj¨h]”hŒ PR_GET_CFI”…””}”(hjªh²hh³Nh´Nubah}”(h]”h ]”(jïjðŒc-macro”eh"]”h$]”h&]”uh1j;hj¦ubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”jüŒ refdomain”jðŒreftype”Œmacro”Œ refexplicit”‰Œrefwarn”‰jŒ PR_GET_CFI”uh1hh³hÇh´KphjžubhŒ, ”…””}”(hjžh²hh³Nh´Nubh)”}”(hŒ%:c:macro:`PR_CFI_BRANCH_LANDING_PADS`”h]”j<)”}”(hjËh]”hŒPR_CFI_BRANCH_LANDING_PADS”…””}”(hjÍh²hh³Nh´Nubah}”(h]”h ]”(jïjðŒc-macro”eh"]”h$]”h&]”uh1j;hjÉubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”jüŒ refdomain”jðŒreftype”Œmacro”Œ refexplicit”‰Œrefwarn”‰jŒPR_CFI_BRANCH_LANDING_PADS”uh1hh³hÇh´KphjžubhŒ, unsigned long * arg)”…””}”(hjžh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Kphjšubah}”(h]”h ]”h"]”h$]”h&]”uh1j-hj—h²hh³hÇh´Nubah}”(h]”h ]”h"]”h$]”h&]”j¬jfuh1j(h³hÇh´Kphj`h²hubhÞ)”}”(hX³Returns the current status of indirect branch tracking into a bitmask stored into the memory location pointed to by arg. The bitmask will have the :c:macro:`PR_CFI_ENABLE` bit set if indirect branch tracking is currently enabled for the task, and if it is locked, will additionally have the :c:macro:`PR_CFI_LOCK` bit set. If indirect branch tracking is currently disabled for the task, the :c:macro:`PR_CFI_DISABLE` bit will be set.”h]”(hŒ”Returns the current status of indirect branch tracking into a bitmask stored into the memory location pointed to by arg. The bitmask will have the ”…””}”(hjþh²hh³Nh´Nubh)”}”(hŒ:c:macro:`PR_CFI_ENABLE`”h]”j<)”}”(hjh]”hŒ PR_CFI_ENABLE”…””}”(hj h²hh³Nh´Nubah}”(h]”h ]”(jïjðŒc-macro”eh"]”h$]”h&]”uh1j;hjubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”jüŒ refdomain”jðŒreftype”Œmacro”Œ refexplicit”‰Œrefwarn”‰jŒ PR_CFI_ENABLE”uh1hh³hÇh´KrhjþubhŒx bit set if indirect branch tracking is currently enabled for the task, and if it is locked, will additionally have the ”…””}”(hjþh²hh³Nh´Nubh)”}”(hŒ:c:macro:`PR_CFI_LOCK`”h]”j<)”}”(hj+h]”hŒ PR_CFI_LOCK”…””}”(hj-h²hh³Nh´Nubah}”(h]”h ]”(jïjðŒc-macro”eh"]”h$]”h&]”uh1j;hj)ubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”jüŒ refdomain”jðŒreftype”Œmacro”Œ refexplicit”‰Œrefwarn”‰jŒ PR_CFI_LOCK”uh1hh³hÇh´KrhjþubhŒO bit set. If indirect branch tracking is currently disabled for the task, the ”…””}”(hjþh²hh³Nh´Nubh)”}”(hŒ:c:macro:`PR_CFI_DISABLE`”h]”j<)”}”(hjNh]”hŒPR_CFI_DISABLE”…””}”(hjPh²hh³Nh´Nubah}”(h]”h ]”(jïjðŒc-macro”eh"]”h$]”h&]”uh1j;hjLubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”jüŒ refdomain”jðŒreftype”Œmacro”Œ refexplicit”‰Œrefwarn”‰jŒPR_CFI_DISABLE”uh1hh³hÇh´KrhjþubhŒ bit will be set.”…””}”(hjþh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Krhj`h²hubeh}”(h]”Œprctl-enabling”ah ]”h"]”Œ4. prctl() enabling”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´KMubhÉ)”}”(hhh]”(hÎ)”}”(hŒ15. violations related to indirect branch tracking”h]”hŒ15. violations related to indirect branch tracking”…””}”(hj€h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhj}h²hh³hÇh´K|ubhÞ)”}”(hŒnPertaining to indirect branch tracking, the CPU raises a software check exception in the following conditions:”h]”hŒnPertaining to indirect branch tracking, the CPU raises a software check exception in the following conditions:”…””}”(hjŽh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K~hj}h²hubj))”}”(hhh]”(j.)”}”(hŒ*missing ``lpad`` after indirect call / jmp”h]”hÞ)”}”(hj¡h]”(hŒmissing ”…””}”(hj£h²hh³Nh´Nubj<)”}”(hŒ``lpad``”h]”hŒlpad”…””}”(hjªh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j;hj£ubhŒ after indirect call / jmp”…””}”(hj£h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KhjŸubah}”(h]”h ]”h"]”h$]”h&]”uh1j-hjœh²hh³hÇh´Nubj.)”}”(hŒ``lpad`` not on 4 byte boundary”h]”hÞ)”}”(hjÊh]”(j<)”}”(hŒ``lpad``”h]”hŒlpad”…””}”(hjÏh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j;hjÌubhŒ not on 4 byte boundary”…””}”(hjÌh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K‚hjÈubah}”(h]”h ]”h"]”h$]”h&]”uh1j-hjœh²hh³hÇh´Nubj.)”}”(hŒI``imm_20bit`` embedded in ``lpad`` instruction doesn't match with ``x7`` ”h]”hÞ)”}”(hŒH``imm_20bit`` embedded in ``lpad`` instruction doesn't match with ``x7``”h]”(j<)”}”(hŒ ``imm_20bit``”h]”hŒ imm_20bit”…””}”(hjõh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j;hjñubhŒ embedded in ”…””}”(hjñh²hh³Nh´Nubj<)”}”(hŒ``lpad``”h]”hŒlpad”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j;hjñubhŒ" instruction doesn’t match with ”…””}”(hjñh²hh³Nh´Nubj<)”}”(hŒ``x7``”h]”hŒx7”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j;hjñubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Kƒhjíubah}”(h]”h ]”h"]”h$]”h&]”uh1j-hjœh²hh³hÇh´Nubeh}”(h]”h ]”h"]”h$]”h&]”j¬j­uh1j(h³hÇh´Khj}h²hubhÞ)”}”(hŒ`In all 3 cases, ``*tval = 2`` is captured and software check exception is raised (``cause=18``).”h]”(hŒIn all 3 cases, ”…””}”(hj9h²hh³Nh´Nubj<)”}”(hŒ ``*tval = 2``”h]”hŒ *tval = 2”…””}”(hjAh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j;hj9ubhŒ5 is captured and software check exception is raised (”…””}”(hj9h²hh³Nh´Nubj<)”}”(hŒ ``cause=18``”h]”hŒcause=18”…””}”(hjSh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j;hj9ubhŒ).”…””}”(hj9h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K…hj}h²hubhÞ)”}”(hŒƒThe kernel will treat this as :c:macro:`SIGSEGV` with code = :c:macro:`SEGV_CPERR` and follow the normal course of signal delivery.”h]”(hŒThe kernel will treat this as ”…””}”(hjkh²hh³Nh´Nubh)”}”(hŒ:c:macro:`SIGSEGV`”h]”j<)”}”(hjuh]”hŒSIGSEGV”…””}”(hjwh²hh³Nh´Nubah}”(h]”h ]”(jïjðŒc-macro”eh"]”h$]”h&]”uh1j;hjsubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”jüŒ refdomain”jðŒreftype”Œmacro”Œ refexplicit”‰Œrefwarn”‰jŒSIGSEGV”uh1hh³hÇh´KˆhjkubhŒ with code = ”…””}”(hjkh²hh³Nh´Nubh)”}”(hŒ:c:macro:`SEGV_CPERR`”h]”j<)”}”(hj˜h]”hŒ SEGV_CPERR”…””}”(hjšh²hh³Nh´Nubah}”(h]”h ]”(jïjðŒc-macro”eh"]”h$]”h&]”uh1j;hj–ubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”jüŒ refdomain”jðŒreftype”Œmacro”Œ refexplicit”‰Œrefwarn”‰jŒ SEGV_CPERR”uh1hh³hÇh´KˆhjkubhŒ1 and follow the normal course of signal delivery.”…””}”(hjkh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Kˆhj}h²hubeh}”(h]”Œ.violations-related-to-indirect-branch-tracking”ah ]”h"]”Œ15. violations related to indirect branch tracking”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´K|ubeh}”(h]”Œ3tracking-indirect-control-transfers-on-risc-v-linux”ah ]”h"]”Œ3tracking indirect control transfers on risc-v linux”ah$]”h&]”uh1hÈhhh²hh³hÇh´Kubeh}”(h]”h ]”h"]”h$]”h&]”Œsource”hÇuh1hŒcurrent_source”NŒ current_line”NŒsettings”Œdocutils.frontend”ŒValues”“”)”}”(hÍNŒ generator”NŒ datestamp”NŒ source_link”NŒ source_url”NŒ toc_backlinks”Œentry”Œfootnote_backlinks”KŒ sectnum_xform”KŒstrip_comments”NŒstrip_elements_with_classes”NŒ strip_classes”NŒ report_level”KŒ halt_level”KŒexit_status_level”KŒdebug”NŒwarning_stream”NŒ traceback”ˆŒinput_encoding”Œ utf-8-sig”Œinput_encoding_error_handler”Œstrict”Œoutput_encoding”Œutf-8”Œoutput_encoding_error_handler”jòŒerror_encoding”Œutf-8”Œerror_encoding_error_handler”Œbackslashreplace”Œ language_code”Œen”Œrecord_dependencies”NŒconfig”NŒ id_prefix”hŒauto_id_prefix”Œid”Œ dump_settings”NŒdump_internals”NŒdump_transforms”NŒdump_pseudo_xml”NŒexpose_internals”NŒstrict_visitor”NŒ_disable_config”NŒ_source”hÇŒ _destination”NŒ _config_files”]”Œ7/var/lib/git/docbuild/linux/Documentation/docutils.conf”aŒfile_insertion_enabled”ˆŒ raw_enabled”KŒline_length_limit”M'Œpep_references”NŒ pep_base_url”Œhttps://peps.python.org/”Œpep_file_url_template”Œpep-%04d”Œrfc_references”NŒ rfc_base_url”Œ&https://datatracker.ietf.org/doc/html/”Œ tab_width”KŒtrim_footnote_reference_space”‰Œsyntax_highlight”Œlong”Œ smart_quotes”ˆŒsmartquotes_locales”]”Œcharacter_level_inline_markup”‰Œdoctitle_xform”‰Œ docinfo_xform”KŒsectsubtitle_xform”‰Œ image_loading”Œlink”Œembed_stylesheet”‰Œcloak_email_addresses”ˆŒsection_self_link”‰Œenv”NubŒreporter”NŒindirect_targets”]”Œsubstitution_defs”}”Œsubstitution_names”}”Œrefnames”}”Œrefids”}”Œnameids”}”(jÌjÉjÅjÂj6j3j]jZjzjwjÄjÁuŒ nametypes”}”(j̉jʼnj6‰j]‰jz‰jĉuh}”(jÉhÊjÂhíj3jÈjZj9jwj`jÑhŒsystem_message”“”)”}”(hhh]”hÞ)”}”(hŒ/Inline literal start-string without end-string.”h]”hŒ/Inline literal start-string without end-string.”…””}”(hj>h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝhj;ubah}”(h]”jÑah ]”h"]”h$]”h&]”jËaŒlevel”KŒtype”ŒWARNING”Œline”KOŒsource”hÇuh1j9hj`h²hh³hÇh´KTubjËjÁjÁj}uŒ footnote_refs”}”Œ citation_refs”}”Œ autofootnotes”]”Œautofootnote_refs”]”Œsymbol_footnotes”]”Œsymbol_footnote_refs”]”Œ footnotes”]”Œ citations”]”Œautofootnote_start”KŒsymbol_footnote_start”KŒ id_counter”Œ collections”ŒCounter”“”}”jKs…”R”Œparse_messages”]”j;aŒtransform_messages”]”Œ transformer”NŒ include_log”]”Œ decoration”Nh²hub.