Compare commits

..

59 Commits
0.30.1 ... main

Author SHA1 Message Date
531f9a1241 Merge pull request 'Update README' (#1) from noormohammedb/detee-occlum:fix_readme into main
Some checks failed
SGX Hardware Mode Test / Fish_test ([self-hosted SGX2-HW EDMM]) (push) Has been cancelled
SGX Hardware Mode Test / Fish_test ([self-hosted SGX2-HW]) (push) Has been cancelled
SGX Hardware Mode Test / Xgboost_test ([self-hosted SGX2-HW EDMM]) (push) Has been cancelled
SGX Hardware Mode Test / Python_musl_support_test ([self-hosted SGX2-HW]) (push) Has been cancelled
SGX Hardware Mode Test / Openvino_test ([self-hosted SGX2-HW EDMM]) (push) Has been cancelled
SGX Hardware Mode Test / Openvino_test ([self-hosted SGX2-HW]) (push) Has been cancelled
SGX Hardware Mode Test / Grpc_test ([self-hosted SGX2-HW EDMM]) (push) Has been cancelled
SGX Hardware Mode Test / Grpc_test ([self-hosted SGX2-HW]) (push) Has been cancelled
SGX Hardware Mode Test / Init_RA_grpc ([self-hosted SGX2-HW EDMM]) (push) Has been cancelled
SGX Hardware Mode Test / Gvisor_test ([self-hosted SGX2-HW EDMM]) (push) Has been cancelled
SGX Hardware Mode Test / Gvisor_test ([self-hosted SGX2-HW]) (push) Has been cancelled
SGX Hardware Mode Test / Test_deb_deploy ([self-hosted SGX2-HW]) (push) Has been cancelled
SGX Hardware Mode Test / Tensorflow_serving_test ([self-hosted SGX2-HW EDMM]) (push) Has been cancelled
SGX Hardware Mode Test / Tensorflow_serving_test ([self-hosted SGX2-HW]) (push) Has been cancelled
SGX Hardware Mode Test / Remote_attestation_test ([self-hosted SGX2-HW EDMM]) (push) Has been cancelled
SGX Hardware Mode Test / Init_RA_grpc ([self-hosted SGX2-HW]) (push) Has been cancelled
SGX Hardware Mode Test / Init_RA_AECS ([self-hosted SGX2-HW EDMM]) (push) Has been cancelled
SGX Hardware Mode Test / Init_RA_AECS ([self-hosted SGX2-HW]) (push) Has been cancelled
SGX Hardware Mode Test / MySQL_test ([self-hosted SGX2-HW EDMM]) (push) Has been cancelled
SGX Hardware Mode Test / MySQL_test ([self-hosted SGX2-HW]) (push) Has been cancelled
SGX Hardware Mode Test / Stress_test_with_musl ([self-hosted SGX2-HW EDMM]) (push) Has been cancelled
SGX Hardware Mode Test / Stress_test_with_musl ([self-hosted SGX2-HW]) (push) Has been cancelled
SGX Hardware Mode Test / Stress_test_with_glibc ([self-hosted SGX2-HW EDMM]) (push) Has been cancelled
SGX Hardware Mode Test / Stress_test_with_glibc ([self-hosted SGX2-HW]) (push) Has been cancelled
Benchmarks Test / Sysbench_Test ([self-hosted SGX2-HW benchmark]) (push) Has been cancelled
Benchmarks Test / Iperf3_Test ([self-hosted SGX2-HW benchmark]) (push) Has been cancelled
Benchmarks Test for dev branch / Sysbench_Test ([self-hosted SGX2-HW benchmark]) (push) Has been cancelled
Benchmarks Test for dev branch / Iperf3_Test ([self-hosted SGX2-HW benchmark]) (push) Has been cancelled
Benchmarks Test for dev branch / SEFS_FIO_Test ([self-hosted SGX2-HW benchmark]) (push) Has been cancelled
Benchmarks Test for dev branch / AsyncSFS_FIO_Test ([self-hosted SGX2-HW benchmark]) (push) Has been cancelled
fixed occlum_utils library installation scripts
correct repository clone URL

Reviewed-on: SGX/occlum#1
Reviewed-by: Valentyn Faychuk <valy@detee.ltd>
2024-12-03 10:09:37 +00:00
cd594d293d Update README
fixed occlum_utils library installation scripts
correct repository clone URL
2024-12-02 14:36:13 +05:30
fb93be46a2 added utils_lib 2024-10-27 15:51:53 +02:00
98550a1ebc
sealing key generation 2024-10-27 15:51:53 +02:00
ClawSeven
be4de47940 [Demos] Fix broken mnist source in paddlepaddle demo 2024-06-13 12:00:13 +08:00
Qi Zheng
814b573304 [demos] Specify protoc-gen-go-grpc version for go pingpong demo 2024-06-13 12:00:13 +08:00
Qi Zheng
ea6e33e6f1 [demos] Fix flask demo run failure 2024-06-13 12:00:13 +08:00
Qi Zheng
8f9e8d52cb [demos] Fix golang webserver build error 2024-06-13 12:00:13 +08:00
Hui, Chunyang
0c9a44fc60 Add kernel_heap_monitor as the default feature 2024-05-29 14:03:40 +08:00
Qi Zheng
473eec584e Update cargo lock 2024-03-19 10:19:50 +08:00
LI Qing
f9839299b2 Refine the implementation of NiceValue 2024-03-18 15:26:45 +08:00
LI Qing
db3a31d42e Fix the chown syscall with negative id 2024-03-15 14:44:26 +08:00
Hui, Chunyang
6eaad69941 Bump version to 0.30.1 2024-03-14 16:23:34 +08:00
ClawSeven
fb013a2bcd [time] Fix wrong SGX_CPUID leaf 2024-03-14 16:23:34 +08:00
Qi Zheng
faad595225 [deps] Update rust sgx sdk 2024-03-14 16:23:34 +08:00
Hui, Chunyang
2198d9e395 Add "kernel_heap_monitor" feature 2024-03-14 16:23:34 +08:00
ClawSeven
e48cc13f79 [time] Adapt vdso module to SGX1 platform 2024-03-14 16:23:34 +08:00
ClawSeven
b2f721d1bb [crates] Implement vdso for time precision 2024-03-14 16:23:34 +08:00
ClawSeven
9404da7cf8 [crates] Seperate error module into errno crate 2024-03-14 16:23:34 +08:00
Qi Zheng
f9b53dc410 [toolchains] Support set glibc branch for Occlum glibc build 2024-03-14 16:23:34 +08:00
Hui, Chunyang
d95199ace5 Fix feature configuration for make test 2024-03-14 16:23:34 +08:00
Hui, Chunyang
0b93c187f4 Remove reuse actions for release image 2024-03-14 16:23:34 +08:00
Hui, Chunyang
f46dbbad11 Refine CI actions to reuse old image 2024-03-14 16:23:34 +08:00
Hui, Chunyang
4ce27ae5c9 Fix AECS client version mismatch 2024-03-14 16:23:34 +08:00
Hui, Chunyang
aae9b6d940 Use special exception register and Replace sgx_tprotect_rsrv_mem with low leve API 2024-03-14 16:23:34 +08:00
Hui, Chunyang
ca4bcbf8fe Use low level API to replace sgx_mm_(commit/commit_data/modify_permissions)
Reduce the EMA management overhead and the global lock of emm module of
Intel SGX SDK
2024-03-14 16:23:34 +08:00
ClawSeven
2b1a9b960a [libos] Fix rt_sigaction wrong inargument 2024-03-14 16:23:34 +08:00
ClawSeven
e9f2c09012 [libos] Fix readlinkat with non-positive bufsize 2024-03-14 16:23:34 +08:00
ClawSeven
c2296c13d2 [libos] Fix sendfile with non-writable file 2024-03-14 16:23:34 +08:00
Hui, Chunyang
ee77ee618b Fix permission violation check for mmap and mprotect 2024-03-14 16:23:34 +08:00
Hui, Chunyang
e637ddbdfe Fix mmap file flush exceeding the file length 2024-03-14 16:23:34 +08:00
Hui, Chunyang
bf8d6a65f0 Add AMX and EDMM as feature in Occlum.json 2024-03-14 16:23:34 +08:00
Hui, Chunyang
836513687a Refine log for #UD exception and file open 2024-03-14 16:23:34 +08:00
Hui, Chunyang
ad6cab55f9 Refine log for VM module 2024-03-14 16:23:34 +08:00
ClawSeven
c465e7782a [libos] Fix clock_getres return successfully with wrong clock id 2024-03-14 16:23:34 +08:00
Qi Zheng
41e62ae982 [demos] Update Linux LTP test demo 2024-03-14 16:23:34 +08:00
Qi Zheng
b746fea82b [libos] Add iov buffer check for readv and writev
Signed-off-by: Qi Zheng <huaiqing.zq@antgroup.com>
2024-03-14 16:23:34 +08:00
Qi Zheng
dc060c57b4 Update unsupported syscall table 2024-03-14 16:23:34 +08:00
Qi Zheng
ce2cbccdb8 [readthedocs] Update occlum commands chapter 2024-03-14 16:23:34 +08:00
Qi Zheng
beeffcced7 [libos] faccessat only accepts three parameters 2024-03-14 16:23:34 +08:00
ClawSeven
47ac767886 [libos] Lower sigsuspend error log level 2024-03-14 16:23:34 +08:00
Qi Zheng
bc7096815d [readthedocs] Description for Occlum log config option 2024-03-14 16:23:34 +08:00
Qi Zheng
a7317b0aa9 [libos] Add disable_log cfg option 2024-03-14 16:23:34 +08:00
ClawSeven
065c367b37 [libos] Fix deadlock in signal implementions 2024-03-14 16:23:34 +08:00
ClawSeven
2a801e5fec [test] Implement ut for sigsuspend 2024-03-14 16:23:34 +08:00
ClawSeven
1147e6956f [libos] Implement the rt_sigsuspend syscall 2024-03-14 16:23:34 +08:00
ClawSeven
382bc812f1 [test] Implement unit test for pselect 2024-03-14 16:23:34 +08:00
ClawSeven
56528f67da [libos] Implement Pselect syscall with sigset 2024-03-14 16:23:34 +08:00
Hui, Chunyang
4d2ba8ca01 Refine error level log 2024-03-14 16:23:34 +08:00
Shaowei Song
69a8d078a5 [ci] Enable features on hw ci for EDMM 2024-03-14 16:23:34 +08:00
Shaowei Song
76edc08233 [config] Add "feature" field to Occlum.json 2024-03-14 16:23:34 +08:00
Shaowei Song
5efc54cb81 [vm] Refine shared chunk expansion 2024-03-14 16:23:34 +08:00
ClawSeven
6c8c8fc871 Reduce error log by downgrading unnecessary error! to warn! 2024-03-14 16:23:34 +08:00
Qi Zheng
367fa9c4ce [demos] CUDA torch python packages are not required for CPU inference 2024-03-14 16:23:34 +08:00
ClawSeven
5043797bc8 Change netty ut java version to jdk8 2024-03-14 16:23:34 +08:00
Qi Zheng
37c56c8b81 [test] SIGSTKSZ is not constant in glibc>2.34 2024-03-14 16:23:34 +08:00
Qi Zheng
3fb86f96c4 [libos] Update cpuid leaf table 2024-03-14 16:23:34 +08:00
Qi Zheng
cb1ee85605 [toolchain] Update grpc_ratls toolchain with patching way
Signed-off-by: Qi Zheng <huaiqing.zq@antgroup.com>
2024-03-14 16:23:34 +08:00
LI Qing
a82cfb87f0 Fix the issue about handling the AT_EMPTY_PATH flag 2024-03-14 16:23:34 +08:00
23 changed files with 213 additions and 113 deletions

@ -82,8 +82,7 @@ jobs:
run: docker exec ${{ github.job }} bash -c "cd /root/occlum/tools/toolchains/golang && ./build.sh go1.18.4_for_occlum && cd /root/occlum/demos/golang/go_sqlite/ && SGX_MODE=SIM ./run_go_sqlite_demo.sh" run: docker exec ${{ github.job }} bash -c "cd /root/occlum/tools/toolchains/golang && ./build.sh go1.18.4_for_occlum && cd /root/occlum/demos/golang/go_sqlite/ && SGX_MODE=SIM ./run_go_sqlite_demo.sh"
- name: Go Server set up and run - name: Go Server set up and run
run: docker exec ${{ github.job }} bash -c "cd /root/occlum/demos/golang/web_server && occlum-go mod init web_server && occlum-go get -u -v github.com/gin-gonic/gin; run: docker exec ${{ github.job }} bash -c "cd /root/occlum/demos/golang/web_server && ./build.sh;
occlum-go build -o web_server ./web_server.go;
SGX_MODE=SIM ./run_golang_on_occlum.sh" & SGX_MODE=SIM ./run_golang_on_occlum.sh" &
- name: Set up Golang grpc pingpong test - name: Set up Golang grpc pingpong test

@ -142,8 +142,7 @@ jobs:
- name: Go server set up and run - name: Go server set up and run
run: docker exec ${{ env.CONTAINER_NAME }} bash -c "export GO111MODULE=on; run: docker exec ${{ env.CONTAINER_NAME }} bash -c "export GO111MODULE=on;
cd /root/occlum/demos/golang/web_server && occlum-go mod init web_server && occlum-go get -u -v github.com/gin-gonic/gin; cd /root/occlum/demos/golang/web_server && ./build.sh;
occlum-go build -o web_server ./web_server.go;
./run_golang_on_occlum.sh" & ./run_golang_on_occlum.sh" &
- name: Set up Golang grpc pingpong test - name: Set up Golang grpc pingpong test

@ -54,9 +54,9 @@ fi
if ! type "protoc-gen-go-grpc" > /dev/null 2>&1; then if ! type "protoc-gen-go-grpc" > /dev/null 2>&1; then
if [[ $GOVERSION != 'go1.16.3' ]];then if [[ $GOVERSION != 'go1.16.3' ]];then
occlum-go get google.golang.org/grpc/cmd/protoc-gen-go-grpc occlum-go get google.golang.org/grpc/cmd/protoc-gen-go-grpc
occlum-go install google.golang.org/grpc/cmd/protoc-gen-go-grpc occlum-go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.3.0
else else
occlum-go get google.golang.org/grpc/cmd/protoc-gen-go-grpc occlum-go get google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.3.0
fi fi
fi fi

@ -19,10 +19,7 @@ occlum init
new_json="$(jq '.resource_limits.user_space_size = "1MB" | new_json="$(jq '.resource_limits.user_space_size = "1MB" |
.resource_limits.user_space_max_size = "800MB" | .resource_limits.user_space_max_size = "800MB" |
.resource_limits.kernel_space_heap_size="1MB" | .resource_limits.kernel_space_heap_size="1MB" |
.resource_limits.kernel_space_heap_max_size="40MB" | .resource_limits.kernel_space_heap_max_size="80MB" ' Occlum.json)" && \
.resource_limits.kernel_space_stack_size="1MB" |
.process.default_stack_size = "1MB" |
.process.default_heap_size = "20MB" ' Occlum.json)" && \
echo "${new_json}" > Occlum.json echo "${new_json}" > Occlum.json
# 2. Copy program into Occlum Workspace and build # 2. Copy program into Occlum Workspace and build

@ -19,10 +19,7 @@ occlum init
new_json="$(jq '.resource_limits.user_space_size = "1MB" | new_json="$(jq '.resource_limits.user_space_size = "1MB" |
.resource_limits.user_space_max_size = "800MB" | .resource_limits.user_space_max_size = "800MB" |
.resource_limits.kernel_space_heap_size="1MB" | .resource_limits.kernel_space_heap_size="1MB" |
.resource_limits.kernel_space_heap_max_size="40MB" | .resource_limits.kernel_space_heap_max_size="80MB" ' Occlum.json)" && \
.resource_limits.kernel_space_stack_size="1MB" |
.process.default_stack_size = "1MB" |
.process.default_heap_size = "20MB" ' Occlum.json)" && \
echo "${new_json}" > Occlum.json echo "${new_json}" > Occlum.json
# 2. Copy program into Occlum Workspace and build # 2. Copy program into Occlum Workspace and build

@ -2,24 +2,18 @@
This project demonstrates how Occlum enables [Golang](https://golang.org) programs running in SGX enclaves, the demo program is a HTTP web server based on a widely used web framework([Gin](https://gin-gonic.com)) for Go. This project demonstrates how Occlum enables [Golang](https://golang.org) programs running in SGX enclaves, the demo program is a HTTP web server based on a widely used web framework([Gin](https://gin-gonic.com)) for Go.
Step 1: Install Gin with `occlum-go`, it may take a few minutes Step 1: Install Gin and build Golang web server with `occlum-go`
``` ```
occlum-go mod init web_server && \ ./build.sh
occlum-go get -u -v github.com/gin-gonic/gin
``` ```
Step 2: Build the Golang web server using the Occlum Golang toolchain(i.e., `occlum-go`) Step 2: You can run the web server demo on Occlum via
```
occlum-go build -o web_server ./web_server.go
```
Step 3: You can run the web server demo on Occlum via
``` ```
./run_golang_on_occlum.sh ./run_golang_on_occlum.sh
``` ```
The HTTP web server should now start to listen on port 8090 and serve HTTP requests. The HTTP web server should now start to listen on port 8090 and serve HTTP requests.
Step 4: To check whether the HTTP server works, run Step 3: To check whether the HTTP server works, run
``` ```
curl http://127.0.0.1:8090/ping curl http://127.0.0.1:8090/ping
``` ```

@ -0,0 +1,10 @@
#!/bin/bash
set -e
rm -f go.mod
occlum-go mod init web_server
occlum-go mod tidy
occlum-go get -u -v github.com/gin-gonic/gin
occlum-go get -u -v golang.org/x/crypto@v0.23.0
occlum-go build -o web_server ./web_server.go

@ -21,19 +21,7 @@ sed -i "186 i \ elif sysstr == 'occlum':\n return True" $CORE_PY
sed -ie "37,64d" $IMAGE_PY sed -ie "37,64d" $IMAGE_PY
sed -i "37 i \try:\n import cv2\nexcept ImportError:\n cv2 = None" $IMAGE_PY sed -i "37 i \try:\n import cv2\nexcept ImportError:\n cv2 = None" $IMAGE_PY
# Download the dataset # Download the dataset
DATASET=$script_dir/mnist git clone https://github.com/fgnt/mnist.git
[ -d $DATASET ] && exit 0
TRAIN_IMAGE=train-images-idx3-ubyte.gz
TRAIN_LABEL=train-labels-idx1-ubyte.gz
TEST_IMAGE=t10k-images-idx3-ubyte.gz
TEST_LABEL=t10k-labels-idx1-ubyte.gz
URL=http://yann.lecun.com/exdb/mnist
mkdir $DATASET
wget $URL/$TRAIN_IMAGE -P $DATASET
wget $URL/$TRAIN_LABEL -P $DATASET
wget $URL/$TEST_IMAGE -P $DATASET
wget $URL/$TEST_LABEL -P $DATASET

@ -8,7 +8,7 @@ script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
# 2. Install python and dependencies to specified position # 2. Install python and dependencies to specified position
[ -f Miniconda3-latest-Linux-x86_64.sh ] || wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh [ -f Miniconda3-latest-Linux-x86_64.sh ] || wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
[ -d miniconda ] || bash ./Miniconda3-latest-Linux-x86_64.sh -b -p $script_dir/miniconda [ -d miniconda ] || bash ./Miniconda3-latest-Linux-x86_64.sh -b -p $script_dir/miniconda
$script_dir/miniconda/bin/conda create --prefix $script_dir/python-occlum -y python=3.9.11 flask=2.2.2 flask-restful=0.3.9 jinja2=3.1.2 werkzeug $script_dir/miniconda/bin/conda create --prefix $script_dir/python-occlum -y python=3.9.11 flask=2.2.2 flask-restful=0.3.9 jinja2=3.1.2 werkzeug=2.3
# 3. Remove miniconda and installation scripts # 3. Remove miniconda and installation scripts
rm -rf ./Miniconda3-latest-Linux-x86_64.sh $script_dir/miniconda rm -rf ./Miniconda3-latest-Linux-x86_64.sh $script_dir/miniconda

26
src/libos/Cargo.lock generated

@ -12,6 +12,7 @@ dependencies = [
"bitvec 1.0.1", "bitvec 1.0.1",
"ctor", "ctor",
"derive_builder", "derive_builder",
"errno",
"goblin", "goblin",
"intrusive-collections", "intrusive-collections",
"itertools", "itertools",
@ -38,6 +39,7 @@ dependencies = [
"sgx_tstd", "sgx_tstd",
"sgx_types", "sgx_types",
"spin 0.7.1", "spin 0.7.1",
"vdso-time",
] ]
[[package]] [[package]]
@ -207,6 +209,16 @@ version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797"
[[package]]
name = "errno"
version = "0.1.0"
dependencies = [
"log",
"rcore-fs",
"serde_json",
"sgx_tstd",
]
[[package]] [[package]]
name = "fnv" name = "fnv"
version = "1.0.7" version = "1.0.7"
@ -809,6 +821,20 @@ dependencies = [
"rand", "rand",
] ]
[[package]]
name = "vdso-time"
version = "0.1.0"
dependencies = [
"cfg-if",
"errno",
"lazy_static",
"log",
"sgx_libc",
"sgx_trts",
"sgx_tstd",
"sgx_types",
]
[[package]] [[package]]
name = "winapi" name = "winapi"
version = "0.3.9" version = "0.3.9"

@ -41,7 +41,7 @@ modular-bitfield = "0.11.2"
sgx_tstd = { path = "../../deps/rust-sgx-sdk/sgx_tstd" } sgx_tstd = { path = "../../deps/rust-sgx-sdk/sgx_tstd" }
[features] [features]
default = ["integrity_only_opt", "sgx_file_cache", "sgx1_exception_sim"] default = ["integrity_only_opt", "sgx_file_cache", "sgx1_exception_sim", "kernel_heap_monitor"]
syscall_timing = [] # Timing for each syscall. But it has cost from more ocall. syscall_timing = [] # Timing for each syscall. But it has cost from more ocall.
integrity_only_opt = [] # Clear bss only. It should be disabled if checking memory reads. integrity_only_opt = [] # Clear bss only. It should be disabled if checking memory reads.
sgx_file_cache = [] # Cache SgxFile objects. Invalidation is unimplemented. sgx_file_cache = [] # Cache SgxFile objects. Invalidation is unimplemented.

@ -7,12 +7,19 @@ bitflags! {
} }
} }
pub fn do_fchownat(fs_path: &FsPath, uid: u32, gid: u32, flags: ChownFlags) -> Result<()> { pub fn do_fchownat(fs_path: &FsPath, uid: i32, gid: i32, flags: ChownFlags) -> Result<()> {
debug!( debug!(
"fchownat: fs_path: {:?}, uid: {}, gid: {}, flags: {:?}", "fchownat: fs_path: {:?}, uid: {}, gid: {}, flags: {:?}",
fs_path, uid, gid, flags fs_path, uid, gid, flags
); );
let uid = to_opt(uid)?;
let gid = to_opt(gid)?;
// Return early if owner and group are -1
if uid.is_none() && gid.is_none() {
return Ok(());
}
let inode = { let inode = {
let path = fs_path.to_abs_path()?; let path = fs_path.to_abs_path()?;
let current = current!(); let current = current!();
@ -24,19 +31,47 @@ pub fn do_fchownat(fs_path: &FsPath, uid: u32, gid: u32, flags: ChownFlags) -> R
} }
}; };
let mut info = inode.metadata()?; let mut info = inode.metadata()?;
info.uid = uid as usize; if let Some(uid) = uid {
info.gid = gid as usize; info.uid = uid as usize;
}
if let Some(gid) = gid {
info.gid = gid as usize;
}
inode.set_metadata(&info)?; inode.set_metadata(&info)?;
Ok(()) Ok(())
} }
pub fn do_fchown(fd: FileDesc, uid: u32, gid: u32) -> Result<()> { pub fn do_fchown(fd: FileDesc, uid: i32, gid: i32) -> Result<()> {
debug!("fchown: fd: {}, uid: {}, gid: {}", fd, uid, gid); debug!("fchown: fd: {}, uid: {}, gid: {}", fd, uid, gid);
let uid = to_opt(uid)?;
let gid = to_opt(gid)?;
// Return early if owner and group are -1
if uid.is_none() && gid.is_none() {
return Ok(());
}
let file_ref = current!().file(fd)?; let file_ref = current!().file(fd)?;
let mut info = file_ref.metadata()?; let mut info = file_ref.metadata()?;
info.uid = uid as usize; if let Some(uid) = uid {
info.gid = gid as usize; info.uid = uid as usize;
}
if let Some(gid) = gid {
info.gid = gid as usize;
}
file_ref.set_metadata(&info)?; file_ref.set_metadata(&info)?;
Ok(()) Ok(())
} }
fn to_opt(id: i32) -> Result<Option<u32>> {
let id = if id >= 0 {
Some(id as u32)
} else if id == -1 {
// If the ID is specified as -1, then that ID is not changed
None
} else {
return_errno!(EINVAL, "invalid id");
};
Ok(id)
}

