Skip to content

Commit fd58225

Browse files
committed
Merge: x86/sgx: Update SGX code up thru v6.12-rc1
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-9/-/merge_requests/5422 ``` JIRA: https://issues.redhat.com/browse/RHEL-22826 JIRA: https://issues.redhat.com/browse/RHEL-63522 CVE: CVE-2024-49856 Upstream Status: 21 commits are merged into the linux.git Bring in the latest SGX code bugfixes and improvements. All the commits apply cleanly, no conflicts, no changes vs the upstream. Signed-off-by: Vladis Dronov <vdronov@redhat.com> ``` Approved-by: Steve Best <sbest@redhat.com> Approved-by: Vitaly Kuznetsov <vkuznets@redhat.com> Approved-by: CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> Merged-by: Rado Vrbovsky <rvrbovsk@redhat.com>
2 parents f2feeba + b49c65c commit fd58225

File tree

12 files changed

+103
-74
lines changed

12 files changed

+103
-74
lines changed

arch/x86/entry/vdso/vsgx.S

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
/* SPDX-License-Identifier: GPL-2.0 */
22

33
#include <linux/linkage.h>
4-
#include <asm/export.h>
54
#include <asm/errno.h>
65
#include <asm/enclu.h>
76

arch/x86/kernel/cpu/feat_ctl.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ void init_ia32_feat_ctl(struct cpuinfo_x86 *c)
188188
update_sgx:
189189
if (!(msr & FEAT_CTL_SGX_ENABLED)) {
190190
if (enable_sgx_kvm || enable_sgx_driver)
191-
pr_err_once("SGX disabled by BIOS.\n");
191+
pr_err_once("SGX disabled or unsupported by BIOS.\n");
192192
clear_cpu_cap(c, X86_FEATURE_SGX);
193193
return;
194194
}

arch/x86/kernel/cpu/sgx/main.c

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -474,24 +474,25 @@ struct sgx_epc_page *__sgx_alloc_epc_page(void)
474474
{
475475
struct sgx_epc_page *page;
476476
int nid_of_current = numa_node_id();
477-
int nid = nid_of_current;
477+
int nid_start, nid;
478478

479-
if (node_isset(nid_of_current, sgx_numa_mask)) {
480-
page = __sgx_alloc_epc_page_from_node(nid_of_current);
481-
if (page)
482-
return page;
483-
}
484-
485-
/* Fall back to the non-local NUMA nodes: */
486-
while (true) {
487-
nid = next_node_in(nid, sgx_numa_mask);
488-
if (nid == nid_of_current)
489-
break;
479+
/*
480+
* Try local node first. If it doesn't have an EPC section,
481+
* fall back to the non-local NUMA nodes.
482+
*/
483+
if (node_isset(nid_of_current, sgx_numa_mask))
484+
nid_start = nid_of_current;
485+
else
486+
nid_start = next_node_in(nid_of_current, sgx_numa_mask);
490487

488+
nid = nid_start;
489+
do {
491490
page = __sgx_alloc_epc_page_from_node(nid);
492491
if (page)
493492
return page;
494-
}
493+
494+
nid = next_node_in(nid, sgx_numa_mask);
495+
} while (nid != nid_start);
495496

496497
return ERR_PTR(-ENOMEM);
497498
}
@@ -731,7 +732,7 @@ int arch_memory_failure(unsigned long pfn, int flags)
731732
return 0;
732733
}
733734

734-
/**
735+
/*
735736
* A section metric is concatenated in a way that @low bits 12-31 define the
736737
* bits 12-31 of the metric and @high bits 0-19 define the bits 32-51 of the
737738
* metric.
@@ -846,6 +847,13 @@ static bool __init sgx_page_cache_init(void)
846847
return false;
847848
}
848849

850+
for_each_online_node(nid) {
851+
if (!node_isset(nid, sgx_numa_mask) &&
852+
node_state(nid, N_MEMORY) && node_state(nid, N_CPU))
853+
pr_info("node%d has both CPUs and memory but doesn't have an EPC section\n",
854+
nid);
855+
}
856+
849857
return true;
850858
}
851859

arch/x86/kvm/vmx/sgx.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ static int handle_encls_ecreate(struct kvm_vcpu *vcpu)
274274
* simultaneously set SGX_ATTR_PROVISIONKEY to bypass the check to
275275
* enforce restriction of access to the PROVISIONKEY.
276276
*/
277-
contents = (struct sgx_secs *)__get_free_page(GFP_KERNEL_ACCOUNT);
277+
contents = (struct sgx_secs *)__get_free_page(GFP_KERNEL);
278278
if (!contents)
279279
return -ENOMEM;
280280

