From 59443ee76e4c46d478059821fbaa16c4e5816504 Mon Sep 17 00:00:00 2001 From: fandehui Date: Thu, 28 Dec 2023 10:37:57 +0800 Subject: [PATCH] Linux 2.11 Open Source Gold Release Supported new OS: RHEL 8.2 and SUSE 15. Provided standalone Intel(R) SGX DCAP Quote verification library installer. Added Intel(R) SGX DCAP Platform Certificate ID Retrieval Tool and Multi-package Registration Agent (MPA) installers into SGX installation repo. Fixed bugs. Signed-off-by: fandehui --- ...-linux-2.11-Open-Source-Gold-Release.patch | 2209 +++++++++++++++++ linux-sgx.spec | 6 +- 2 files changed, 2214 insertions(+), 1 deletion(-) create mode 100644 backport-linux-2.11-Open-Source-Gold-Release.patch diff --git a/backport-linux-2.11-Open-Source-Gold-Release.patch b/backport-linux-2.11-Open-Source-Gold-Release.patch new file mode 100644 index 0000000..7e9acda --- /dev/null +++ b/backport-linux-2.11-Open-Source-Gold-Release.patch @@ -0,0 +1,2209 @@ +From b9b071b54476e93ba21ae4f8dc41394970667cdd Mon Sep 17 00:00:00 2001 +From: "Li, Xun" +Date: Fri, 28 Aug 2020 08:46:47 +0800 +Subject: [PATCH] Linux 2.11 Open Source Gold Release + +Supported new OS: RHEL 8.2 and SUSE 15. +Provided standalone Intel(R) SGX DCAP Quote verification library installer. +Added Intel(R) SGX DCAP Platform Certificate ID Retrieval Tool and Multi-package Registration + Agent (MPA) installers into SGX installation repo. +Fixed bugs. + +Signed-off-by: Li, Xun +--- + .gitmodules | 2 +- + Makefile | 89 ++-- + README.md | 51 +-- + SampleCode/LocalAttestation/util/fifo.cpp | 3 +- + .../service_provider/service_provider.cpp | 14 +- + common/inc/internal/rts.h | 7 +- + common/inc/internal/se_version.h | 18 +- + common/inc/sgx_defs.h | 22 +- + common/inc/sgx_random_buffers.h | 8 +- + common/inc/{internal => }/sgx_rsrv_mem_mngr.h | 33 +- + common/inc/sgx_thread.h | 32 ++ + common/inc/tlibc/pthread.h | 13 +- + download_prebuilt.sh | 8 +- + external/dcap_source | 2 +- + external/dnnl/Makefile | 12 +- + external/ippcp_internal/Makefile | 9 +- + external/openmp/Makefile | 9 +- + linux/installer/common/sdk/BOMs/sdk_base.txt | 1 + + .../sgx-aesm-service-1.0/debian/control | 4 +- + .../libsgx-aesm-ecdsa-plugin.spec | 2 +- + .../libsgx-aesm-pce-plugin.spec | 2 +- + linux/reproducibility/README.md | 24 ++ + .../build_and_launch_docker.sh | 114 ++++-- + linux/reproducibility/start_build.sh.tmp | 37 +- + psw/urts/enclave.cpp | 14 +- + psw/urts/enclave_creator_hw_com.cpp | 2 +- + psw/urts/linux/urts_emodpr.cpp | 28 +- + psw/urts/linux/urts_emodpr.h | 2 +- + psw/urts/urts_com.h | 2 +- + sdk/pthread/Makefile | 3 +- + sdk/pthread/pthread_rwlock.cpp | 158 +++++++ + sdk/switchless/sgx_uswitchless/Makefile | 1 + + sdk/tlibthread/Makefile | 1 + + sdk/tlibthread/sethread_internal.h | 31 ++ + sdk/tlibthread/sethread_mutex.cpp | 1 + + sdk/tlibthread/sethread_rwlock.cpp | 387 ++++++++++++++++++ + sdk/tmm_rsrv/sgx_rsrv_mem.cpp | 79 +++- + sdk/trts/trts_ecall.cpp | 2 +- + sdk/trts/trts_emodpr.cpp | 5 +- + sdk/trts/trts_emodpr.h | 2 +- + 40 files changed, 1032 insertions(+), 202 deletions(-) + rename common/inc/{internal => }/sgx_rsrv_mem_mngr.h (64%) + create mode 100644 sdk/pthread/pthread_rwlock.cpp + create mode 100644 sdk/tlibthread/sethread_rwlock.cpp + +diff --git a/.gitmodules b/.gitmodules +index 7a3b7259..091847bb 100644 +--- a/.gitmodules ++++ b/.gitmodules +@@ -7,7 +7,7 @@ + branch = svn-tags/RELEASE_801 + [submodule "dnnl"] + path = external/dnnl/dnnl +- url = https://github.com/intel/mkl-dnn.git ++ url = https://github.com/oneapi-src/oneDNN.git + branch = rls-v1.1 + [submodule "ipp-crypto"] + path = external/ippcp_internal/ipp-crypto +diff --git a/Makefile b/Makefile +index 35253364..8d803d62 100644 +--- a/Makefile ++++ b/Makefile +@@ -29,17 +29,8 @@ + # + # + +-DCAP_VER?= 1.7 +-DCAP_DOWNLOAD_BASE ?= https://github.com/intel/SGXDataCenterAttestationPrimitives/archive +- +-CHECK_OPT := +-ifeq ("$(wildcard ./external/dcap_source/QuoteGeneration)", "") +-CHECK_OPT := dcap_source +-endif +- + include buildenv.mk +-.PHONY: all dcap_source psw sdk clean rebuild sdk_install_pkg psw_install_pkg +-.NOTPARALLEL: dcap_source sdk psw ++.PHONY: all preparation psw sdk clean rebuild sdk_install_pkg psw_install_pkg + + all: tips + +@@ -55,26 +46,26 @@ tips: + @echo " 3) enter the commmand: \"make psw\"" + @echo " 3. If you want to build other targets, please also follow README.md in same directory" + +-dcap_source: +-ifeq ($(shell git rev-parse --is-inside-work-tree), true) ++ ++preparation: ++# As SDK build needs to clone and patch openmp, we cannot support the mode that download the source from github as zip. ++# Only enable the download from git + git submodule update --init --recursive +-else +- curl --output dcap_source.tar.gz -L --tlsv1 ${DCAP_DOWNLOAD_BASE}/DCAP_${DCAP_VER}.tar.gz +- tar xvzf dcap_source.tar.gz +- $(RM) dcap_source.tar.gz +- $(RM) -rf external/dcap_source +- mv SGXDataCenterAttestationPrimitives-DCAP_${DCAP_VER} external/dcap_source +-endif ++ ./external/dcap_source/QuoteVerification/prepare_sgxssl.sh nobuild ++ cd external/openmp/openmp_code && git apply ../0001-Enable-OpenMP-in-SGX.patch >/dev/null 2>&1 || git apply ../0001-Enable-OpenMP-in-SGX.patch --check -R ++ @# download prebuilt binaries ++ ./download_prebuilt.sh ++ ./external/dcap_source/QuoteGeneration/download_prebuilt.sh + +-psw: $(CHECK_OPT) ++psw: + $(MAKE) -C psw/ USE_OPT_LIBS=$(USE_OPT_LIBS) + +-sdk_no_mitigation: $(CHECK_OPT) ++sdk_no_mitigation: + $(MAKE) -C sdk/ USE_OPT_LIBS=$(USE_OPT_LIBS) + $(MAKE) -C external/dcap_source/QuoteVerification/dcap_tvl clean + $(MAKE) -C external/dcap_source/QuoteVerification/dcap_tvl + +-sdk: $(CHECK_OPT) ++sdk: + $(MAKE) -C sdk/ clean + $(MAKE) -C sdk/ MODE=$(MODE) MITIGATION-CVE-2020-0551=LOAD + $(MAKE) -C sdk/ clean +@@ -98,8 +89,8 @@ sdk_install_pkg: sdk + psw_install_pkg: psw + ifeq ("$(wildcard ./external/dcap_source/QuoteGeneration/psw/ae/data/prebuilt/libsgx_qe3.signed.so)", "") + ./external/dcap_source/QuoteGeneration/download_prebuilt.sh +- $(CP) external/dcap_source/QuoteGeneration/psw/ae/data/prebuilt/libsgx_qe3.signed.so $(BUILD_DIR) + endif ++ $(CP) external/dcap_source/QuoteGeneration/psw/ae/data/prebuilt/libsgx_qe3.signed.so $(BUILD_DIR) + ./linux/installer/bin/build-installpkg.sh psw + + .PHONY: deb_libsgx_ae_qe3 +@@ -165,6 +156,11 @@ deb_libsgx_dcap_ql: + $(MAKE) -C external/dcap_source/QuoteGeneration deb_sgx_dcap_ql_pkg + $(CP) external/dcap_source/QuoteGeneration/installer/linux/deb/libsgx-dcap-ql/libsgx-dcap-ql*deb ./linux/installer/deb/sgx-aesm-service/ + ++.PHONY: deb_sgx_dcap_quote_verify ++deb_sgx_dcap_quote_verify: ++ $(MAKE) -C external/dcap_source/QuoteGeneration deb_sgx_dcap_quote_verify_pkg ++ $(CP) external/dcap_source/QuoteGeneration/installer/linux/deb/libsgx-dcap-quote-verify/libsgx-dcap-quote-verify*deb ./linux/installer/deb/sgx-aesm-service/ ++ + .PHONY: deb_libsgx_ae_qve + deb_libsgx_ae_qve: + ifeq ("$(wildcard ./external/dcap_source/QuoteGeneration/psw/ae/data/prebuilt/libsgx_qve.signed.so)", "") +@@ -173,8 +169,21 @@ endif + $(MAKE) -C external/dcap_source/QuoteGeneration deb_sgx_ae_qve_pkg + $(CP) external/dcap_source/QuoteGeneration/installer/linux/deb/libsgx-ae-qve/libsgx-ae-qve*deb ./linux/installer/deb/sgx-aesm-service/ + ++.PHONY: deb_sgx_pck_id_retrieval_tool_pkg ++deb_sgx_pck_id_retrieval_tool_pkg: ++ $(MAKE) -C external/dcap_source/QuoteGeneration deb_sgx_pck_id_retrieval_tool_pkg ++ $(CP) external/dcap_source/tools/PCKRetrievalTool/installer/deb/sgx-pck-id-retrieval-tool/sgx-pck-id-retrieval-tool*deb ./linux/installer/deb/sgx-aesm-service/ ++ ++ ++.PHONY: deb_sgx_ra_service_pkg ++deb_sgx_ra_service_pkg: ++ $(MAKE) -C external/dcap_source/QuoteGeneration deb_sgx_ra_service_pkg ++ $(CP) external/dcap_source/tools/SGXPlatformRegistration/build/installer/sgx-ra-service*deb ./linux/installer/deb/sgx-aesm-service/ ++ $(CP) external/dcap_source/tools/SGXPlatformRegistration/build/installer/libsgx-ra-*deb ./linux/installer/deb/sgx-aesm-service/ ++ ++ + .PHONY: deb_psw_pkg +-deb_psw_pkg: deb_libsgx_qe3_logic deb_libsgx_pce_logic deb_sgx_aesm_service deb_libsgx_epid deb_libsgx_launch deb_libsgx_quote_ex deb_libsgx_uae_service deb_libsgx_enclave_common deb_libsgx_urts deb_libsgx_ae_qe3 deb_libsgx_dcap_default_qpl deb_libsgx_dcap_pccs deb_libsgx_dcap_ql deb_libsgx_ae_qve ++deb_psw_pkg: deb_libsgx_qe3_logic deb_libsgx_pce_logic deb_sgx_aesm_service deb_libsgx_epid deb_libsgx_launch deb_libsgx_quote_ex deb_libsgx_uae_service deb_libsgx_enclave_common deb_libsgx_urts deb_libsgx_ae_qe3 deb_libsgx_dcap_default_qpl deb_libsgx_dcap_pccs deb_libsgx_dcap_ql deb_libsgx_ae_qve deb_sgx_dcap_quote_verify deb_sgx_pck_id_retrieval_tool_pkg deb_sgx_ra_service_pkg + endif + + .PHONY: deb_local_repo +@@ -256,8 +265,24 @@ endif + $(MAKE) -C external/dcap_source/QuoteGeneration rpm_sgx_ae_qve_pkg + $(CP) external/dcap_source/QuoteGeneration/installer/linux/rpm/libsgx-ae-qve/libsgx-ae-qve*rpm ./linux/installer/rpm/sgx-aesm-service/ + ++.PHONY: rpm_sgx_dcap_quote_verify ++rpm_sgx_dcap_quote_verify: ++ $(MAKE) -C external/dcap_source/QuoteGeneration rpm_sgx_dcap_quote_verify_pkg ++ $(CP) external/dcap_source/QuoteGeneration/installer/linux/rpm/libsgx-dcap-quote-verify/libsgx-dcap-quote-verify*rpm ./linux/installer/rpm/sgx-aesm-service/ ++ ++.PHONY: rpm_sgx_pck_id_retrieval_tool_pkg ++rpm_sgx_pck_id_retrieval_tool_pkg: ++ $(MAKE) -C external/dcap_source/QuoteGeneration rpm_sgx_pck_id_retrieval_tool_pkg ++ $(CP) external/dcap_source/tools/PCKRetrievalTool/installer/rpm/sgx-pck-id-retrieval-tool/sgx-pck-id-retrieval-tool*rpm ./linux/installer/rpm/sgx-aesm-service/ ++ ++.PHONY: rpm_sgx_ra_service_pkg ++rpm_sgx_ra_service_pkg: ++ $(MAKE) -C external/dcap_source/QuoteGeneration rpm_sgx_ra_service_pkg ++ $(CP) external/dcap_source/tools/SGXPlatformRegistration/build/installer/sgx-ra-service*rpm ./linux/installer/rpm/sgx-aesm-service/ ++ $(CP) external/dcap_source/tools/SGXPlatformRegistration/build/installer/libsgx-ra-*rpm ./linux/installer/rpm/sgx-aesm-service/ ++ + .PHONY: rpm_psw_pkg +-rpm_psw_pkg: rpm_libsgx_pce_logic rpm_libsgx_qe3_logic rpm_sgx_aesm_service rpm_libsgx_epid rpm_libsgx_launch rpm_libsgx_quote_ex rpm_libsgx_uae_service rpm_libsgx_enclave_common rpm_libsgx_urts rpm_libsgx_ae_qe3 rpm_libsgx_dcap_default_qpl rpm_libsgx_dcap_pccs rpm_libsgx_dcap_ql rpm_libsgx_ae_qve ++rpm_psw_pkg: rpm_libsgx_pce_logic rpm_libsgx_qe3_logic rpm_sgx_aesm_service rpm_libsgx_epid rpm_libsgx_launch rpm_libsgx_quote_ex rpm_libsgx_uae_service rpm_libsgx_enclave_common rpm_libsgx_urts rpm_libsgx_ae_qe3 rpm_libsgx_dcap_default_qpl rpm_libsgx_dcap_pccs rpm_libsgx_dcap_ql rpm_libsgx_ae_qve rpm_sgx_dcap_quote_verify rpm_sgx_pck_id_retrieval_tool_pkg rpm_sgx_ra_service_pkg + endif + + .PHONY: rpm_local_repo +@@ -303,6 +328,7 @@ ifeq ("$(shell test -f external/dcap_source/QuoteVerification/Makefile && echo M + ./external/dcap_source/QuoteGeneration/installer/linux/deb/libsgx-dcap-ql/clean.sh + ./external/dcap_source/QuoteGeneration/installer/linux/deb/libsgx-pce-logic/clean.sh + ./external/dcap_source/QuoteGeneration/installer/linux/deb/libsgx-qe3-logic/clean.sh ++ ./external/dcap_source/QuoteGeneration/installer/linux/deb/libsgx-dcap-quote-verify/clean.sh + ./external/dcap_source/QuoteGeneration/installer/linux/deb/sgx-dcap-pccs/clean.sh + ./external/dcap_source/QuoteGeneration/installer/linux/rpm/libsgx-ae-qve/clean.sh + ./external/dcap_source/QuoteGeneration/installer/linux/rpm/libsgx-ae-qe3/clean.sh +@@ -310,9 +336,22 @@ ifeq ("$(shell test -f external/dcap_source/QuoteVerification/Makefile && echo M + ./external/dcap_source/QuoteGeneration/installer/linux/rpm/libsgx-dcap-ql/clean.sh + ./external/dcap_source/QuoteGeneration/installer/linux/rpm/libsgx-pce-logic/clean.sh + ./external/dcap_source/QuoteGeneration/installer/linux/rpm/libsgx-qe3-logic/clean.sh ++ ./external/dcap_source/QuoteGeneration/installer/linux/rpm/libsgx-dcap-quote-verify/clean.sh + ./external/dcap_source/QuoteGeneration/installer/linux/rpm/sgx-dcap-pccs/clean.sh + endif + + rebuild: + $(MAKE) clean + $(MAKE) all ++ ++.PHONY: distclean ++distclean: ++ $(MAKE) clean ++ # Cleanup ++ $(RM) -r 'Intel redistributable binary.txt' Master_EULA_for_Intel_Sw_Development_Products.pdf redist.txt ++ $(RM) -rf external/ippcp_internal/inc/*.h external/ippcp_internal/lib/ external/ippcp_internal/license ++ $(RM) -rf external/toolset psw/ae/data/prebuilt/lib*.so psw/ae/data/prebuilt/README.md ++ $(RM) -rf external/dcap_source/QuoteGeneration/psw/ae/data/prebuilt/ ++ $(RM) -rf external/dcap_source/QuoteGeneration/'Intel redistributable binary.txt' ++ $(RM) -rf external/dcap_source/QuoteVerification/sgxssl/ ++ git submodule deinit --all -f +diff --git a/README.md b/README.md +index 62ea669d..51f1305d 100644 +--- a/README.md ++++ b/README.md +@@ -56,10 +56,10 @@ Build the Intel(R) SGX SDK and Intel(R) SGX PSW Package + * Ubuntu\* 18.04 LTS Desktop 64bits + * Ubuntu\* 18.04 LTS Server 64bits + * Red Hat Enterprise Linux Server release 7.6 64bits +- * Red Hat Enterprise Linux Server release 8.1 64bits ++ * Red Hat Enterprise Linux Server release 8.2 64bits + * CentOS 8.1 64bits + * Fedora 31 Server 64bits +- * SUSE Linux Enterprise Server 12 64bits ++ * SUSE Linux Enterprise Server 15 64bits + + - Use the following command(s) to install the required tools to build the Intel(R) SGX SDK: + * On Ubuntu 16.04: +@@ -70,7 +70,7 @@ Build the Intel(R) SGX SDK and Intel(R) SGX PSW Package + ``` + $ sudo apt-get install build-essential ocaml ocamlbuild automake autoconf libtool wget python libssl-dev git cmake perl + ``` +- * On Red Hat Enterprise Linux 7.6, Red Hat Enterprise Linux 8.1: ++ * On Red Hat Enterprise Linux 7.6, Red Hat Enterprise Linux 8.2: + ``` + $ sudo yum groupinstall 'Development Tools' + $ sudo yum install ocaml ocaml-ocamlbuild wget python2 openssl-devel git cmake perl +@@ -87,19 +87,19 @@ Build the Intel(R) SGX SDK and Intel(R) SGX PSW Package + $ sudo yum groupinstall 'C Development Tools and Libraries' + $ sudo yum install ocaml ocaml-ocamlbuild redhat-rpm-config openssl-devel wget python rpm-build git cmake perl + ``` +- * On SUSE Linux Enterprise Server 12: ++ * On SUSE Linux Enterprise Server 15: + ``` + $ sudo zypper install --type pattern devel_basis + $ sudo zypper install ocaml ocaml-ocamlbuild automake autoconf libtool wget python libopenssl-devel rpm-build git cmake perl + ``` +- **Note**: To build Intel(R) SGX SDK, gcc version is required to be 7.3 or above and glibc version is required to be 2.27 or above. For Ubuntu 16.04, Red Hat Enterprise Linux 7.6 and SUSE Linux Enterprise Server 12, you may need to update gcc and glibc version manually. ++ **Note**: To build Intel(R) SGX SDK, gcc version is required to be 7.3 or above and glibc version is required to be 2.27 or above. For Ubuntu 16.04, Red Hat Enterprise Linux 7.6, you may need to update gcc and glibc version manually. + - Use the following command to install additional required tools and latest Intel(R) SGX SDK Installer to build the Intel(R) SGX PSW: + 1) To install the additional required tools: + * On Ubuntu 16.04 and Ubuntu 18.04: + ``` + $ sudo apt-get install libssl-dev libcurl4-openssl-dev protobuf-compiler libprotobuf-dev debhelper cmake reprepro unzip + ``` +- * On Red Hat Enterprise Linux 7.6, Red Hat Enterprise Linux 8.1 and Fedora 31: ++ * On Red Hat Enterprise Linux 7.6, Red Hat Enterprise Linux 8.2 and Fedora 31: + ``` + $ sudo yum install openssl-devel libcurl-devel protobuf-devel cmake rpm-build createrepo yum-utils + ``` +@@ -107,18 +107,19 @@ Build the Intel(R) SGX SDK and Intel(R) SGX PSW Package + ``` + $ sudo dnf --enablerepo=PowerTools install openssl-devel libcurl-devel protobuf-devel cmake rpm-build createrepo yum-utils + ``` +- * On SUSE Linux Enterprise Server 12: ++ * On SUSE Linux Enterprise Server 15: + ``` + $ sudo zypper install libopenssl-devel libcurl-devel protobuf-devel cmake rpm-build createrepo + ``` + 2) To install latest Intel(R) SGX SDK Installer + Ensure that you have downloaded latest Intel(R) SGX SDK Installer from the [Intel(R) SGX SDK](https://software.intel.com/en-us/sgx-sdk/download) and followed the Installation Guide in the same page to install latest Intel(R) SGX SDK Installer. +- +-- Use the script ``download_prebuilt.sh`` inside source code package to download prebuilt binaries to prebuilt folder +- You may need set an https proxy for the `wget` tool used by the script (such as ``export https_proxy=http://test-proxy:test-port``) ++ ++- Download the source code and prepare the submodules and prebuilt binaries: + ``` +- $ ./download_prebuilt.sh ++ $ git clone https://github.com/intel/linux-sgx.git . ++ $ cd linux-sgx && make preparation + ``` ++ The above ``make preparation`` would trigger the script ``download_prebuilt.sh`` to download the prebuilt binaries. You may need to set an https proxy for the `wget` tool used by the script (such as ``export https_proxy=http://test-proxy:test-port``) + + - Copy the mitigation tools corresponding to current OS distribution from external/toolset/{current_distr} to /usr/local/bin and make sure they have execute permission: + ``` +@@ -203,7 +204,7 @@ You can find the tools and libraries generated in the `build/linux` directory. + ``` + $ make deb_psw_pkg DEBUG=1 + ``` +- * On Red Hat Enterprise Linux 7.6, Red Hat Enterprise Linux 8.1, CentOS 8.1, Fedora 31 and SUSE Linux Enterprise Server 12: ++ * On Red Hat Enterprise Linux 7.6, Red Hat Enterprise Linux 8.2, CentOS 8.1, Fedora 31 and SUSE Linux Enterprise Server 15: + ``` + $ make rpm_psw_pkg + ``` +@@ -247,20 +248,20 @@ You can find the tools and libraries generated in the `build/linux` directory. + **Note**: The above command builds the local package repository. If you want to use it, you need to add it to the system repository configuration. Since the local package repository is not signed with GPG, you should ignore the gpgcheck when installing the packages. + + - To add the local RPM package repository to the system repository configuration, you can use the following command. You need to replace PATH_TO_LOCAL_REPO with the proper path on your system: +- * On Red Hat Enterprise Linux 7.6, Red Hat Enterprise Linux 8.1, CentOS 8.1, Fedora 31: ++ * On Red Hat Enterprise Linux 7.6, Red Hat Enterprise Linux 8.2, CentOS 8.1, Fedora 31: + ``` + $ sudo yum-config-manager --add-repo file://PATH_TO_LOCAL_REPO + ``` +- * On SUSE Linux Enterprise Server 12, you need to replace LOCAL_REPO_ALIAS with proper alias name for the local repo: ++ * On SUSE Linux Enterprise Server 15, you need to replace LOCAL_REPO_ALIAS with proper alias name for the local repo: + ``` + $ sudo zypper addrepo PATH_TO_LOCAL_REPO LOCAL_REPO_ALIAS + ``` + - To ignore the gpgcheck when you install the package, enter the following command: +- * On Red Hat Enterprise Linux 7.6, Red Hat Enterprise Linux 8.1, CentOS 8.1, Fedora 31: ++ * On Red Hat Enterprise Linux 7.6, Red Hat Enterprise Linux 8.2, CentOS 8.1, Fedora 31: + ``` + $ sudo yum --nogpgcheck install + ``` +- * On SUSE Linux Enterprise Server 12: ++ * On SUSE Linux Enterprise Server 15: + ``` + $ sudo zypper --no-gpg-checks install + ``` +@@ -274,16 +275,16 @@ Install the Intel(R) SGX SDK + * Ubuntu\* 18.04 LTS Desktop 64bits + * Ubuntu\* 18.04 LTS Server 64bits + * Red Hat Enterprise Linux Server release 7.6 64bits +- * Red Hat Enterprise Linux Server release 8.1 64bits ++ * Red Hat Enterprise Linux Server release 8.2 64bits + * CentOS 8.1 64bits + * Fedora 31 Server 64bits +- * SUSE Linux Enterprise Server 12 64bits ++ * SUSE Linux Enterprise Server 15 64bits + - Use the following command to install the required tool to use Intel(R) SGX SDK: + * On Ubuntu 16.04 and Ubuntu 18.04: + ``` + $ sudo apt-get install build-essential python + ``` +- * On Red Hat Enterprise Linux 7.6, Red Hat Enterprise Linux 8.1 and CentOS 8.1: ++ * On Red Hat Enterprise Linux 7.6, Red Hat Enterprise Linux 8.2 and CentOS 8.1: + ``` + $ sudo yum groupinstall 'Development Tools' + $ sudo yum install python2 +@@ -293,7 +294,7 @@ Install the Intel(R) SGX SDK + ``` + $ sudo yum groupinstall 'C Development Tools and Libraries' + ``` +- * On SUSE Linux Enterprise Server 12: ++ * On SUSE Linux Enterprise Server 15: + ``` + $ sudo zypper install --type pattern devel_basis + $ sudo zypper install python +@@ -344,10 +345,10 @@ Install the Intel(R) SGX PSW + * Ubuntu\* 18.04 LTS Desktop 64bits + * Ubuntu\* 18.04 LTS Server 64bits + * Red Hat Enterprise Linux Server release 7.6 64bits +- * Red Hat Enterprise Linux Server release 8.1 64bits ++ * Red Hat Enterprise Linux Server release 8.2 64bits + * CentOS 8.1 64bits + * Fedora 31 Server 64bits +- * SUSE Linux Enterprise Server 12 64bits ++ * SUSE Linux Enterprise Server 15 64bits + - Ensure that you have a system with the following required hardware: + * 6th Generation Intel(R) Core(TM) Processor or newer + - Configure the system with the **Intel SGX hardware enabled** option and install Intel(R) SGX driver in advance. +@@ -357,7 +358,7 @@ Install the Intel(R) SGX PSW + ``` + $ sudo apt-get install libssl-dev libcurl4-openssl-dev libprotobuf-dev + ``` +- * On Red Hat Enterprise Linux 7.6, Red Hat Enterprise Linux 8.1 and Fedora 31: ++ * On Red Hat Enterprise Linux 7.6, Red Hat Enterprise Linux 8.2 and Fedora 31: + ``` + $ sudo yum install openssl-devel libcurl-devel protobuf-devel + ``` +@@ -365,7 +366,7 @@ Install the Intel(R) SGX PSW + ``` + $ sudo dnf --enablerepo=PowerTools install libcurl-devel protobuf-devel + ``` +- * On SUSE Linux Enterprise Server 12: ++ * On SUSE Linux Enterprise Server 15: + ``` + $ sudo zypper install libopenssl-devel libcurl-devel protobuf-devel + ``` +@@ -375,7 +376,7 @@ Install the Intel(R) SGX PSW + + #### Using the local repo(recommended) + +- | |Ubuntu 16.04, Ubuntu 18.04|Red Hat Enterprise Linux 7.6, Red Hat Enterprise Linux 8.1, CentOS 8.1, Fedora 31|SUSE Linux Enterprise Server 12| ++ | |Ubuntu 16.04, Ubuntu 18.04|Red Hat Enterprise Linux 7.6, Red Hat Enterprise Linux 8.2, CentOS 8.1, Fedora 31|SUSE Linux Enterprise Server 15| + | ------------ | ------------ | ------------ | ------------ | + |launch service |apt-get install libsgx-launch libsgx-urts|yum install libsgx-launch libsgx-urts|zypper install libsgx-launch libsgx-urts| + |EPID-based attestation service|apt-get install libsgx-epid libsgx-urts|yum install libsgx-epid libsgx-urts|zypper install libsgx-epid libsgx-urts|| +diff --git a/SampleCode/LocalAttestation/util/fifo.cpp b/SampleCode/LocalAttestation/util/fifo.cpp +index 8faa8962..b2064bbe 100644 +--- a/SampleCode/LocalAttestation/util/fifo.cpp ++++ b/SampleCode/LocalAttestation/util/fifo.cpp +@@ -62,7 +62,7 @@ int client_send_receive(FIFO_MSG *fiforequest, size_t fiforequest_size, FIFO_MSG + long byte_num; + char recv_msg[BUFFER_SIZE + 1] = {0}; + FIFO_MSG * response = NULL; +- ++ + struct sockaddr_un server_addr; + int server_sock_fd = socket(PF_UNIX, SOCK_STREAM, 0); + if (server_sock_fd == -1) +@@ -133,3 +133,4 @@ CLEAN: + + return ret; + } ++ +diff --git a/SampleCode/RemoteAttestation/service_provider/service_provider.cpp b/SampleCode/RemoteAttestation/service_provider/service_provider.cpp +index 7254baa8..1844237d 100644 +--- a/SampleCode/RemoteAttestation/service_provider/service_provider.cpp ++++ b/SampleCode/RemoteAttestation/service_provider/service_provider.cpp +@@ -319,14 +319,14 @@ int sp_ra_proc_msg1_req(const sample_ra_msg1_t *p_msg1, + { + // Get the sig_rl from attestation server using GID. + // GID is Base-16 encoded of EPID GID in little-endian format. +- // In the product, the SP and attestation server uses an established channel for ++ // In the product, the SP and attesation server uses an established channel for + // communication. + uint8_t* sig_rl; + uint32_t sig_rl_size = 0; + + // The product interface uses a REST based message to get the SigRL. +- //! Refer to the attestation server API for more information on how to communicate to +- //! the real attestation server. ++ //! Refer to the attesation server API for more information on how to communicate to ++ //! the real attesation server. + ret = g_sp_extended_epid_group_id->get_sigrl(p_msg1->gid, &sig_rl_size, &sig_rl); + if(0 != ret) + { +@@ -344,7 +344,7 @@ int sp_ra_proc_msg1_req(const sample_ra_msg1_t *p_msg1, + break; + } + +- // Generate the Service providers ECDH key pair. ++ // Generate the Service providers ECCDH key pair. + sample_ret = sample_ecc256_open_context(&ecc_state); + if(SAMPLE_SUCCESS != sample_ret) + { +@@ -365,7 +365,7 @@ int sp_ra_proc_msg1_req(const sample_ra_msg1_t *p_msg1, + break; + } + +- // Need to save the SP ECDH key pair to local storage. ++ // Need to save the SP ECCDH key pair to local storage. + if(memcpy_s(&g_sp_db.b, sizeof(g_sp_db.b), &priv_key,sizeof(priv_key)) + || memcpy_s(&g_sp_db.g_b, sizeof(g_sp_db.g_b), + &pub_key,sizeof(pub_key))) +@@ -861,3 +861,7 @@ int sp_ra_proc_msg3_req(const sample_ra_msg3_t *p_msg3, + } + return ret; + } ++ ++ ++ ++ +diff --git a/common/inc/internal/rts.h b/common/inc/internal/rts.h +index 48c8539b..aa30804b 100644 +--- a/common/inc/internal/rts.h ++++ b/common/inc/internal/rts.h +@@ -64,7 +64,8 @@ typedef enum + SDK_VERSION_1_5, + SDK_VERSION_2_0, + SDK_VERSION_2_1, +- SDK_VERSION_2_2 ++ SDK_VERSION_2_2, ++ SDK_VERSION_2_3 + } sdk_version_t; + + typedef struct _system_features +@@ -93,16 +94,18 @@ typedef struct _system_features + #define BUILTIN_OCALL_1 -2 + #define BUILTIN_OCALL_2 -3 + #define BUILTIN_OCALL_3 -4 ++#define BUILTIN_OCALL_4 -5 + + typedef enum + { + EDMM_TRIM = BUILTIN_OCALL_1, + EDMM_TRIM_COMMIT = BUILTIN_OCALL_2, + EDMM_MODPR = BUILTIN_OCALL_3, ++ EDMM_MPROTECT = BUILTIN_OCALL_4, + }edmm_ocall_t; + + +-#define is_builtin_ocall(ocall_val) (((int)ocall_val >= BUILTIN_OCALL_3) && ((int)ocall_val <= BUILTIN_OCALL_1)) ++#define is_builtin_ocall(ocall_val) (((int)ocall_val >= BUILTIN_OCALL_4) && ((int)ocall_val <= BUILTIN_OCALL_1)) + + #pragma pack(pop) + +diff --git a/common/inc/internal/se_version.h b/common/inc/internal/se_version.h +index 0c564694..d09a0c3d 100644 +--- a/common/inc/internal/se_version.h ++++ b/common/inc/internal/se_version.h +@@ -31,20 +31,20 @@ + #ifndef _SE_VERSION_H_ + #define _SE_VERSION_H_ + +-#define STRFILEVER "2.10.100.2" ++#define STRFILEVER "2.11.100.2" + #define SGX_MAJOR_VERSION 2 +-#define SGX_MINOR_VERSION 10 +-#define SGX_REVISION_VERSION 102 ++#define SGX_MINOR_VERSION 11 ++#define SGX_REVISION_VERSION 100 + #define MAKE_VERSION_UINT(major,minor,rev) (((uint64_t)major)<<32 | ((uint64_t)minor) << 16 | rev) + #define VERSION_UINT MAKE_VERSION_UINT(SGX_MAJOR_VERSION, SGX_MINOR_VERSION, SGX_REVISION_VERSION) + + #define COPYRIGHT "Copyright (C) 2020 Intel Corporation" + +-#define UAE_SERVICE_VERSION "2.3.204.2" +-#define URTS_VERSION "1.1.108.2" +-#define ENCLAVE_COMMON_VERSION "1.0.111.2" +-#define LAUNCH_VERSION "1.0.106.2" +-#define EPID_VERSION "1.0.106.2" +-#define QUOTE_EX_VERSION "1.1.106.2" ++#define UAE_SERVICE_VERSION "2.3.205.2" ++#define URTS_VERSION "1.1.109.2" ++#define ENCLAVE_COMMON_VERSION "1.0.112.2" ++#define LAUNCH_VERSION "1.0.107.2" ++#define EPID_VERSION "1.0.107.2" ++#define QUOTE_EX_VERSION "1.1.107.2" + + #endif +diff --git a/common/inc/sgx_defs.h b/common/inc/sgx_defs.h +index 87a2be9f..8ff79370 100644 +--- a/common/inc/sgx_defs.h ++++ b/common/inc/sgx_defs.h +@@ -34,21 +34,21 @@ + + /* The following macros are for GCC only */ + +-# define SGXAPI ++#define SGXAPI + +-# ifdef linux +-# undef linux +-# endif +-# define SGX_CXX_NATIVE_HEADER(header) ++#ifdef linux ++ #undef linux ++#endif ++#define SGX_CXX_NATIVE_HEADER(header) + +-# define SGX_CDECL +-# define SGX_STDCALL +-# define SGX_FASTCALL ++#define SGX_CDECL ++#define SGX_STDCALL ++#define SGX_FASTCALL + +-# define SGX_DLLIMPORT +-# define SGX_UBRIDGE(attr, fname, args...) attr fname args ++#define SGX_DLLIMPORT ++#define SGX_UBRIDGE(attr, fname, args...) attr fname args + +-# define SGX_DEPRECATED __attribute__((deprecated)) ++#define SGX_DEPRECATED __attribute__((deprecated)) + + + #define SGX_NOCONVENTION /* Empty. No calling convention specified. */ +diff --git a/common/inc/sgx_random_buffers.h b/common/inc/sgx_random_buffers.h +index 1d54a385..56727cbd 100644 +--- a/common/inc/sgx_random_buffers.h ++++ b/common/inc/sgx_random_buffers.h +@@ -53,8 +53,14 @@ template + inline R rdrand(void) + { + R r; +- __asm__ volatile ("rdrand %0" : "=r"(r)); ++ __asm__ volatile ( ++ "1: rdrand %0\n" ++ " jnc 1b\n" ++ : "=r" (r) ++ ); ++ + return r; ++ + } + + /* +diff --git a/common/inc/internal/sgx_rsrv_mem_mngr.h b/common/inc/sgx_rsrv_mem_mngr.h +similarity index 64% +rename from common/inc/internal/sgx_rsrv_mem_mngr.h +rename to common/inc/sgx_rsrv_mem_mngr.h +index 9553fd68..7af4d8a5 100644 +--- a/common/inc/internal/sgx_rsrv_mem_mngr.h ++++ b/common/inc/sgx_rsrv_mem_mngr.h +@@ -45,21 +45,38 @@ + #ifdef __cplusplus + extern "C" { + #endif ++ ++ /* Return the start address and/or the max size info for the reserved memory ++ * ++ * Parameters: ++ * start_addr[out] - the start address of the reserved memory ++ * max_size[out] - the maximum size of the reserved memory ++ * Return: sgx_status_t - SGX_SUCCESS or failure as defined in sgx_error.h ++ */ ++ sgx_status_t sgx_get_rsrv_mem_info(void ** start_addr, size_t * max_size); ++ ++ /* Allocate a range of EPC memory with a fixed address from the reserved memory area with RW permission ++ * ++ * Parameters: ++ * desired_addr[in] - the desired address to allocate the reserved memory. Page aligned ++ * length [in] - Size of region to be allocated in bytes. Page aligned ++ * Return: Starting address of the new allocated memory area on success; otherwise NULL ++ */ ++ void * sgx_alloc_rsrv_mem_ex(void * desired_addr, size_t length); + + /* Allocate a range of EPC memory from the reserved memory area with RW permission + * + * Parameters: +- * Inputs: length [in]: Size of region to be allocated in bytes. Page aligned ++ * length [in] - Size of region to be allocated in bytes. Page aligned + * Return: Starting address of the new allocated memory area on success; otherwise NULL + */ + void * sgx_alloc_rsrv_mem(size_t length); + +- + /* Free a range of EPC memory from the reserved memory area + * + * Parameters: +- * Inputs: addr[in]: Starting address of region to be freed. Page aligned. +- * length[in]: The length of the memory to be freed in bytes. Page aligned ++ * addr[in] - Starting address of region to be freed. Page aligned. ++ * length[in] - The length of the memory to be freed in bytes. Page aligned + * Return: 0 on success; otherwise -1 + */ + int sgx_free_rsrv_mem(void * addr, size_t length); +@@ -68,12 +85,12 @@ extern "C" { + /* Modify the access permissions of the pages in the reserved memory area. + * + * Parameters: +- * Inputs: addr[in]: Starting address of region which needs to change access permission. Page aligned. +- * length[in]: The length of the memory to be manipulated in bytes. Page aligned. +- * prot[in]: The target memory protection. ++ * addr[in] - Starting address of region which needs to change access permission. Page aligned. ++ * length[in] - The length of the memory to be manipulated in bytes. Page aligned. ++ * prot[in] - The target memory protection. + * Return: sgx_status_t - SGX_SUCCESS or failure as defined in sgx_error.h + */ +- sgx_status_t sgx_tprotect_rsrv_mem(void *addr, size_t len, int prot); ++ sgx_status_t sgx_tprotect_rsrv_mem(void *addr, size_t length, int prot); + + + #ifdef __cplusplus +diff --git a/common/inc/sgx_thread.h b/common/inc/sgx_thread.h +index 2be8bb4a..323a79c2 100644 +--- a/common/inc/sgx_thread.h ++++ b/common/inc/sgx_thread.h +@@ -54,6 +54,17 @@ typedef struct _sgx_thread_mutex_t + sgx_thread_queue_t m_queue; + } sgx_thread_mutex_t; + ++/* read write lock */ ++typedef struct _sgx_thread_rwlock_t ++{ ++ uint32_t m_reader_count; /*number of readers holding the lock*/ ++ uint32_t m_writers_waiting; /*number of writers waiting for the lock*/ ++ volatile uint32_t m_lock; /* use sgx_spinlock_t */ ++ sgx_thread_t m_owner; /* owner of the lock - must be a writer*/ ++ sgx_thread_queue_t m_reader_queue; /* readers waiting */ ++ sgx_thread_queue_t m_writer_queue; /* writers waiting */ ++} sgx_thread_rwlock_t; ++ + #define SGX_THREAD_T_NULL ((sgx_thread_t)(NULL)) + + #define SGX_THREAD_MUTEX_NONRECURSIVE 0x01 +@@ -65,11 +76,21 @@ typedef struct _sgx_thread_mutex_t + #define SGX_THREAD_MUTEX_INITIALIZER \ + SGX_THREAD_NONRECURSIVE_MUTEX_INITIALIZER + ++#define SGX_THREAD_LOCK_INITIALIZER \ ++ {0, 0, 0, SGX_THREAD_T_NULL, {SGX_THREAD_T_NULL, SGX_THREAD_T_NULL}, {SGX_THREAD_T_NULL, SGX_THREAD_T_NULL}} ++ ++ ++ + typedef struct _sgx_thread_mutex_attr_t + { + unsigned char m_dummy; /* for C syntax check */ + } sgx_thread_mutexattr_t; + ++typedef struct _sgx_thread_rwlock_attr_t ++{ ++ unsigned char m_dummy; /* for C syntax check */ ++} sgx_thread_rwlockattr_t; ++ + /* Condition Variable */ + typedef struct _sgx_thread_cond_t + { +@@ -96,6 +117,17 @@ int SGXAPI sgx_thread_mutex_lock(sgx_thread_mutex_t *mutex); + int SGXAPI sgx_thread_mutex_trylock(sgx_thread_mutex_t *mutex); + int SGXAPI sgx_thread_mutex_unlock(sgx_thread_mutex_t *mutex); + ++/* Reader/Writer Locks */ ++int SGXAPI sgx_thread_rwlock_init(sgx_thread_rwlock_t *rwlock, const sgx_thread_rwlockattr_t *unused); ++int SGXAPI sgx_thread_rwlock_destroy(sgx_thread_rwlock_t *rwlock); ++int SGXAPI sgx_thread_rwlock_rdlock(sgx_thread_rwlock_t *rwlock); ++int SGXAPI sgx_thread_rwlock_wrlock(sgx_thread_rwlock_t *rwlock); ++int SGXAPI sgx_thread_rwlock_rdunlock(sgx_thread_rwlock_t *rwlock); ++int SGXAPI sgx_thread_rwlock_wrunlock(sgx_thread_rwlock_t *rwlock); ++int SGXAPI sgx_thread_rwlock_unlock(sgx_thread_rwlock_t *rwlock); ++int SGXAPI sgx_thread_rwlock_tryrdlock(sgx_thread_rwlock_t *rwlock); ++int SGXAPI sgx_thread_rwlock_trywrlock(sgx_thread_rwlock_t *rwlock); ++ + /* Condition Variable */ + int SGXAPI sgx_thread_cond_init(sgx_thread_cond_t *cond, const sgx_thread_condattr_t *unused); + int SGXAPI sgx_thread_cond_destroy(sgx_thread_cond_t *cond); +diff --git a/common/inc/tlibc/pthread.h b/common/inc/tlibc/pthread.h +index f59770c6..ab3b605b 100644 +--- a/common/inc/tlibc/pthread.h ++++ b/common/inc/tlibc/pthread.h +@@ -58,8 +58,8 @@ typedef struct _sgx_thread_mutex_attr_t *pthread_mutexattr_t; + typedef struct _sgx_thread_cond_t *pthread_cond_t; + typedef struct _sgx_thread_cond_attr_t *pthread_condattr_t; + typedef int pthread_key_t; +-//typedef struct pthread_rwlock *pthread_rwlock_t; +-//typedef struct pthread_rwlockattr *pthread_rwlockattr_t; ++typedef struct _sgx_thread_rwlock_t *pthread_rwlock_t; ++typedef struct _sgx_thread_rwlockattr_t *pthread_rwlockattr_t; + //typedef struct pthread_barrier *pthread_barrier_t; + //typedef struct pthread_barrierattr *pthread_barrierattr_t; + //typedef struct pthread_spinlock *pthread_spinlock_t; +@@ -98,6 +98,15 @@ int SGXAPI pthread_cond_wait(pthread_cond_t *, pthread_mutex_t *); + int SGXAPI pthread_cond_signal(pthread_cond_t *); + int SGXAPI pthread_cond_broadcast(pthread_cond_t *); + ++/* RW Locks */ ++int SGXAPI pthread_rwlock_init(pthread_rwlock_t *, const pthread_rwlockattr_t *); ++int SGXAPI pthread_rwlock_destroy(pthread_rwlock_t *); ++int SGXAPI pthread_rwlock_rdlock(pthread_rwlock_t *); ++int SGXAPI pthread_rwlock_tryrdlock(pthread_rwlock_t *); ++int SGXAPI pthread_rwlock_wrlock(pthread_rwlock_t *); ++int SGXAPI pthread_rwlock_trywrlock(pthread_rwlock_t *); ++int SGXAPI pthread_rwlock_unlock(pthread_rwlock_t *); ++ + /* tls */ + int SGXAPI pthread_key_create(pthread_key_t *, void (*destructor)(void*)); + int SGXAPI pthread_key_delete(pthread_key_t); +diff --git a/download_prebuilt.sh b/download_prebuilt.sh +index 9dd484dd..be972962 100755 +--- a/download_prebuilt.sh ++++ b/download_prebuilt.sh +@@ -33,11 +33,11 @@ + + top_dir=`dirname $0` + out_dir=$top_dir +-optlib_name=optimized_libs_2.10.tar.gz +-ae_file_name=prebuilt_ae_2.10.tar.gz ++optlib_name=optimized_libs_2.11.tar.gz ++ae_file_name=prebuilt_ae_2.11.tar.gz + binutils_file_name=as.ld.objdump.gold.r2.tar.gz +-checksum_file=SHA256SUM_prebuilt_2.10.txt +-server_url_path=https://download.01.org/intel-sgx/sgx-linux/2.10/ ++checksum_file=SHA256SUM_prebuilt_2.11.txt ++server_url_path=https://download.01.org/intel-sgx/sgx-linux/2.11/ + server_optlib_url=$server_url_path/$optlib_name + server_ae_url=$server_url_path/$ae_file_name + server_binutils_url=$server_url_path/$binutils_file_name +diff --git a/external/dcap_source b/external/dcap_source +index 96ea09b7..c9b70740 160000 +--- a/external/dcap_source ++++ b/external/dcap_source +@@ -1 +1 @@ +-Subproject commit 96ea09b72c52852be166ce21e435562e74f9966d ++Subproject commit c9b707408d14fc1f1dcc519950bafb8bc58f0f42 +diff --git a/external/dnnl/Makefile b/external/dnnl/Makefile +index feb1444d..4a850db7 100644 +--- a/external/dnnl/Makefile ++++ b/external/dnnl/Makefile +@@ -76,15 +76,15 @@ $(SGX_DNNL_INCLUDE): + + .PHONY: dnnl_src + dnnl_src: +-ifeq ($(shell git rev-parse --is-inside-work-tree), true) +- @$(RM) -r $(DNNL_DIR)/* +- git submodule update -f --init dnnl +- cd $(DNNL_DIR) && git am ../sgx_dnnl.patch +-else ++#ifeq ($(shell git rev-parse --is-inside-work-tree), true) ++# @$(RM) -r $(DNNL_DIR)/* ++# git submodule update -f --init dnnl ++# cd $(DNNL_DIR) && git am ../sgx_dnnl.patch ++#else + @$(RM) -r $(DNNL_DIR) + git clone https://github.com/intel/mkl-dnn.git -b v1.1.1 --depth 1 $(DNNL_DIR) + cd $(DNNL_DIR) && git am ../sgx_dnnl.patch +-endif ++#endif + + $(LIBDNNL):$(CHECK_SOURCE) + mkdir -p $(DNNL_DIR)/build && cd $(DNNL_DIR)/build && cmake -DCMAKE_CXX_ENCLAVE_FLAGS="$(CXX_ENCLAVE_FLAGS)" -DCMAKE_C_ENCLAVE_FLAGS="$(C_ENCLAVE_FLAGS)" $(DNNL_CONFIG) .. && make +diff --git a/external/ippcp_internal/Makefile b/external/ippcp_internal/Makefile +index 32fa2891..b8218a11 100644 +--- a/external/ippcp_internal/Makefile ++++ b/external/ippcp_internal/Makefile +@@ -89,12 +89,13 @@ build_ipp: $(CHECK_PATCHED) + + .PHONY: ipp_source + ipp_source: +-ifeq ($(shell git rev-parse --is-inside-work-tree), true) +- git submodule update -f --init --recursive --remote -- $(IPP_SOURCE) +-else ++## Need to enable below code when release ++#ifeq ($(shell git rev-parse --is-inside-work-tree), true) ++# git submodule update -f --init --recursive --remote -- $(IPP_SOURCE) ++#else + $(RM) -rf $(IPP_SOURCE) + git clone -b ipp-crypto_2019_update5 https://github.com/intel/ipp-crypto.git --depth 1 $(IPP_SOURCE) +-endif ++#endif + cd $(IPP_SOURCE) && git am ../0001-Add-mitigation-support-to-assembly-code.patch + + .PHONY: clean +diff --git a/external/openmp/Makefile b/external/openmp/Makefile +index 9c049d1b..acc92d76 100644 +--- a/external/openmp/Makefile ++++ b/external/openmp/Makefile +@@ -56,12 +56,13 @@ $(BUILD_DIR): + + .PHONY: omp_code + omp_code: +-ifeq ($(shell git rev-parse --is-inside-work-tree 2> /dev/null), true) +- git submodule update -f --init --recursive --remote -- $(OMP_DIR) +-else ++## Need to enable below code when release ++#ifeq ($(shell git rev-parse --is-inside-work-tree 2> /dev/null), true) ++# git submodule update -f --init --recursive --remote -- $(OMP_DIR) ++#else + $(RM) -rf openmp_code + git clone -b svn-tags/RELEASE_801 https://github.com/llvm-mirror/openmp.git --depth 1 $(OMP_DIR) +-endif ++#endif + + + $(LIBOMP): $(CHECK_SOURCE) +diff --git a/linux/installer/common/sdk/BOMs/sdk_base.txt b/linux/installer/common/sdk/BOMs/sdk_base.txt +index 219d9efe..1300c49e 100644 +--- a/linux/installer/common/sdk/BOMs/sdk_base.txt ++++ b/linux/installer/common/sdk/BOMs/sdk_base.txt +@@ -39,6 +39,7 @@ DeliveryName InstallName FileCheckSum FileFeature FileOwner + /common/inc/sgx_pcl_guid.h /package/include/./sgx_pcl_guid.h 0 main STP + /common/inc/sgx_secure_align.h /package/include/./sgx_secure_align.h 0 main STP + /common/inc/sgx_secure_align_api.h /package/include/./sgx_secure_align_api.h 0 main STP ++/common/inc/sgx_rsrv_mem_mngr.h /package/include/sgx_rsrv_mem_mngr.h 0 main STP + /common/inc/stdc++/exception /package/include/stdc++/exception 0 main STP + /common/inc/stdc++/linux/exception /package/include/stdc++/linux/exception 0 main STP + /common/inc/stdc++/linux/typeinfo /package/include/stdc++/linux/typeinfo 0 main STP +diff --git a/linux/installer/deb/sgx-aesm-service/sgx-aesm-service-1.0/debian/control b/linux/installer/deb/sgx-aesm-service/sgx-aesm-service-1.0/debian/control +index 66aa7c2c..532c3683 100644 +--- a/linux/installer/deb/sgx-aesm-service/sgx-aesm-service-1.0/debian/control ++++ b/linux/installer/deb/sgx-aesm-service/sgx-aesm-service-1.0/debian/control +@@ -37,12 +37,12 @@ Description: Unified Quote Plugin for Intel(R) Software Guard Extensions AESM Se + + Package: libsgx-aesm-ecdsa-plugin + Architecture: amd64 +-Depends: ${shlibs:Depends}, ${misc:Depends}, sgx-aesm-service(>= @dep_version@), libsgx-qe3-logic(>= 1.7), libsgx-aesm-pce-plugin(>= @dep_version@) ++Depends: ${shlibs:Depends}, ${misc:Depends}, sgx-aesm-service(>= @dep_version@), libsgx-qe3-logic(>= 1.8), libsgx-aesm-pce-plugin(>= @dep_version@) + Description: ECDSA Quote Plugin for Intel(R) Software Guard Extensions AESM Service + + Package: libsgx-aesm-pce-plugin + Architecture: amd64 +-Depends: ${shlibs:Depends}, ${misc:Depends}, sgx-aesm-service(>= @dep_version@), libsgx-pce-logic(>= 1.7), libsgx-ae-pce(>= @dep_version@) ++Depends: ${shlibs:Depends}, ${misc:Depends}, sgx-aesm-service(>= @dep_version@), libsgx-pce-logic(>= 1.8), libsgx-ae-pce(>= @dep_version@) + Description: PCE Plugin for Intel(R) Software Guard Extensions AESM Service + + Package: libsgx-ae-pce +diff --git a/linux/installer/rpm/sgx-aesm-service/libsgx-aesm-ecdsa-plugin.spec b/linux/installer/rpm/sgx-aesm-service/libsgx-aesm-ecdsa-plugin.spec +index 03d5e82d..b74322ca 100644 +--- a/linux/installer/rpm/sgx-aesm-service/libsgx-aesm-ecdsa-plugin.spec ++++ b/linux/installer/rpm/sgx-aesm-service/libsgx-aesm-ecdsa-plugin.spec +@@ -38,7 +38,7 @@ Version: @version@ + Release: 1%{?dist} + Summary: ECDSA Quote Plugin for Intel(R) Software Guard Extensions AESM Service + Group: Development/System +-Requires: sgx-aesm-service >= %{version}-%{release} libsgx-qe3-logic >= 1.7 libsgx-aesm-pce-plugin >= %{version}-%{release} ++Requires: sgx-aesm-service >= %{version}-%{release} libsgx-qe3-logic >= 1.8 libsgx-aesm-pce-plugin >= %{version}-%{release} + + License: BSD License + URL: https://github.com/intel/linux-sgx +diff --git a/linux/installer/rpm/sgx-aesm-service/libsgx-aesm-pce-plugin.spec b/linux/installer/rpm/sgx-aesm-service/libsgx-aesm-pce-plugin.spec +index 26dd9424..a99e0e84 100644 +--- a/linux/installer/rpm/sgx-aesm-service/libsgx-aesm-pce-plugin.spec ++++ b/linux/installer/rpm/sgx-aesm-service/libsgx-aesm-pce-plugin.spec +@@ -38,7 +38,7 @@ Version: @version@ + Release: 1%{?dist} + Summary: PCE Plugin for Intel(R) Software Guard Extensions AESM Service + Group: Development/System +-Requires: sgx-aesm-service >= %{version}-%{release} libsgx-pce-logic >= 1.7 ++Requires: sgx-aesm-service >= %{version}-%{release} libsgx-pce-logic >= 1.8 + + License: BSD License + URL: https://github.com/intel/linux-sgx +diff --git a/linux/reproducibility/README.md b/linux/reproducibility/README.md +index c95e9158..d3e2962d 100644 +--- a/linux/reproducibility/README.md ++++ b/linux/reproducibility/README.md +@@ -31,3 +31,27 @@ In order to reproduce the enclave build, there are three requirements:1. stable + ``` + $ ./build_and_launch_docker.sh + ``` ++ c) Below command triggers the reproducible build for 'ae' using a specified reproducible SGX SDK installer and code repo. Of course, you need to prepare the SGX SDK installer and SGX source repo beforehand. ++ ``` ++ $ ./build_and_launch_docker.sh --reproduce-type ae --code-dir ~/code_dir --sdk-installer {prepared_sdk_installer} --sgx-src-dir {prepared_sgx_src} ++ ``` ++ ++ ++**Note**: ++To reproduce QVE, you need to apply below patch to the [build_and_launch_docker.sh](./build_and_launch_docker.sh) before start the reproducible build with the script. ++``` ++diff --git a/linux/reproducibility/build_and_launch_docker.sh b/linux/reproducibility/build_and_launch_docker.sh ++index b85eda85..f8bc6812 100755 ++--- a/linux/reproducibility/build_and_launch_docker.sh +++++ b/linux/reproducibility/build_and_launch_docker.sh ++@@ -188,6 +188,7 @@ prepare_sgx_src() ++ fi ++ ++ cd "$sgx_repo" && make preparation +++ mkdir dcap-trunk/ && mv external/dcap_source/ dcap-trunk/ && ln -sfr dcap-trunk/dcap_source external/dcap_source ++ popd ++ ++ } ++``` ++ ++ +diff --git a/linux/reproducibility/build_and_launch_docker.sh b/linux/reproducibility/build_and_launch_docker.sh +index bedf2cdb..5a7e8057 100755 +--- a/linux/reproducibility/build_and_launch_docker.sh ++++ b/linux/reproducibility/build_and_launch_docker.sh +@@ -34,7 +34,7 @@ + # in the docker container. + # + # Usage: +-# ./build_and_launch_docker.sh [ [ -d | --code-dir dir ] [ -t | --reproduce-type type ] | [ -h | --help ] ] ++# ./build_and_launch_docker.sh [ [ -d | --code-dir dir ] [ -t | --reproduce-type type ] | [ -i | --sdk-installer installer ] | [ -s | --sgx-src-dir src_dir ] [ -h | --help ] ] + # + # Options: + # -d, --code-dir: +@@ -48,8 +48,19 @@ + # If no type is provided, all the code will be prepared. And the build steps will + # be triggered in the container. Then you can choose to build what you want in the container. + # ++# -i, --sdk-installer: ++# Specify the SDK installer used for AE reproducibility. If this option is not specified, ++# script will download the default SDK installer. ++# ++# -s, --sgx-src-dir: ++# Specify the local sgx source path if you have pulled the sgx source code via `$git clone` ++# or by other ways. ++# If this option is specified, script will not clone sgx source but start the build based on ++# the code base specified by this option. ++# + # -h, --help: +-# Show this usage message.# ++# Show this usage message. ++# + # + + set -e +@@ -62,6 +73,13 @@ type="all" + type_flag=0 + mount_dir="/linux-sgx" + ++sdk_installer="" ++sgx_src="" ++ ++default_sdk_installer=sgx_linux_x64_sdk_reproducible_2.11.100.1.bin ++default_sdk_installer_url=https://download.01.org/intel-sgx/sgx-linux/2.11/distro/nix_reproducibility/$default_sdk_installer ++ ++ + usage() + { + echo " +@@ -69,20 +87,27 @@ usage() + in the docker container. + + Usage: +- $0 [ [ -d | --code-dir dir ] [ -t | --reproduce-type type ] | [ -h | --help ] ] ++ $0 [ [ -d | --code-dir dir ] [ -t | --reproduce-type type ] | [ -i | --sdk-installer installer ] | [ -s | --sgx-src-dir src_dir ] [ -h | --help ] ] + + Options: + -d, --code-dir: +- Specify the directory you want to download the repo. If this option is +- not specified, will use the same directory as the script location. +- ++ Specify the directory you want to prepare the code and share to the reproducible container. ++ If this option is not specified, will use the same directory as the script location. + -t, --reproduce-type: + Specify the reproducibility type. Provided options: all|sdk|ae|ipp|binutils. + If one type is provided, the corresponding code will be prepared. And the correponding + build steps will also be executed in the container automatically. + If no type is provided, all the code will be prepared. And the build steps will not + be triggered in the container. Then you can choose to build what you want in the container. +- ++ -i, --sdk-installer: ++ Specify the SDK installer used for AE reproducibility. ++ If this option is not provided, script will choose the default SDK installer to build AEs. ++ Only valid when the reproduce type is 'ae'. ++ -s, --sgx-src-dir: ++ Specify the local sgx source path if you have pulled the sgx source code via \`\$git clone\` ++ or by other ways. ++ If this option is specified, script will not clone sgx source but start the build based on ++ the code base specified by this option. + -h, --help: + Show this usage message." + } +@@ -106,12 +131,35 @@ parse_cmd() + usage + exit + ;; ++ -i | --sdk-installer ) shift ++ sdk_installer="$1" ++ if [ ! -f "$sdk_installer" ]; then ++ echo "The $sdk_installer doesn't exist." ++ usage ++ exit 1 ++ fi ++ sdk_installer="$(realpath $sdk_installer)" ++ ;; ++ -s | --sgx-src-dir) shift ++ sgx_src="$1" ++ if [ ! -d "$sgx_src" ]; then ++ echo "The $sgx_src doesn't exist." ++ usage ++ exit 1 ++ fi ++ sgx_src="$(realpath $sgx_src)" ++ ;; + * ) + usage + exit 1 + esac + shift + done ++ if [ "$type" != "ae" ] && [ $type_flag == 1 ] && [ "$sdk_installer" != "" ]; then ++ echo -e "\n ERROR: Option '--sdk-installer' is valid only if '--reproduce-type' is 'ae'." ++ usage ++ exit 1 ++ fi + mkdir -p "$code_dir" | exit + code_dir="$(realpath $code_dir)" + sgx_repo="$code_dir/sgx" +@@ -120,44 +168,29 @@ parse_cmd() + + prepare_sgx_src() + { ++ pushd . + if [ -d $sgx_repo ]; then + echo "Removing existing SGX code repo in $sgx_repo" + rm -rf $sgx_repo + fi + +- git clone https://github.com/intel/linux-sgx.git $sgx_repo +- cd $sgx_repo && ./download_prebuilt.sh && cd - +-} +- +-prepare_dcap_src() +-{ +- if [ ! -f $sgx_repo/Makefile ]; then +- echo "Please download the source repo firstly." +- exit -1 ++ # If user prepares the sgx code repo in the host machine, copy the code to $sgx_repo ++ # Otherwise, pull the sgx source code. ++ if [ "$sgx_src" != "" ]; then ++ mkdir -p "$sgx_repo" && cp -a "$sgx_src/." "$sgx_repo" ++ else ++ git clone -b sgx_2.11_reproducible https://github.com/intel/linux-sgx.git $sgx_repo + fi +- cd ${sgx_repo} && make dcap_source && cd - +- $sgx_repo/external/dcap_source/QuoteVerification/prepare_sgxssl.sh nobuild +-} + +-prepare_openmp_src() +-{ +- openmp_dir="$sgx_repo/external/openmp/" +- if [ ! -d $openmp_dir/openmp_code/final ]; then +- cd $openmp_dir && git clone -b svn-tags/RELEASE_801 https://github.com/llvm-mirror/openmp.git --depth 1 openmp_code && cd - +- fi +- if [ ! -f $openmp_dir/openmp_code/final/runtime/src/sgx_stub.h ]; then +- cd $openmp_dir/openmp_code && git apply ../0001-Enable-OpenMP-in-SGX.patch && cd - +- fi ++ cd "$sgx_repo" && make preparation ++ popd ++ + } + + prepare_ipp_src() + { + pushd . + ipp_dir="$sgx_repo/external/ippcp_internal" +- if [ ! -d $ipp_dir/ipp-crypto ]; then +- git clone -b ipp-crypto_2019_update5 https://github.com/intel/ipp-crypto.git --depth 1 $ipp_dir/ipp-crypto +- fi +- + patch_log="$( cd $ipp_dir/ipp-crypto && git log --oneline --grep='Add mitigation support to assembly code' | cut -d' ' -f 3)" + + if [ "$patch_log" != "mitigation" ]; then +@@ -182,14 +215,18 @@ prepare_binutils_src() + prepare_sdk_installer() + { + # Used for 'ae' type repreducibility. +- sdk_installer=sgx_linux_x64_sdk_2.10.100.2.bin +- sdk_url=https://download.01.org/intel-sgx/latest/linux-latest/distro/ubuntu18.04-server/$sdk_installer +- cd $code_dir && wget $sdk_url && chmod +x $sdk_installer && cd - ++ # If user prepares the sdk installer, we copy it to the right place ++ # Otherwise, we download one from 01.org ++ if [ "$sdk_installer" != "" ]; then ++ chmod +x "$sdk_installer" && cp "$sdk_installer" "$code_dir" ++ else ++ cd $code_dir && wget $default_sdk_installer_url && chmod +x $default_sdk_installer && cd - ++ fi + } + + generate_cmd_script() + { +- rm -rf $code_dir/cmd.sh ++ rm -f $code_dir/cmd.sh + + cat > $code_dir/cmd.sh << EOF + #!/usr/bin/env bash +@@ -214,18 +251,13 @@ case $type in + "all") + prepare_binutils_src + prepare_sgx_src +- prepare_dcap_src +- prepare_openmp_src + prepare_ipp_src + ;; + "sdk") + prepare_sgx_src +- prepare_dcap_src +- prepare_openmp_src + ;; + "ae") + prepare_sgx_src +- prepare_dcap_src + prepare_sdk_installer + ;; + "ipp") +diff --git a/linux/reproducibility/start_build.sh.tmp b/linux/reproducibility/start_build.sh.tmp +index 5328a8f2..9e0255ba 100644 +--- a/linux/reproducibility/start_build.sh.tmp ++++ b/linux/reproducibility/start_build.sh.tmp +@@ -1,6 +1,6 @@ + #!/usr/bin/env bash + # +-# Copyright (C) 2020 Intel Corporation. All rights reserved. ++# Copyright (C) 2011-2020 Intel Corporation. All rights reserved. + # + # Redistribution and use in source and binary forms, with or without + # modification, are permitted provided that the following conditions +@@ -57,10 +57,12 @@ clean_repo() + cd $sgx_repo/ && make clean + fi + if [ -f $binutils_repo/Makefile ]; then +- cd $binutils_repo && make clean && rm -rf Makefile ++ cd $binutils_repo && make clean ++ rm -f Makefile + fi + if [ -f $binutils_repo/gold/Makefile ]; then +- cd $binutils_repo/gold && make clean && rm -rf Makefile ++ cd $binutils_repo/gold && make clean ++ rm -f Makefile + fi + # uninstall SDK installer + if [ -x "$sdk_install_path/uninstall.sh" ]; then +@@ -75,9 +77,9 @@ build_ipp() + local ipp_out="$build_out/ipp" + pushd . + cd $sgx_repo/external/ippcp_internal/ +- make clean && make +- make clean && make MITIGATION-CVE-2020-0551=LOAD +- make clean && make MITIGATION-CVE-2020-0551=CF ++ make clean; make ++ make clean; make MITIGATION-CVE-2020-0551=LOAD ++ make clean; make MITIGATION-CVE-2020-0551=CF + mkdir -p "$ipp_out" + cp -r $sgx_repo/external/ippcp_internal/lib/linux/intel64/* "$ipp_out" + popd +@@ -87,7 +89,7 @@ build_sdk() + { + local sdk_out="$build_out/sdk" + pushd . +- cd $sgx_repo && make sdk_install_pkg ++ cd $sgx_repo; make sdk_install_pkg + local installer=$(find $sgx_repo/linux/installer/bin -name "sgx_linux_x64_sdk*.bin") + if [ ! -d "$sdk_out" ]; then + mkdir -p $sdk_out +@@ -119,7 +121,8 @@ build_ae() + exit 1 + fi + # Install sdk installer and source environment +- $sdk_installer --prefix=$sdk_prefix && . $sdk_install_path/environment ++ $sdk_installer --prefix=$sdk_prefix ++ source $sdk_install_path/environment + + # Current export MITIGATION_CFLAGS+=-B{toolset_dir} + # We can copy binutils to sdk installation folder +@@ -128,12 +131,18 @@ build_ae() + pushd . + local ae_out="$build_out/ae" + mkdir -p $ae_out +- cd $sgx_repo/psw/ae/le && make && cp le.so $ae_out +- cd $sgx_repo/psw/ae/pce && make && cp pce.so $ae_out +- cd $sgx_repo/psw/ae/pve && make && cp pve.so $ae_out +- cd $sgx_repo/psw/ae/qe && make && cp qe.so $ae_out +- cd $sgx_repo/external/dcap_source/QuoteGeneration/quote_wrapper/quote/enclave/linux && make && cp qe3.so $ae_out +- cd $sgx_repo/external/dcap_source/QuoteVerification/QvE && make && cp qve.so $ae_out ++ cd $sgx_repo/psw/ae/le && make ++ cp le.so $ae_out ++ cd $sgx_repo/psw/ae/pce && make ++ cp pce.so $ae_out ++ cd $sgx_repo/psw/ae/pve && make ++ cp pve.so $ae_out ++ cd $sgx_repo/psw/ae/qe && make ++ cp qe.so $ae_out ++ cd $sgx_repo/external/dcap_source/QuoteGeneration/quote_wrapper/quote/enclave/linux && make ++ cp qe3.so $ae_out ++ cd $sgx_repo/external/dcap_source/QuoteVerification/QvE && make ++ cp qve.so $ae_out + popd + } + +diff --git a/psw/urts/enclave.cpp b/psw/urts/enclave.cpp +index 429a4fa7..efdc3242 100644 +--- a/psw/urts/enclave.cpp ++++ b/psw/urts/enclave.cpp +@@ -413,12 +413,14 @@ int CEnclave::ocall(const unsigned int proc, const sgx_ocall_table_t *ocall_tabl + if (is_builtin_ocall(proc)) + { + se_rdunlock(&m_rwlock); +- if ((int)proc == EDMM_TRIM) +- error = ocall_trim_range(ms); +- else if ((int)proc == EDMM_TRIM_COMMIT) +- error = ocall_trim_accept(ms); +- else if ((int)proc == EDMM_MODPR) +- error = ocall_emodpr(ms); ++ if ((int)proc == EDMM_TRIM) ++ error = ocall_trim_range(ms); ++ else if ((int)proc == EDMM_TRIM_COMMIT) ++ error = ocall_trim_accept(ms); ++ else if ((int)proc == EDMM_MODPR) ++ error = ocall_emodpr(ms); ++ else if ((int)proc == EDMM_MPROTECT) ++ error = ocall_mprotect(ms); + } + else + { +diff --git a/psw/urts/enclave_creator_hw_com.cpp b/psw/urts/enclave_creator_hw_com.cpp +index 28d10a44..8b31b75b 100644 +--- a/psw/urts/enclave_creator_hw_com.cpp ++++ b/psw/urts/enclave_creator_hw_com.cpp +@@ -65,7 +65,7 @@ int EnclaveCreatorHW::initialize(sgx_enclave_id_t enclave_id) + init_cpuinfo((uint32_t *)info.cpuinfo_table); + info.system_feature_set[0] |= (1ULL << SYS_FEATURE_EXTEND); + info.size = sizeof(system_features_t); +- info.version = (sdk_version_t)MIN((uint32_t)SDK_VERSION_2_2, enclave->get_enclave_version()); ++ info.version = (sdk_version_t)MIN((uint32_t)SDK_VERSION_2_3, enclave->get_enclave_version()); + info.sealed_key = enclave->get_sealed_key(); + info.cpu_core_num = (uint32_t)sysconf(_SC_NPROCESSORS_ONLN); + if (is_EDMM_supported(enclave_id)) +diff --git a/psw/urts/linux/urts_emodpr.cpp b/psw/urts/linux/urts_emodpr.cpp +index 488fd3e7..4b5193b5 100644 +--- a/psw/urts/linux/urts_emodpr.cpp ++++ b/psw/urts/linux/urts_emodpr.cpp +@@ -59,11 +59,33 @@ sgx_status_t ocall_emodpr(void* pms) + return (sgx_status_t)ret; + } + } ++ if(ms->ms_epcm_perms != SI_FLAG_NONE) ++ { ++ ret = mprotect((void*)ms->ms_addr, ms->ms_size, (int)ms->ms_epcm_perms); ++ if(ret != 0) ++ { ++ return SGX_ERROR_UNEXPECTED; ++ } ++ } ++ ++ return SGX_SUCCESS; ++} + +- ret = mprotect((void*)ms->ms_addr, ms->ms_size, (int)ms->ms_epcm_perms); +- if(ret != 0) ++sgx_status_t ocall_mprotect(void *pms) ++{ ++ int ret = 0; ++ ms_trim_emodpr_ocall_t* ms = SGX_CAST(ms_trim_emodpr_ocall_t*, pms); ++ if(ms->ms_epcm_perms & ~(SI_FLAG_R|SI_FLAG_W|SI_FLAG_X)) ++ { ++ return SGX_ERROR_INVALID_PARAMETER; ++ } ++ else + { +- return SGX_ERROR_UNEXPECTED; ++ ret = mprotect((void*)ms->ms_addr, ms->ms_size, (int)ms->ms_epcm_perms); ++ if(ret != 0) ++ { ++ return SGX_ERROR_UNEXPECTED; ++ } + } + + return SGX_SUCCESS; +diff --git a/psw/urts/linux/urts_emodpr.h b/psw/urts/linux/urts_emodpr.h +index 13990ea5..17bf1201 100644 +--- a/psw/urts/linux/urts_emodpr.h ++++ b/psw/urts/linux/urts_emodpr.h +@@ -47,7 +47,7 @@ extern "C" { + + + sgx_status_t SGX_CDECL ocall_emodpr(void* pms); +- ++sgx_status_t SGX_CDECL ocall_mprotect(void *pms); + + + #ifdef __cplusplus +diff --git a/psw/urts/urts_com.h b/psw/urts/urts_com.h +index 8c37e2c7..39611562 100644 +--- a/psw/urts/urts_com.h ++++ b/psw/urts/urts_com.h +@@ -273,7 +273,7 @@ static int __create_enclave(BinParser &parser, + if (MAJOR_VERSION_OF_METADATA(metadata->version) == MAJOR_VERSION_OF_METADATA(urts_version) && + MINOR_VERSION_OF_METADATA(metadata->version) >= MINOR_VERSION_OF_METADATA(urts_version)) + { +- enclave_version = SDK_VERSION_2_2; ++ enclave_version = SDK_VERSION_2_3; + } + else if (MAJOR_VERSION_OF_METADATA(metadata->version) == MAJOR_VERSION_OF_METADATA(urts_version) && + MINOR_VERSION_OF_METADATA(metadata->version) < MINOR_VERSION_OF_METADATA(urts_version)) +diff --git a/sdk/pthread/Makefile b/sdk/pthread/Makefile +index 8f141a5c..93024002 100755 +--- a/sdk/pthread/Makefile ++++ b/sdk/pthread/Makefile +@@ -48,7 +48,8 @@ OBJ := pthread.o \ + pthread_once.o \ + pthread_mutex.o \ + pthread_cond.o \ +- pthread_tls.o ++ pthread_tls.o \ ++ pthread_rwlock.o + + EDGER8R_DIR = $(LINUX_SDK_DIR)/edger8r/linux + EDGER8R = $(EDGER8R_DIR)/_build/Edger8r.native +diff --git a/sdk/pthread/pthread_rwlock.cpp b/sdk/pthread/pthread_rwlock.cpp +new file mode 100644 +index 00000000..329ebc5a +--- /dev/null ++++ b/sdk/pthread/pthread_rwlock.cpp +@@ -0,0 +1,158 @@ ++/* $OpenBSD: rthread_cond.c,v 1.5 2019/01/29 17:40:26 mpi Exp $ */ ++/* ++ * Copyright (c) 2017 Martin Pieuchot ++ * Copyright (c) 2012 Philip Guenther ++ * ++ * Permission to use, copy, modify, and distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF ++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ */ ++ ++#include ++#include ++#include ++#include "sgx_trts.h" ++#include "sgx_spinlock.h" ++#include "pthread_imp.h" ++#include "util.h" ++ ++static volatile uint32_t static_init_lock = SGX_SPINLOCK_INITIALIZER; ++ ++int pthread_rwlock_init(pthread_rwlock_t *rwlockp, const pthread_rwlockattr_t *attr) ++{ ++ pthread_rwlock_t rwlock; ++ UNUSED(attr); ++ rwlock = (pthread_rwlock_t)calloc(1, sizeof(*rwlock)); ++ if (rwlock == NULL) ++ return (ENOMEM); ++ sgx_thread_rwlock_init(rwlock, NULL); ++ *rwlockp = rwlock; ++ return 0; ++} ++ ++int pthread_rwlock_destroy(pthread_rwlock_t *rwlockp) ++{ ++ if (rwlockp == NULL) ++ return (EINVAL); ++ ++ sgx_thread_rwlock_t *rwlock = *rwlockp; ++ if(rwlock) { ++ int ret = sgx_thread_rwlock_destroy(rwlock); ++ if(ret != 0) ++ return ret; ++ ++ free((void *)(rwlock)); ++ *rwlockp = NULL; ++ } ++ return 0; ++} ++ ++int pthread_rwlock_rdlock(pthread_rwlock_t *rwlockp) ++{ ++ if (rwlockp == NULL) ++ return (EINVAL); ++ int error = 0; ++ ++ /* ++ * If the rwlock is statically initialized, perform the dynamic ++ * initialization. ++ */ ++ if (*rwlockp == NULL) { ++ sgx_spin_lock(&static_init_lock); ++ if (*rwlockp == NULL) ++ error = pthread_rwlock_init(rwlockp, NULL); ++ sgx_spin_unlock(&static_init_lock); ++ if (error != 0) ++ return (EINVAL); ++ } ++ ++ return sgx_thread_rwlock_rdlock(*rwlockp); ++} ++ ++int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlockp) ++{ ++ if (rwlockp == NULL) ++ return (EINVAL); ++ int error=0; ++ ++ /* ++ * If the rwlock is statically initialized, perform the dynamic ++ * initialization. ++ */ ++ if (*rwlockp == NULL) { ++ sgx_spin_lock(&static_init_lock); ++ if (*rwlockp == NULL) ++ error = pthread_rwlock_init(rwlockp, NULL); ++ sgx_spin_unlock(&static_init_lock); ++ if (error != 0) ++ return (EINVAL); ++ } ++ ++ return sgx_thread_rwlock_tryrdlock(*rwlockp); ++} ++ ++ ++int pthread_rwlock_wrlock(pthread_rwlock_t *rwlockp) ++{ ++ if (rwlockp == NULL) ++ return (EINVAL); ++ int error = 0; ++ ++ /* ++ * If the rwlock is statically initialized, perform the dynamic ++ * initialization. ++ */ ++ if (*rwlockp == NULL) { ++ sgx_spin_lock(&static_init_lock); ++ if (*rwlockp == NULL) ++ error = pthread_rwlock_init(rwlockp, NULL); ++ sgx_spin_unlock(&static_init_lock); ++ if (error != 0) ++ return (EINVAL); ++ } ++ ++ return sgx_thread_rwlock_wrlock(*rwlockp); ++} ++ ++ ++int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlockp) ++{ ++ if (rwlockp == NULL) ++ return (EINVAL); ++ int error = 0; ++ ++ /* ++ * If the rwlock is statically initialized, perform the dynamic ++ * initialization. ++ */ ++ if (*rwlockp == NULL) { ++ sgx_spin_lock(&static_init_lock); ++ if (*rwlockp == NULL) ++ error = pthread_rwlock_init(rwlockp, NULL); ++ sgx_spin_unlock(&static_init_lock); ++ if (error != 0) ++ return (EINVAL); ++ } ++ ++ return sgx_thread_rwlock_trywrlock(*rwlockp); ++} ++ ++int pthread_rwlock_unlock(pthread_rwlock_t *rwlockp) ++{ ++ if (rwlockp == NULL) ++ return (EINVAL); ++ ++ if (*rwlockp == NULL) ++ abort(); ++ ++ return sgx_thread_rwlock_unlock(*rwlockp); ++} ++ +diff --git a/sdk/switchless/sgx_uswitchless/Makefile b/sdk/switchless/sgx_uswitchless/Makefile +index a89cff71..b5bbd97e 100644 +--- a/sdk/switchless/sgx_uswitchless/Makefile ++++ b/sdk/switchless/sgx_uswitchless/Makefile +@@ -52,6 +52,7 @@ CPP_OBJS := $(CPP_SRCS:.cpp=.o) + ALL_OBJS := $(CPP_OBJS) $(C_OBJS) + + SL_CXXFLAGS := $(CXXFLAGS) ++SL_CXXFLAGS += -fPIC + SL_CXXFLAGS += -I$(COMMON_DIR)/inc \ + -I$(COMMON_DIR)/inc/internal \ + -I$(SL_DIR)/inc +diff --git a/sdk/tlibthread/Makefile b/sdk/tlibthread/Makefile +index 8fbc206d..1a69c4f6 100755 +--- a/sdk/tlibthread/Makefile ++++ b/sdk/tlibthread/Makefile +@@ -40,6 +40,7 @@ CPPFLAGS := -I$(COMMON_DIR)/inc/internal \ + -I$(LINUX_PSW_DIR) + + OBJ := sethread_mutex.o \ ++ sethread_rwlock.o \ + sethread_cond.o \ + sethread_utils.o + +diff --git a/sdk/tlibthread/sethread_internal.h b/sdk/tlibthread/sethread_internal.h +index a782a95a..d875ac28 100644 +--- a/sdk/tlibthread/sethread_internal.h ++++ b/sdk/tlibthread/sethread_internal.h +@@ -71,6 +71,37 @@ typedef struct _thread_data_t *pTD; + (head)->m_last = SGX_THREAD_T_NULL; \ + } while (0) + ++#define QUEUE_REMOVE(var, elm) do \ ++{ \ ++ sgx_thread_t tmpThread = (var)->m_first; \ ++ if ((var)->m_first == SGX_THREAD_T_NULL ) \ ++ { \ ++ break; \ ++ } \ ++ else if ((var)->m_first == (elm) ) \ ++ { \ ++ QUEUE_REMOVE_HEAD((var)); \ ++ } \ ++ else \ ++ { \ ++ while ( ((pTD)tmpThread)->m_next != NULL ) \ ++ { \ ++ if ( ((pTD)tmpThread)->m_next == (pTD)(elm) ) \ ++ { \ ++ ((pTD)tmpThread)->m_next = (((pTD)tmpThread)->m_next)->m_next; \ ++ ((pTD)(elm))->m_next = NULL; \ ++ if ( (var)->m_last == (sgx_thread_t)(elm) ) \ ++ { \ ++ (var)->m_last = (sgx_thread_t)tmpThread; \ ++ } \ ++ break; \ ++ } \ ++ tmpThread = (sgx_thread_t)((pTD)tmpThread)->m_next; \ ++ } \ ++ } \ ++} while(0) ++ ++ + #define QUEUE_COUNT_ALL(var, head, total) do { \ + QUEUE_FOREACH(var, head) \ + (total)++; \ +diff --git a/sdk/tlibthread/sethread_mutex.cpp b/sdk/tlibthread/sethread_mutex.cpp +index cc28cd13..38cef7c0 100644 +--- a/sdk/tlibthread/sethread_mutex.cpp ++++ b/sdk/tlibthread/sethread_mutex.cpp +@@ -225,3 +225,4 @@ int sgx_thread_mutex_unlock(sgx_thread_mutex_t *mutex) + + return 0; + } ++ +diff --git a/sdk/tlibthread/sethread_rwlock.cpp b/sdk/tlibthread/sethread_rwlock.cpp +new file mode 100644 +index 00000000..fc440e2f +--- /dev/null ++++ b/sdk/tlibthread/sethread_rwlock.cpp +@@ -0,0 +1,387 @@ ++/* ++ * Copyright (C) 2011-2020 Intel Corporation. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Intel Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ */ ++ ++ ++#include ++#include ++#include ++ ++#include "util.h" ++#include "sethread_internal.h" ++ ++/* sgx_thread_rwlock_init: ++ * initialize a reader/writer lock ++ */ ++int sgx_thread_rwlock_init(sgx_thread_rwlock_t *rwlock, const sgx_thread_rwlockattr_t *unused) ++{ ++ UNUSED(unused); ++ CHECK_PARAMETER(rwlock); ++ ++ rwlock->m_reader_count = 0; ++ rwlock->m_writers_waiting = 0; ++ rwlock->m_owner = SGX_THREAD_T_NULL; ++ rwlock->m_lock = SGX_SPINLOCK_INITIALIZER; ++ ++ QUEUE_INIT(&rwlock->m_reader_queue); ++ QUEUE_INIT(&rwlock->m_writer_queue); ++ ++ return 0; ++} ++ ++ ++/* sgx_thread_rwlock_destroy: ++ * destroy a reader/writer lock ++ * - this will fail if any threads are holding a lock or are ++ * waiting for the lock ++ */ ++int SGXAPI sgx_thread_rwlock_destroy(sgx_thread_rwlock_t *rwlock) ++{ ++ CHECK_PARAMETER(rwlock); ++ ++ SPIN_LOCK(&rwlock->m_lock); ++ if ( (rwlock->m_owner != SGX_THREAD_T_NULL ) ++ || (rwlock->m_reader_count != 0 ) ++ || (rwlock->m_writers_waiting != 0) ++ || (QUEUE_FIRST(&rwlock->m_reader_queue) != SGX_THREAD_T_NULL) ++ || (QUEUE_FIRST(&rwlock->m_writer_queue) != SGX_THREAD_T_NULL)) { ++ SPIN_UNLOCK(&rwlock->m_lock); ++ return EBUSY; ++ } ++ ++ SPIN_UNLOCK(&rwlock->m_lock); ++ ++ return 0; ++} ++ ++/* sgx_thread_rwlock_rdlock: ++ * acquire a reader lock ++ * - should not be called if the thread is already holding the writer lock ++ */ ++int sgx_thread_rwlock_rdlock(sgx_thread_rwlock_t *rwlock) ++{ ++ CHECK_PARAMETER(rwlock); ++ ++ sgx_thread_t self = (sgx_thread_t)get_thread_data(); ++ ++ SPIN_LOCK(&rwlock->m_lock); ++ ++ //if no writers own the lock, then read lock is allowed ++ if (rwlock->m_owner == SGX_THREAD_T_NULL) ++ { ++ ++ //increase the reader count to show that a new thread has the reader lock ++ rwlock->m_reader_count++; ++ ++ SPIN_UNLOCK(&rwlock->m_lock); ++ return 0; ++ } ++ else ++ { ++ //still holding the spinlock ++ if ( rwlock->m_owner == self ) ++ { ++ SPIN_UNLOCK(&rwlock->m_lock); ++ return EDEADLK; ++ } ++ ++ //insert this thread into the queue ++ QUEUE_INSERT_TAIL(&rwlock->m_reader_queue, self); ++ ++ while (1) ++ { ++ int err = 0; ++ SPIN_UNLOCK(&rwlock->m_lock); ++ ++ //make an OCall to wait for the lock ++ sgx_thread_wait_untrusted_event_ocall(&err, TD2TCS(self)); ++ ++ SPIN_LOCK(&rwlock->m_lock); ++ ++ //if no writers own the lock, then read lock is allowed ++ if (rwlock->m_owner == SGX_THREAD_T_NULL) ++ { ++ //increase the reader count to show that this thread has the reader lock ++ rwlock->m_reader_count++; ++ ++ //remove this thread from the reader queue - if this thread was queued ++ QUEUE_REMOVE(&rwlock->m_reader_queue, self); ++ ++ SPIN_UNLOCK(&rwlock->m_lock); ++ return 0; ++ } ++ } ++ } ++ /* NOTREACHED */ ++} ++ ++/* sgx_thread_rwlock_tryrdlock: ++ * try to acquire a reader lock ++ * - return ++ * 0 if the lock is acquired ++ * EBUSY if the lock is busy ++ */ ++int sgx_thread_rwlock_tryrdlock(sgx_thread_rwlock_t *rwlock) ++{ ++ CHECK_PARAMETER(rwlock); ++ ++ SPIN_LOCK(&rwlock->m_lock); ++ ++ //if no writers own the lock, then read lock is allowed ++ if (rwlock->m_owner == SGX_THREAD_T_NULL) ++ { ++ ++ //increase the reader count to show that a new thread has the reader lock ++ rwlock->m_reader_count++; ++ ++ SPIN_UNLOCK(&rwlock->m_lock); ++ return 0; ++ } ++ else ++ { ++ SPIN_UNLOCK(&rwlock->m_lock); ++ return EBUSY; ++ } ++ /* NOTREACHED */ ++} ++ ++/* sgx_thread_rwlock_wrlock: ++ * acquire a writer lock ++ * - should not be called if the thread is already holding the writer lock ++ */ ++int sgx_thread_rwlock_wrlock(sgx_thread_rwlock_t *rwlock) ++{ ++ CHECK_PARAMETER(rwlock); ++ ++ sgx_thread_t self = (sgx_thread_t)get_thread_data(); ++ ++ SPIN_LOCK(&rwlock->m_lock); ++ ++ //if no writers own the lock and there are no readers ++ if ((rwlock->m_owner == SGX_THREAD_T_NULL) ++ && (rwlock->m_reader_count == 0)) ++ { ++ //take the writer lock by inserting our thread ID ++ rwlock->m_owner = self; ++ ++ SPIN_UNLOCK(&rwlock->m_lock); ++ return 0; ++ } ++ else ++ { ++ //still holding the spinlock ++ if ( rwlock->m_owner == self ) ++ { ++ //try to acquire writer lock when we hold it is a deadlock ++ SPIN_UNLOCK(&rwlock->m_lock); ++ return EDEADLK; ++ } ++ //insert this thread into the writer queue ++ QUEUE_INSERT_TAIL(&rwlock->m_writer_queue, self); ++ ++ while (1) ++ { ++ int err = 0; ++ SPIN_UNLOCK(&rwlock->m_lock); ++ ++ //make an OCall to wait for the lock ++ sgx_thread_wait_untrusted_event_ocall(&err, TD2TCS(self)); ++ ++ SPIN_LOCK(&rwlock->m_lock); ++ ++ //if no writers own the lock and there are no readers ++ if ((rwlock->m_owner == SGX_THREAD_T_NULL) ++ && (rwlock->m_reader_count == 0)) ++ { ++ //take the writer lock by inserting our thread ID ++ rwlock->m_owner = self; ++ ++ //remove this thread from the reader queue - if this thread was queued ++ QUEUE_REMOVE(&rwlock->m_writer_queue, self); ++ ++ SPIN_UNLOCK(&rwlock->m_lock); ++ return 0; ++ } ++ } ++ } ++ /* NOTREACHED */ ++} ++ ++/* sgx_thread_rwlock_trywrlock: ++ * try to acquire a writer lock ++ * - return ++ * 0 if the lock is acquired ++ * EBUSY if the lock is busy ++ */ ++int sgx_thread_rwlock_trywrlock(sgx_thread_rwlock_t *rwlock) ++{ ++ CHECK_PARAMETER(rwlock); ++ ++ sgx_thread_t self = (sgx_thread_t)get_thread_data(); ++ ++ SPIN_LOCK(&rwlock->m_lock); ++ ++ //if no writers own the lock and there are no readers ++ if ((rwlock->m_owner == SGX_THREAD_T_NULL) ++ && (rwlock->m_reader_count == 0)) ++ { ++ //take the writer lock by inserting our thread ID ++ rwlock->m_owner = self; ++ ++ SPIN_UNLOCK(&rwlock->m_lock); ++ return 0; ++ } ++ else ++ { ++ SPIN_UNLOCK(&rwlock->m_lock); ++ return EBUSY; ++ } ++ /* NOTREACHED */ ++} ++ ++/* sgx_thread_rwlock_rdunlock: ++ * remove a reader lock. If there are no more readers and there is a ++ * writer waiting, then wake it up. ++ */ ++int sgx_thread_rwlock_rdunlock(sgx_thread_rwlock_t *rwlock) ++{ ++ int ret = 0; ++ ++ SPIN_LOCK(&rwlock->m_lock); ++ ++ /* if the lock is not held by anyone */ ++ if (rwlock->m_reader_count == 0) { ++ SPIN_UNLOCK(&rwlock->m_lock); ++ return EPERM; ++ } ++ ++ rwlock->m_reader_count--; ++ ++ /* if the lock is now not held by anyone */ ++ if (rwlock->m_reader_count == 0) ++ { ++ /* If there is a writer waiting, then ++ * the thread should be awakened up by the caller. ++ */ ++ sgx_thread_t waiter = QUEUE_FIRST(&rwlock->m_writer_queue); ++ ++ SPIN_UNLOCK(&rwlock->m_lock); ++ ++ if (waiter != SGX_THREAD_T_NULL) /* wake the waiter up*/ ++ sgx_thread_set_untrusted_event_ocall(&ret, TD2TCS(waiter)); ++ } ++ else ++ { ++ SPIN_UNLOCK(&rwlock->m_lock); ++ } ++ return ret; ++} ++ ++/* sgx_thread_rwlock_wrunlock: ++ * remove the writer lock. If there are reader threads waiting ++ * then wake them, otherwise, if there are writer thread waiting, ++ * then wake them. ++ */ ++int sgx_thread_rwlock_wrunlock(sgx_thread_rwlock_t *rwlock) ++{ ++ int ret = 0; ++ ++ sgx_thread_t self = (sgx_thread_t)get_thread_data(); ++ ++ SPIN_LOCK(&rwlock->m_lock); ++ ++ /* if the lock is not held by this thread */ ++ if (rwlock->m_owner != self ) { ++ SPIN_UNLOCK(&rwlock->m_lock); ++ return EPERM; ++ } ++ ++ rwlock->m_owner = SGX_THREAD_T_NULL; ++ ++ /* if there are reader locks waiting, then wake them first */ ++ sgx_thread_t waiter = QUEUE_FIRST(&rwlock->m_reader_queue); ++ if (waiter != SGX_THREAD_T_NULL) ++ { ++ size_t iCount = 0; ++ QUEUE_COUNT_ALL(waiter, &rwlock->m_reader_queue, iCount); ++ ++ const void** ppWaiters = (const void**)malloc(iCount * sizeof(const void*)); ++ if (!ppWaiters) ++ { ++ SPIN_UNLOCK(&rwlock->m_lock); ++ return ENOMEM; ++ } ++ const void** ppWaitersTemp = ppWaiters; ++ QUEUE_FOREACH(waiter, &rwlock->m_reader_queue) ++ { ++ *ppWaitersTemp++ = TD2TCS(waiter); ++ } ++ SPIN_UNLOCK(&rwlock->m_lock); ++ ++ /* wake all the queued threads up*/ ++ sgx_thread_set_multiple_untrusted_events_ocall(&ret, ppWaiters, iCount); ++ free(ppWaiters); ++ } ++ else ++ { ++ /* If we didn't wake any readers, then look for a waiting writer to wake */ ++ waiter = QUEUE_FIRST(&rwlock->m_writer_queue); ++ SPIN_UNLOCK(&rwlock->m_lock); ++ if (waiter != SGX_THREAD_T_NULL) ++ { ++ /* wake the waiter up*/ ++ sgx_thread_set_untrusted_event_ocall(&ret, TD2TCS(waiter)); ++ } ++ } ++ ++ return ret; ++} ++ ++/* sgx_thread_rwlock_unlock: ++ * if the thread holds a writer lock, then release it; ++ * otherwise release a reader lock. ++ */ ++int sgx_thread_rwlock_unlock(sgx_thread_rwlock_t *rwlock) ++{ ++ sgx_thread_t self = (sgx_thread_t)get_thread_data(); ++ ++ //no need to hold a spinlock here - if it is our write lock, then nobody will change it ++ if (rwlock->m_owner == self) ++ { ++ /* if the lock is held by this thread, then we are releasing a writer lock */ ++ return sgx_thread_rwlock_wrunlock(rwlock); ++ } ++ else ++ { ++ /* otherwise, we are releasing a reader lock */ ++ return sgx_thread_rwlock_rdunlock(rwlock); ++ } ++} ++ +diff --git a/sdk/tmm_rsrv/sgx_rsrv_mem.cpp b/sdk/tmm_rsrv/sgx_rsrv_mem.cpp +index 0d865137..45c5e77e 100644 +--- a/sdk/tmm_rsrv/sgx_rsrv_mem.cpp ++++ b/sdk/tmm_rsrv/sgx_rsrv_mem.cpp +@@ -81,13 +81,24 @@ static int init_rsrv_mem_vrd() + return 0; + } + ++sgx_status_t sgx_get_rsrv_mem_info(void ** start_addr, size_t * max_size) ++{ ++ if(start_addr == NULL && max_size == NULL) ++ { ++ return SGX_ERROR_INVALID_PARAMETER; ++ } ++ if(start_addr != NULL) ++ { ++ *start_addr = rsrv_mem_base; ++ } ++ if (max_size != NULL) ++ { ++ *max_size = rsrv_mem_size; ++ } ++ return SGX_SUCCESS; ++} + +-/* +- * sgx_alloc_rsrv_mem +- * Reserves a range of EPC memory from the reserved memory area. +- * @return Pointer to the new area on success, otherwise NULL. +- */ +-void * sgx_alloc_rsrv_mem(size_t length) ++void * sgx_alloc_rsrv_mem_ex(void *desired_addr, size_t length) + { + static volatile bool g_first_alloc = true; + vrd_t * rsrv_vrd = NULL; +@@ -99,12 +110,22 @@ void * sgx_alloc_rsrv_mem(size_t length) + return NULL; + } + // Sanity checks +- if ((length == 0) || !IS_PAGE_ALIGNED(length) || length > rsrv_mem_size || +- rsrv_mem_committed > (SIZE_MAX - length)) ++ if(!IS_PAGE_ALIGNED(desired_addr) || length == 0 || !IS_PAGE_ALIGNED(length) || length > rsrv_mem_size) + { + errno = EINVAL; + return NULL; + } ++ if(desired_addr != NULL) ++ { ++ size_t end = (size_t)desired_addr + length - 1; ++ if((size_t)desired_addr > end || length > end || end > (size_t)rsrv_mem_base + rsrv_mem_size - 1 || ++ (size_t)desired_addr < (size_t)rsrv_mem_base) ++ { ++ errno = EINVAL; ++ return NULL; ++ } ++ } ++ + sgx_thread_mutex_lock(&g_vrdl_mutex); + if(unlikely(g_first_alloc)) + { +@@ -119,7 +140,7 @@ void * sgx_alloc_rsrv_mem(size_t length) + } + + // Allocate memory from reserved memory region +- rsrv_vrd = insert_vrd((size_t)0, length, ++ rsrv_vrd = insert_vrd((size_t)desired_addr, length, + (!EDMM_supported && g_global_data.rsrv_executable ) ? SGX_PAGE_EXECUTE_READWRITE : SGX_PAGE_READWRITE, + VRD_STATE_COMMITTED, + VRD_PT_REG, &sgx_ret); +@@ -149,7 +170,7 @@ void * sgx_alloc_rsrv_mem(size_t length) + size_t size = 0; + size_t offset = (rsrv_vrd->start_addr + length) - ((size_t)rsrv_mem_base + rsrv_mem_committed); + rsrv_mem_committed += ROUND_TO(offset, SE_PAGE_SIZE); +- if(EDMM_supported && rsrv_mem_committed > rsrv_mem_min_size) ++ if(EDMM_supported && rsrv_vrd->start_addr + length > (size_t)rsrv_mem_base + rsrv_mem_min_size) + { + // Need to apply pages + if(prev_rsrv_mem_committed > rsrv_mem_min_size) +@@ -184,6 +205,16 @@ void * sgx_alloc_rsrv_mem(size_t length) + return (void *)start_addr; + } + ++/* ++ * sgx_alloc_rsrv_mem ++ * Reserves a range of EPC memory from the reserved memory area. ++ * @return Pointer to the new area on success, otherwise NULL. ++ */ ++void * sgx_alloc_rsrv_mem(size_t length) ++{ ++ return sgx_alloc_rsrv_mem_ex(NULL, length); ++} ++ + /* + * sgx_free_rsrv_mem + * Frees a range of EPC memory from the reserved memory area. +@@ -270,10 +301,13 @@ static sgx_status_t tprotect_internal(size_t start, size_t size, si_flags_t perm + return SGX_ERROR_UNEXPECTED; + } + ++ // EMODPE/EACCEPT requires OS level R permission for the page. Therefore, ++ // If target permission is NONE, we should change the OS level permission to NONE after EACCEPT ++ // If original permission is NONE, we should change the OS level permission before EMODPE + if(pr_needed || pe_needed) + { +- // If either EMODPE or EMODPR is needed, mprotect() is required to be called to change permission +- ret = change_permissions_ocall(start, size, perms); ++ // Ocall to EMODPR if target perm is not RWX and mprotect() if target perm is not NONE ++ ret = change_permissions_ocall(start, size, perms, EDMM_MODPR); + if (ret != SGX_SUCCESS) + abort(); + } +@@ -290,6 +324,13 @@ static sgx_status_t tprotect_internal(size_t start, size_t size, si_flags_t perm + if(accept_modified_pages((void *)start, size / SE_PAGE_SIZE, sf)) + abort(); + } ++ if( pr_needed && perms == SI_FLAG_NONE ) ++ { ++ // If the target permission is NONE, ocall to mprotect() to change the OS permission ++ ret = change_permissions_ocall(start, size, perms, EDMM_MPROTECT); ++ if (ret != SGX_SUCCESS) ++ abort(); ++ } + return ret; + } + +@@ -312,19 +353,23 @@ sgx_status_t sgx_tprotect_rsrv_mem(void *addr, size_t len, int prot) + if(!sgx_is_within_enclave(addr, len)) + return SGX_ERROR_INVALID_PARAMETER; + ++ if(g_sdk_version < SDK_VERSION_2_3) ++ { ++ // NONE support requires uRTS changes. Therefore, if the enclave is built with update SDK and loaded with old uRTS, ++ // we return an error code indicating that uRTS should be updated. ++ return SGX_ERROR_UPDATE_NEEDED; ++ } + if(0 == rsrv_mem_size || (size_t)addr < (size_t)rsrv_mem_base || + !IS_PAGE_ALIGNED(addr) || len < SE_PAGE_SIZE || !IS_PAGE_ALIGNED(len)) + { + return SGX_ERROR_INVALID_PARAMETER; + } +- if(prot == SGX_PROT_NONE || +- (!(prot & SGX_PROT_READ) && (prot & (SGX_PROT_WRITE | SGX_PROT_EXEC))) || +- (prot & ~(SGX_PROT_READ | SGX_PROT_WRITE | SGX_PROT_EXEC))) ++ if(((!(prot & SGX_PROT_READ) && (prot & (SGX_PROT_WRITE | SGX_PROT_EXEC))) || ++ (prot & ~(SGX_PROT_READ | SGX_PROT_WRITE | SGX_PROT_EXEC)))) + { + return SGX_ERROR_INVALID_PARAMETER; + } +- +- uint64_t perms = 0; ++ uint64_t perms = SI_FLAG_NONE; + if((prot & SGX_PROT_EXEC) == SGX_PROT_EXEC) + { + perms |= SI_FLAG_X; +diff --git a/sdk/trts/trts_ecall.cpp b/sdk/trts/trts_ecall.cpp +index d0791329..36b75e6c 100644 +--- a/sdk/trts/trts_ecall.cpp ++++ b/sdk/trts/trts_ecall.cpp +@@ -570,7 +570,7 @@ extern "C" sgx_status_t trts_mprotect(size_t start, size_t size, uint64_t perms) + return SGX_ERROR_INVALID_PARAMETER; + if (g_sdk_version == SDK_VERSION_2_0) + { +- ret = change_permissions_ocall(start, size, perms); ++ ret = change_permissions_ocall(start, size, perms, EDMM_MODPR); + if (ret != SGX_SUCCESS) + return ret; + } +diff --git a/sdk/trts/trts_emodpr.cpp b/sdk/trts/trts_emodpr.cpp +index 6c979040..7cab0286 100644 +--- a/sdk/trts/trts_emodpr.cpp ++++ b/sdk/trts/trts_emodpr.cpp +@@ -53,12 +53,13 @@ typedef struct ms_change_permissions_ocall_t { + uint64_t ms_epcm_perms; + } ms_change_permissions_ocall_t; + +-sgx_status_t SGXAPI change_permissions_ocall(size_t addr, size_t size, uint64_t epcm_perms) ++sgx_status_t SGXAPI change_permissions_ocall(size_t addr, size_t size, uint64_t epcm_perms, const int proc) + { + #ifdef SE_SIM + (void)addr; + (void)size; + (void)epcm_perms; ++ (void)proc; + return SGX_SUCCESS; + #else + sgx_status_t status = SGX_SUCCESS; +@@ -69,7 +70,7 @@ sgx_status_t SGXAPI change_permissions_ocall(size_t addr, size_t size, uint64_t + ms->ms_addr = addr; + ms->ms_size = size; + ms->ms_epcm_perms = epcm_perms; +- status = sgx_ocall(EDMM_MODPR, ms); ++ status = sgx_ocall(proc, ms); + + + sgx_ocfree(); +diff --git a/sdk/trts/trts_emodpr.h b/sdk/trts/trts_emodpr.h +index 4d674029..abe0382a 100644 +--- a/sdk/trts/trts_emodpr.h ++++ b/sdk/trts/trts_emodpr.h +@@ -47,7 +47,7 @@ + extern "C" { + #endif + +-sgx_status_t SGXAPI change_permissions_ocall(size_t addr, size_t size, uint64_t epcm_perms); ++sgx_status_t SGXAPI change_permissions_ocall(size_t addr, size_t size, uint64_t epcm_perms, const int proc); + + sgx_status_t change_protection(void *enclave_base); + +-- +2.27.0 + diff --git a/linux-sgx.spec b/linux-sgx.spec index ce44354..133c2f9 100644 --- a/linux-sgx.spec +++ b/linux-sgx.spec @@ -1,6 +1,6 @@ Name: linux-sgx Version: 2.11.100 -Release: 13 +Release: 14 Summary: Intel(R) Software Guard Extensions for Linux* OS ExclusiveArch: x86_64 License: BSD-3-Clause @@ -24,6 +24,7 @@ Patch4: backport-CVE-2022-0778_test.patch Patch5: backport-CVE-2022-1292.patch Patch6: backport-CVE-2022-2068-Fix-file-operations-in-c_rehash.patch Patch7: backport-CVE-2022-2097-Fix-AES-OCB-encrypt-decrypt-for-x86-AES-NI.patch +Patch8: backport-linux-2.11-Open-Source-Gold-Release.patch BuildRequires: gcc-c++ protobuf-devel libtool ocaml-ocamlbuild openssl-devel cmake python curl-devel createrepo_c git @@ -939,6 +940,9 @@ fi %files -n sgx-ra-service -f %{TOOLS_INSTALLER_RPM_DIR}/sgx-ra-service/build/list-sgx-ra-service %changelog +* Thu Dec 28 2023 fandehui - 2.11.100-14 +- Linux 2.11 Open Source Gold Release + * Sat Sep 24 2022 wangyu - 2.11.100-13 - The postun script should distinguish uninstall and upgrade scenarios -- Gitee