@ -36,8 +36,9 @@ impl ProcINode for ProcStatINode {
let stime = 0; let stime = 0;
let cutime = 0; let cutime = 0;
let cstime = 0; let cstime = 0;
let priority = main_thread.nice().read().unwrap().to_priority_val(); // Convert [19,-20] to [39,0].
let nice = main_thread.nice().read().unwrap().raw_val(); let priority = main_thread.nice().read().unwrap().to_raw_val() + 20;
let nice = main_thread.nice().read().unwrap().to_raw_val();
let num_threads = self.0.threads().len(); let num_threads = self.0.threads().len();
let itrealvalue = 0; let itrealvalue = 0;
let starttime = self.0.start_time(); let starttime = self.0.start_time();

@ -606,16 +606,16 @@ pub fn do_fchmodat(dirfd: i32, path: *const i8, mode: u16) -> Result<isize> {
Ok(0) Ok(0)
} }
pub fn do_chown(path: *const i8, uid: u32, gid: u32) -> Result<isize> { pub fn do_chown(path: *const i8, uid: i32, gid: i32) -> Result<isize> {
self::do_fchownat(AT_FDCWD, path, uid, gid, 0) self::do_fchownat(AT_FDCWD, path, uid, gid, 0)
} }
pub fn do_fchown(fd: FileDesc, uid: u32, gid: u32) -> Result<isize> { pub fn do_fchown(fd: FileDesc, uid: i32, gid: i32) -> Result<isize> {
file_ops::do_fchown(fd, uid, gid)?; file_ops::do_fchown(fd, uid, gid)?;
Ok(0) Ok(0)
} }
pub fn do_fchownat(dirfd: i32, path: *const i8, uid: u32, gid: u32, flags: i32) -> Result<isize> { pub fn do_fchownat(dirfd: i32, path: *const i8, uid: i32, gid: i32, flags: i32) -> Result<isize> {
let path = from_user::clone_cstring_safely(path)? let path = from_user::clone_cstring_safely(path)?
.to_string_lossy() .to_string_lossy()
.into_owned(); .into_owned();
@ -631,7 +631,7 @@ pub fn do_fchownat(dirfd: i32, path: *const i8, uid: u32, gid: u32, flags: i32)
Ok(0) Ok(0)
} }
pub fn do_lchown(path: *const i8, uid: u32, gid: u32) -> Result<isize> { pub fn do_lchown(path: *const i8, uid: i32, gid: i32) -> Result<isize> {
self::do_fchownat( self::do_fchownat(
AT_FDCWD, AT_FDCWD,
path, path,

@ -42,6 +42,9 @@ pub struct Thread {
fs: FsViewRef, fs: FsViewRef,
files: FileTableRef, files: FileTableRef,
sched: SchedAgentRef, sched: SchedAgentRef,
// According to POSIX, the nice value is a per-process setting.
// In our implementation, the threads belong to same process
// share the same nice value.
nice: NiceValueRef, nice: NiceValueRef,
rlimits: ResourceLimitsRef, rlimits: ResourceLimitsRef,
// Signal // Signal

@ -2,18 +2,17 @@ use super::priority::{NiceValue, PrioWhich};
use crate::prelude::*; use crate::prelude::*;
use crate::process::table::{get_all_processes, get_pgrp, get_process}; use crate::process::table::{get_all_processes, get_pgrp, get_process};
pub fn do_set_priority(which: PrioWhich, who: i32, prio: NiceValue) -> Result<()> { pub fn do_set_priority(which: PrioWhich, who: i32, nice: NiceValue) -> Result<()> {
debug!( debug!(
"set_priority: which: {:?}, who: {}, prio: {:?}", "set_priority: which: {:?}, who: {}, nice: {:?}",
which, who, prio which, who, nice
); );
let processes = get_processes(which, who)?; let processes = get_processes(which, who)?;
for process in processes.iter() { for process in processes.iter() {
let main_thread = process for thread in process.threads().iter() {
.main_thread() *thread.nice().write().unwrap() = nice;
.ok_or_else(|| errno!(ESRCH, "invalid pid"))?; }
*main_thread.nice().write().unwrap() = prio;
} }
Ok(()) Ok(())
} }
@ -22,27 +21,25 @@ pub fn do_get_priority(which: PrioWhich, who: i32) -> Result<NiceValue> {
debug!("get_priority: which: {:?}, who: {}", which, who); debug!("get_priority: which: {:?}, who: {}", which, who);
let processes = get_processes(which, who)?; let processes = get_processes(which, who)?;
let prio = { let nice = {
let mut prio = NiceValue::max_value(); let mut nice = NiceValue::MAX;
for process in processes.iter() { for process in processes.iter() {
let main_thread = process let main_thread = process
.main_thread() .main_thread()
.ok_or_else(|| errno!(ESRCH, "invalid pid"))?; .ok_or_else(|| errno!(ESRCH, "invalid pid"))?;
let nice_value = main_thread.nice().read().unwrap(); let current_nice = main_thread.nice().read().unwrap();
// Returns the highest priority enjoyed by the processes // Returns the highest priority enjoyed by the processes
if *nice_value < prio { if *current_nice < nice {
prio = *nice_value; nice = *current_nice;
} }
} }
prio nice
}; };
Ok(prio) Ok(nice)
} }
// According to POSIX, the nice value is a per-process setting.
// In our implementation, the threads belong to same process share the same nice value.
fn get_processes(which: PrioWhich, who: i32) -> Result<Vec<crate::process::ProcessRef>> { fn get_processes(which: PrioWhich, who: i32) -> Result<Vec<crate::process::ProcessRef>> {
Ok(match which { let processes = match which {
PrioWhich::PRIO_PROCESS => { PrioWhich::PRIO_PROCESS => {
let process = if who == 0 { let process = if who == 0 {
current!().process().clone() current!().process().clone()
@ -67,5 +64,10 @@ fn get_processes(which: PrioWhich, who: i32) -> Result<Vec<crate::process::Proce
return_errno!(ESRCH, "no such user"); return_errno!(ESRCH, "no such user");
} }
} }
}) };
if processes.is_empty() {
return_errno!(ESRCH, "no such process");
}
Ok(processes)
} }

@ -21,55 +21,48 @@ impl TryFrom<i32> for PrioWhich {
} }
} }
/// Process priority value /// Process scheduling nice value.
/// ///
/// Lower values give a process a higher scheduling priority. /// Lower values give a process a higher scheduling priority.
#[derive(Copy, Clone, Debug, Default, PartialEq, PartialOrd)] #[derive(Copy, Clone, Debug, Default, PartialEq, PartialOrd)]
pub struct NiceValue { pub struct NiceValue {
value: i32, value: i8,
} }
impl NiceValue { impl NiceValue {
const MAX_PRIO: i32 = 19; pub const MAX: Self = Self { value: 19 };
const MIN_PRIO: i32 = -20; pub const MIN: Self = Self { value: -20 };
pub fn max_value() -> Self { /// Create a nice value from a raw value.
Self { ///
value: Self::MAX_PRIO, /// The raw value given beyond the range are automatically adjusted
/// to the nearest boundary value.
pub fn new(raw: i8) -> Self {
if raw < Self::MIN.value {
Self::MIN
} else if raw > Self::MAX.value {
Self::MAX
} else {
Self { value: raw }
} }
} }
pub fn min_value() -> Self { /// Convert to the raw value with range [19, -20].
Self { pub fn to_raw_val(self) -> i8 {
value: Self::MIN_PRIO,
}
}
pub fn raw_val(&self) -> i32 {
self.value self.value
} }
/// Convert [19,-20] to priority value [39,0].
pub fn to_priority_val(&self) -> i32 {
self.value - Self::MIN_PRIO
}
/// Convert [19,-20] to rlimit style value [1,40].
pub fn to_rlimit_val(&self) -> i32 {
Self::MAX_PRIO - self.value + 1
}
} }
impl From<i32> for NiceValue { impl From<i32> for NiceValue {
fn from(raw: i32) -> Self { fn from(raw: i32) -> Self {
let value = if raw < Self::MIN_PRIO { let adj_raw = if raw > i8::MAX as i32 {
Self::MIN_PRIO i8::MAX
} else if raw > Self::MAX_PRIO { } else if raw < i8::MIN as i32 {
Self::MAX_PRIO i8::MIN
} else { } else {
raw raw as i8
}; };
Self { value } Self::new(adj_raw)
} }
} }

@ -83,16 +83,16 @@ pub fn do_getcpu(cpu_ptr: *mut u32, node_ptr: *mut u32) -> Result<isize> {
pub fn do_set_priority(which: i32, who: i32, prio: i32) -> Result<isize> { pub fn do_set_priority(which: i32, who: i32, prio: i32) -> Result<isize> {
let which = PrioWhich::try_from(which)?; let which = PrioWhich::try_from(which)?;
let prio = NiceValue::from(prio); let nice = NiceValue::from(prio);
super::do_priority::do_set_priority(which, who, prio)?; super::do_priority::do_set_priority(which, who, nice)?;
Ok(0) Ok(0)
} }
pub fn do_get_priority(which: i32, who: i32) -> Result<isize> { pub fn do_get_priority(which: i32, who: i32) -> Result<isize> {
let which = PrioWhich::try_from(which)?; let which = PrioWhich::try_from(which)?;
let prio = super::do_priority::do_get_priority(which, who)?; let nice = super::do_priority::do_get_priority(which, who)?;
// To avoid negative return values, "getpriority()" will // To avoid negative return values, "getpriority()" will
// not return the normal nice-value, but a negated value that // not return the normal nice-value, but a negated value that
// has been offset by 20 (ie it returns 40..1 instead of -20..19) // has been offset by 20 (ie it returns 40..1 instead of -20..19)
Ok(prio.to_rlimit_val() as isize) Ok((20 - nice.to_raw_val()) as _)
} }

@ -189,9 +189,9 @@ macro_rules! process_syscall_table_with_callback {
(Readlink = 89) => do_readlink(path: *const i8, buf: *mut u8, size: usize), (Readlink = 89) => do_readlink(path: *const i8, buf: *mut u8, size: usize),
(Chmod = 90) => do_chmod(path: *const i8, mode: u16), (Chmod = 90) => do_chmod(path: *const i8, mode: u16),
(Fchmod = 91) => do_fchmod(fd: FileDesc, mode: u16), (Fchmod = 91) => do_fchmod(fd: FileDesc, mode: u16),
(Chown = 92) => do_chown(path: *const i8, uid: u32, gid: u32), (Chown = 92) => do_chown(path: *const i8, uid: i32, gid: i32),
(Fchown = 93) => do_fchown(fd: FileDesc, uid: u32, gid: u32), (Fchown = 93) => do_fchown(fd: FileDesc, uid: i32, gid: i32),
(Lchown = 94) => do_lchown(path: *const i8, uid: u32, gid: u32), (Lchown = 94) => do_lchown(path: *const i8, uid: i32, gid: i32),
(Umask = 95) => do_umask(mask: u16), (Umask = 95) => do_umask(mask: u16),
(Gettimeofday = 96) => do_gettimeofday(tv_u: *mut timeval_t), (Gettimeofday = 96) => do_gettimeofday(tv_u: *mut timeval_t),
(Getrlimit = 97) => do_gettrlimit(resource: u32, rlim: *mut rlimit_t), (Getrlimit = 97) => do_gettrlimit(resource: u32, rlim: *mut rlimit_t),
@ -357,7 +357,7 @@ macro_rules! process_syscall_table_with_callback {
(Openat = 257) => do_openat(dirfd: i32, path: *const i8, flags: u32, mode: u16), (Openat = 257) => do_openat(dirfd: i32, path: *const i8, flags: u32, mode: u16),
(Mkdirat = 258) => do_mkdirat(dirfd: i32, path: *const i8, mode: u16), (Mkdirat = 258) => do_mkdirat(dirfd: i32, path: *const i8, mode: u16),
(Mknodat = 259) => handle_unsupported(), (Mknodat = 259) => handle_unsupported(),
(Fchownat = 260) => do_fchownat(dirfd: i32, path: *const i8, uid: u32, gid: u32, flags: i32), (Fchownat = 260) => do_fchownat(dirfd: i32, path: *const i8, uid: i32, gid: i32, flags: i32),
(Futimesat = 261) => do_futimesat(dirfd: i32, path: *const i8, times: *const timeval_t), (Futimesat = 261) => do_futimesat(dirfd: i32, path: *const i8, times: *const timeval_t),
(Fstatat = 262) => do_fstatat(dirfd: i32, path: *const i8, stat_buf: *mut Stat, flags: u32), (Fstatat = 262) => do_fstatat(dirfd: i32, path: *const i8, stat_buf: *mut Stat, flags: u32),
(Unlinkat = 263) => do_unlinkat(dirfd: i32, path: *const i8, flags: i32), (Unlinkat = 263) => do_unlinkat(dirfd: i32, path: *const i8, flags: i32),

@ -55,6 +55,57 @@ static int __test_chown(const char *file_path) {
return 0; return 0;
} }
static int __test_chown_with_negative_id(const char *file_path) {
struct stat old_stat_buf;
struct stat new_stat_buf;
uid_t uid = -100;
gid_t gid = -100;
int ret;
ret = chown(file_path, uid, gid);
if (!(ret < 0 && errno == EINVAL)) {
THROW_ERROR("chown should return EINVAL");
}
ret = stat(file_path, &old_stat_buf);
if (ret < 0) {
THROW_ERROR("failed to stat file");
}
uid = 100;
gid = -1;
ret = chown(file_path, uid, gid);
if (ret < 0) {
THROW_ERROR("failed to chown file");
}
ret = stat(file_path, &new_stat_buf);
if (ret < 0) {
THROW_ERROR("failed to stat file");
}
if (new_stat_buf.st_uid != uid || new_stat_buf.st_gid != old_stat_buf.st_gid) {
THROW_ERROR("check chown result failed");
}
old_stat_buf.st_uid = new_stat_buf.st_uid;
uid = -1;
gid = 100;
ret = chown(file_path, uid, gid);
if (ret < 0) {
THROW_ERROR("failed to chown file");
}
ret = stat(file_path, &new_stat_buf);
if (ret < 0) {
THROW_ERROR("failed to stat file");
}
if (new_stat_buf.st_uid != old_stat_buf.st_uid || new_stat_buf.st_gid != gid) {
THROW_ERROR("check chown result failed");
}
return 0;
}
static int __test_lchown(const char *file_path) { static int __test_lchown(const char *file_path) {
struct stat stat_buf; struct stat stat_buf;
uid_t uid = 100; uid_t uid = 100;
@ -188,6 +239,10 @@ static int test_chown() {
return test_chown_framework(__test_chown); return test_chown_framework(__test_chown);
} }
static int test_chown_with_negative_id() {
return test_chown_framework(__test_chown_with_negative_id);
}
static int test_lchown() { static int test_lchown() {
return test_chown_framework(__test_lchown); return test_chown_framework(__test_lchown);
} }
@ -210,6 +265,7 @@ static int test_fchownat_with_empty_path() {
static test_case_t test_cases[] = { static test_case_t test_cases[] = {
TEST_CASE(test_chown), TEST_CASE(test_chown),
TEST_CASE(test_chown_with_negative_id),
TEST_CASE(test_lchown), TEST_CASE(test_lchown),
TEST_CASE(test_fchown), TEST_CASE(test_fchown),
TEST_CASE(test_fchownat), TEST_CASE(test_fchownat),

@ -125,7 +125,7 @@ RUN wget http://www.etallen.com/cpuid/cpuid-20200211.x86_64.tar.gz && \
# Download the Occlum source # Download the Occlum source
ARG OCCLUM_BRANCH ARG OCCLUM_BRANCH
WORKDIR /root WORKDIR /root
RUN git clone -b $OCCLUM_BRANCH https://gitea.detee.cloud/general/occlum && \ RUN git clone -b $OCCLUM_BRANCH https://github.com/occlum/occlum && \
cp -r /root/occlum/tools/toolchains/* /tmp/ && mkdir -p /opt/occlum/ && \ cp -r /root/occlum/tools/toolchains/* /tmp/ && mkdir -p /opt/occlum/ && \
cp /root/occlum/tools/docker/start_aesm.sh /opt/occlum/ cp /root/occlum/tools/docker/start_aesm.sh /opt/occlum/

@ -129,7 +129,7 @@ RUN wget http://www.etallen.com/cpuid/cpuid-20200211.x86_64.tar.gz && \
# Download the Occlum source # Download the Occlum source
ARG OCCLUM_BRANCH ARG OCCLUM_BRANCH
WORKDIR /root WORKDIR /root
RUN git clone -b $OCCLUM_BRANCH https://gitea.detee.cloud/general/occlum && \ RUN git clone -b $OCCLUM_BRANCH https://github.com/occlum/occlum && \
cd /root/occlum && git submodule update --init && \ cd /root/occlum && git submodule update --init && \
mkdir -p /opt/occlum/ && \ mkdir -p /opt/occlum/ && \
cp /root/occlum/tools/docker/start_aesm.sh /opt/occlum/ cp /root/occlum/tools/docker/start_aesm.sh /opt/occlum/

@ -136,7 +136,7 @@ RUN git clone -b sgx_2.20_for_occlum https://github.com/occlum/linux-sgx && \
# Download the Occlum source # Download the Occlum source
ARG OCCLUM_BRANCH ARG OCCLUM_BRANCH
WORKDIR /root WORKDIR /root
RUN git clone -b $OCCLUM_BRANCH https://gitea.detee.cloud/general/occlum && \ RUN git clone -b $OCCLUM_BRANCH https://github.com/occlum/occlum && \
cd /root/occlum && git submodule update --init && \ cd /root/occlum && git submodule update --init && \
mkdir -p /opt/occlum/ && \ mkdir -p /opt/occlum/ && \
cp /root/occlum/tools/docker/start_aesm.sh /opt/occlum/ cp /root/occlum/tools/docker/start_aesm.sh /opt/occlum/
@ -184,9 +184,9 @@ COPY --from=alpine /usr/lib/jvm/java-1.8-openjdk $JDK8_PATH
RUN rm $JDK8_PATH/jre/lib/security/cacerts RUN rm $JDK8_PATH/jre/lib/security/cacerts
COPY --from=alpine /etc/ssl/certs/java/cacerts $JDK8_PATH/jre/lib/security/cacerts COPY --from=alpine /etc/ssl/certs/java/cacerts $JDK8_PATH/jre/lib/security/cacerts
# Install DCAP and Utilities libraries # Install DCAP library
WORKDIR /root/occlum/tools/toolchains WORKDIR /root/occlum/tools/toolchains
RUN cd dcap_lib && ./build.sh && cd ../utils_lib && ./build.sh && cd .. && rm -rf utils_lib dcap_lib RUN cd dcap_lib && ./build.sh && cd .. && rm -rf dcap_lib
# Install AECS Client library # Install AECS Client library
WORKDIR /root/occlum/tools/toolchains WORKDIR /root/occlum/tools/toolchains