arch/x86/kvm/vmx/vmx.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7999,6 +7999,7 @@ static __init void vmx_set_cpu_caps(void)
79997999
kvm_cpu_cap_clear(X86_FEATURE_SGX_LC);
80008000
kvm_cpu_cap_clear(X86_FEATURE_SGX1);
80018001
kvm_cpu_cap_clear(X86_FEATURE_SGX2);
8002+
kvm_cpu_cap_clear(X86_FEATURE_SGX_EDECCSSA);
80028003
}
80038004

80048005
if (vmx_umip_emulated())

tools/testing/selftests/sgx/Makefile

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,16 @@ OBJCOPY := $(CROSS_COMPILE)objcopy
1212
endif
1313

1414
INCLUDES := -I$(top_srcdir)/tools/include
15-
HOST_CFLAGS := -Wall -Werror -g $(INCLUDES) -fPIC -z noexecstack
16-
ENCL_CFLAGS := -Wall -Werror -static -nostdlib -nostartfiles -fPIC \
15+
HOST_CFLAGS := -Wall -Werror -g $(INCLUDES) -fPIC
16+
HOST_LDFLAGS := -z noexecstack -lcrypto
17+
ENCL_CFLAGS += -Wall -Werror -static-pie -nostdlib -ffreestanding -fPIE \
1718
-fno-stack-protector -mrdrnd $(INCLUDES)
19+
ENCL_LDFLAGS := -Wl,-T,test_encl.lds,--build-id=none
1820

21+
ifeq ($(CAN_BUILD_X86_64), 1)
1922
TEST_CUSTOM_PROGS := $(OUTPUT)/test_sgx
2023
TEST_FILES := $(OUTPUT)/test_encl.elf
2124

22-
ifeq ($(CAN_BUILD_X86_64), 1)
2325
all: $(TEST_CUSTOM_PROGS) $(OUTPUT)/test_encl.elf
2426
endif
2527

@@ -28,7 +30,7 @@ $(OUTPUT)/test_sgx: $(OUTPUT)/main.o \
2830
$(OUTPUT)/sigstruct.o \
2931
$(OUTPUT)/call.o \
3032
$(OUTPUT)/sign_key.o
31-
$(CC) $(HOST_CFLAGS) -o $@ $^ -lcrypto
33+
$(CC) $(HOST_CFLAGS) -o $@ $^ $(HOST_LDFLAGS)
3234

3335
$(OUTPUT)/main.o: main.c
3436
$(CC) $(HOST_CFLAGS) -c $< -o $@
@@ -45,8 +47,8 @@ $(OUTPUT)/call.o: call.S
4547
$(OUTPUT)/sign_key.o: sign_key.S
4648
$(CC) $(HOST_CFLAGS) -c $< -o $@
4749

48-
$(OUTPUT)/test_encl.elf: test_encl.lds test_encl.c test_encl_bootstrap.S
49-
$(CC) $(ENCL_CFLAGS) -T $^ -o $@ -Wl,--build-id=none
50+
$(OUTPUT)/test_encl.elf: test_encl.c test_encl_bootstrap.S
51+
$(CC) $(ENCL_CFLAGS) $^ -o $@ $(ENCL_LDFLAGS)
5052

5153
EXTRA_CLEAN := \
5254
$(OUTPUT)/test_encl.elf \

tools/testing/selftests/sgx/defines.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313

1414
#define __aligned(x) __attribute__((__aligned__(x)))
1515
#define __packed __attribute__((packed))
16+
#define __used __attribute__((used))
17+
#define __section(x)__attribute__((__section__(x)))
1618

1719
#include "../../../../arch/x86/include/asm/sgx.h"
1820
#include "../../../../arch/x86/include/asm/enclu.h"

tools/testing/selftests/sgx/load.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -136,11 +136,11 @@ static bool encl_ioc_add_pages(struct encl *encl, struct encl_segment *seg)
136136
*/
137137
uint64_t encl_get_entry(struct encl *encl, const char *symbol)
138138
{
139+
Elf64_Sym *symtab = NULL;
140+
char *sym_names = NULL;
139141
Elf64_Shdr *sections;
140-
Elf64_Sym *symtab;
141142
Elf64_Ehdr *ehdr;
142-
char *sym_names;
143-
int num_sym;
143+
int num_sym = 0;
144144
int i;
145145

146146
ehdr = encl->bin;
@@ -161,6 +161,9 @@ uint64_t encl_get_entry(struct encl *encl, const char *symbol)
161161
}
162162
}
163163

164+
if (!symtab || !sym_names)
165+
return 0;
166+
164167
for (i = 0; i < num_sym; i++) {
165168
Elf64_Sym *sym = &symtab[i];
166169

tools/testing/selftests/sgx/sigstruct.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -318,9 +318,9 @@ bool encl_measure(struct encl *encl)
318318
struct sgx_sigstruct *sigstruct = &encl->sigstruct;
319319
struct sgx_sigstruct_payload payload;
320320
uint8_t digest[SHA256_DIGEST_LENGTH];
321+
EVP_MD_CTX *ctx = NULL;
321322
unsigned int siglen;
322323
RSA *key = NULL;
323-
EVP_MD_CTX *ctx;
324324
int i;
325325

326326
memset(sigstruct, 0, sizeof(*sigstruct));
@@ -384,7 +384,8 @@ bool encl_measure(struct encl *encl)
384384
return true;
385385

386386
err:
387-
EVP_MD_CTX_destroy(ctx);
387+
if (ctx)
388+
EVP_MD_CTX_destroy(ctx);
388389
RSA_free(key);
389390
return false;
390391
}

tools/testing/selftests/sgx/test_encl.c

Lines changed: 45 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@
55
#include "defines.h"
66

77
/*
8-
* Data buffer spanning two pages that will be placed first in .data
9-
* segment. Even if not used internally the second page is needed by
10-
* external test manipulating page permissions.
8+
* Data buffer spanning two pages that will be placed first in the .data
9+
* segment via the linker script. Even if not used internally the second page
10+
* is needed by external test manipulating page permissions, so mark
11+
* encl_buffer as "used" to make sure it is entirely preserved by the compiler.
1112
*/
12-
static uint8_t encl_buffer[8192] = { 1 };
13+
static uint8_t __used __section(".data.encl_buffer") encl_buffer[8192] = { 1 };
1314

1415
enum sgx_enclu_function {
1516
EACCEPT = 0x5,
@@ -24,10 +25,11 @@ static void do_encl_emodpe(void *_op)
2425
secinfo.flags = op->flags;
2526

2627
asm volatile(".byte 0x0f, 0x01, 0xd7"
27-
:
28+
: /* no outputs */
2829
: "a" (EMODPE),
2930
"b" (&secinfo),
30-
"c" (op->epc_addr));
31+
"c" (op->epc_addr)
32+
: "memory" /* read from secinfo pointer */);
3133
}
3234

3335
static void do_encl_eaccept(void *_op)
@@ -42,7 +44,8 @@ static void do_encl_eaccept(void *_op)
4244
: "=a" (rax)
4345
: "a" (EACCEPT),
4446
"b" (&secinfo),
45-
"c" (op->epc_addr));
47+
"c" (op->epc_addr)
48+
: "memory" /* read from secinfo pointer */);
4649

4750
op->ret = rax;
4851
}
@@ -119,21 +122,41 @@ static void do_encl_op_nop(void *_op)
119122

120123
}
121124

125+
/*
126+
* Symbol placed at the start of the enclave image by the linker script.
127+
* Declare this extern symbol with visibility "hidden" to ensure the compiler
128+
* does not access it through the GOT and generates position-independent
129+
* addressing as __encl_base(%rip), so we can get the actual enclave base
130+
* during runtime.
131+
*/
132+
extern const uint8_t __attribute__((visibility("hidden"))) __encl_base;
133+
134+
typedef void (*encl_op_t)(void *);
135+
static const encl_op_t encl_op_array[ENCL_OP_MAX] = {
136+
do_encl_op_put_to_buf,
137+
do_encl_op_get_from_buf,
138+
do_encl_op_put_to_addr,
139+
do_encl_op_get_from_addr,
140+
do_encl_op_nop,
141+
do_encl_eaccept,
142+
do_encl_emodpe,
143+
do_encl_init_tcs_page,
144+
};
145+
122146
void encl_body(void *rdi, void *rsi)
123147
{
124-
const void (*encl_op_array[ENCL_OP_MAX])(void *) = {
125-
do_encl_op_put_to_buf,
126-
do_encl_op_get_from_buf,
127-
do_encl_op_put_to_addr,
128-
do_encl_op_get_from_addr,
129-
do_encl_op_nop,
130-
do_encl_eaccept,
131-
do_encl_emodpe,
132-
do_encl_init_tcs_page,
133-
};
134-
135-
struct encl_op_header *op = (struct encl_op_header *)rdi;
136-
137-
if (op->type < ENCL_OP_MAX)
138-
(*encl_op_array[op->type])(op);
148+
struct encl_op_header *header = (struct encl_op_header *)rdi;
149+
encl_op_t op;
150+
151+
if (header->type >= ENCL_OP_MAX)
152+
return;
153+
154+
/*
155+
* The enclave base address needs to be added, as this call site
156+
* *cannot be* made rip-relative by the compiler, or fixed up by
157+
* any other possible means.
158+
*/
159+
op = ((uint64_t)&__encl_base) + encl_op_array[header->type];
160+
161+
(*op)(header);
139162
}

0 commit comments

Comments
 (0)