Skip to content

Commit 0cbae57

Browse files
SHM: adding sys_shm_get_infos() syscall (#41)
When sharing a shared memory with another, it would be highly easier to be able to get back the SHM infos withtout requiring DTS forge with ninja. The global problematic is defined in #39, which is fixed by this PR. This PR also fixes an invalid glue addition of DMA-related entries at UAPI level versus gate LUT, which were not synchronize in term of syscall identifiers, making autotest failing for the new SHM syscall. Note: all new syscalls are append to avoid any ABI violation. Closes #39
2 parents 4d0e767 + 06630a7 commit 0cbae57

File tree

16 files changed

+408
-5
lines changed

16 files changed

+408
-5
lines changed

.github/workflows/gnulinux.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ concurrency:
1818

1919
jobs:
2020
forge_matrix:
21-
runs-on: ${{ vars.DEFAULT_RUNNER_NAME }}
21+
runs-on: ubuntu-latest
2222
container:
2323
image: python:3.9.14-alpine3.16
2424
steps:
@@ -58,7 +58,7 @@ jobs:
5858
defaults:
5959
run:
6060
shell: bash
61-
runs-on: ${{ vars.DEFAULT_RUNNER_NAME }}
61+
runs-on: ubuntu-latest
6262
container:
6363
image: ${{ matrix.operating_system }}
6464
steps:
@@ -130,7 +130,7 @@ jobs:
130130
defaults:
131131
run:
132132
shell: bash
133-
runs-on: ${{ vars.DEFAULT_RUNNER_NAME }}
133+
runs-on: ubuntu-latest
134134
container:
135135
image: 'mesonbuild/ubuntu-rolling'
136136
steps:
@@ -194,7 +194,7 @@ jobs:
194194
defaults:
195195
run:
196196
shell: bash
197-
runs-on: ${{ vars.DEFAULT_RUNNER_NAME }}
197+
runs-on: ubuntu-latest
198198
container:
199199
image: 'mesonbuild/ubuntu-rolling'
200200
steps:

.github/workflows/proof.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ jobs:
1919
defaults:
2020
run:
2121
shell: bash
22-
runs-on: ${{ vars.DEFAULT_RUNNER_NAME }}
22+
runs-on: ubuntu-latest
2323
container: 'pthierry38/framac-runner:29'
2424
timeout-minutes: 60
2525
steps:

autotest/src/tests/test_shm.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,26 @@ void test_shm_invalidmap(void) {
6666
TEST_END();
6767
}
6868

69+
void test_shm_infos(void) {
70+
Status res;
71+
shmh_t shm;
72+
shm_infos_t infos;
73+
TEST_START();
74+
res = sys_get_shm_handle(shms[0].id);
75+
copy_to_user((uint8_t*)&shm, sizeof(shmh_t));
76+
ASSERT_EQ(res, STATUS_OK);
77+
res = sys_shm_get_infos(shm);
78+
copy_to_user((uint8_t*)&infos, sizeof(shm_infos_t));
79+
80+
ASSERT_EQ(res, STATUS_OK);
81+
ASSERT_EQ(infos.label, shms[0].id);
82+
ASSERT_EQ(infos.handle, shm);
83+
ASSERT_EQ((uint32_t)infos.base, (uint32_t)shms[0].baseaddr);
84+
ASSERT_EQ((uint32_t)infos.len, (uint32_t)shms[0].size);
85+
86+
TEST_END();
87+
}
88+
6989
void test_shm_creds_on_mapped(void) {
7090
Status res;
7191
shmh_t shm;
@@ -185,6 +205,7 @@ void test_shm(void) {
185205
test_shm_mapunmap();
186206
test_shm_map_unmappable();
187207
test_shm_creds_on_mapped();
208+
test_shm_infos();
188209
test_shm_allows_idle();
189210
TEST_SUITE_END("sys_map_shm");
190211
}

doc/concepts/uapi/syscalls.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,11 @@ Syscall definition
139139
single: sys_shm_set_credential; usage
140140
.. include:: syscalls/shm_set_credential.rst
141141

142+
.. index::
143+
single: sys_shm_get_infos; definition
144+
single: sys_shm_get_infos; usage
145+
.. include:: syscalls/shm_get_infos.rst
146+
142147
.. index::
143148
single: sys_wait_for_event; definition
144149
single: sys_wait_for_event; usage

doc/concepts/uapi/syscalls/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ syscalls_src = files(
2222
'shm_map.rst',
2323
'shm_unmap.rst',
2424
'shm_set_credential.rst',
25+
'shm_get_infos.rst',
2526
'send_ipc.rst',
2627
'waitforevent.rst',
2728
)
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
sys_shm_get_infos
2+
"""""""""""""""""
3+
.. _uapi_shm_get_infos:
4+
5+
**API definition**
6+
7+
.. code-block:: rust
8+
:caption: Rust UAPI for shm_get_infos syscall
9+
10+
mod uapi {
11+
fn shm_get_infos(shm: shm_t) -> Status
12+
}
13+
14+
.. code-block:: c
15+
:caption: C UAPI for shm_get_infos syscall
16+
17+
enum Status sys_shm_get_infos(shmh_t shm);
18+
19+
**Usage**
20+
21+
In Sentry, as explained in :ref:`SHM model definition chapter <shm_principles>`, a shared memory
22+
holds credential for its owner and user task. It also hold some memory-related shm_get_infos
23+
such as base address and size.
24+
25+
These information set is useful to get back in user-space without requiring any DTS forge at application level.
26+
27+
These informations can be received through this syscall, by fulfilling the shm_infos_t structure
28+
declared by the UAPI in the SVC Exchange area. The `shm_infos_t` is defined in the
29+
UAPI `<types.h>` header in C or through the uapi.systypes Rust mod.
30+
31+
.. code-block:: C
32+
:linenos:
33+
:caption: shm_infos_t structure definition
34+
35+
/* SHM informations data structure */
36+
typedef struct shm_infos {
37+
shmh_t handle; /*< SHM handle */
38+
uint32_t label; /*< SHM label */
39+
size_t base; /*< SHM base address */
40+
size_t len; /*< SHM length in bytes */
41+
uint32_t perms; /*< SHM permissions (mask of SHMPermission) */
42+
} shm_infos_t;
43+
44+
45+
46+
The only input required for this syscall is the SHM handle, as given by the
47+
`sys_get_shmhandle()` syscall.
48+
49+
When a given SHM credentials set for the current job is updated, the `sys_shm_get_infos()`
50+
returns an up-to-date content synchronously.
51+
52+
.. code-block:: C
53+
:linenos:
54+
:caption: sample bare usage of sys_shm_get_infos
55+
56+
uint32_t my_shm_label=0xf00UL;
57+
taskh_t myself;
58+
shm_infos_t infos;
59+
if (sys_get_task_handle(myself_label) != STATUS_OK) {
60+
// [...]
61+
}
62+
copy_to_user(&myself, sizeof(taskh_t));
63+
if (sys_get_shm_handle(my_shm_label) != STATUS_OK) {
64+
// [...]
65+
}
66+
copy_to_user(&my_shm_handle, sizeof(shmh_t));
67+
68+
if (sys_shm_get_infos(my_shm_handle)) {
69+
// [...]
70+
}
71+
copy_to_user(&infos, sizeof(shm_infos_t));
72+
printf("SHM base address is %lx\n", infos.base);
73+
74+
**Required capability**
75+
76+
None.
77+
78+
**Return values**
79+
80+
* STATUS_INVALID if the SHM do not exist, target do not exist or is not owned or used by the calling task
81+
* STATUS_OK

kernel/include/sentry/managers/memory.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,12 @@ kstatus_t mgr_mm_shm_is_shared(shmh_t shm, secure_bool_t * result);
111111

112112
kstatus_t mgr_mm_shm_get_handle(uint32_t shm_id, shmh_t *handle);
113113

114+
kstatus_t mgr_mm_shm_get_baseaddr(shmh_t shm, size_t *base);
115+
116+
kstatus_t mgr_mm_shm_get_size(shmh_t shm, size_t *size);
117+
118+
kstatus_t mgr_mm_shm_get_label(shmh_t shm, uint32_t *label);
119+
114120
/* per user/owner properties requests */
115121

116122
kstatus_t mgr_mm_shm_is_mapped_by(shmh_t shm, shm_user_t accessor, secure_bool_t * result);

kernel/include/sentry/syscalls.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,4 +69,6 @@ stack_frame_t *gate_log(stack_frame_t *frame, __MAYBE_UNUSED uint32_t log_len);
6969

7070
stack_frame_t *gate_get_dmahandle(stack_frame_t *frame, uint32_t streamlabel);
7171

72+
stack_frame_t *gate_shm_get_infos(stack_frame_t *frame, shmh_t shm);
73+
7274
#endif/*!SYSCALLS_H*/

kernel/src/arch/asm-generic/handler-svc-lut.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,16 @@ static stack_frame_t *lut_notsup(stack_frame_t *f) {
178178
return f;
179179
}
180180

181+
static stack_frame_t *lut_shm_get_infos(stack_frame_t *frame) {
182+
shmh_t shm = frame->r0;
183+
return gate_shm_get_infos(frame, shm);
184+
}
185+
186+
/* for not yet supported syscalls */
187+
static stack_frame_t *lut_unsuported(stack_frame_t *frame) {
188+
mgr_task_set_sysreturn(sched_get_current(), STATUS_NO_ENTITY);
189+
return frame;
190+
}
181191

182192
static const lut_svc_handler svc_lut[] = {
183193
lut_exit,
@@ -210,6 +220,10 @@ static const lut_svc_handler svc_lut[] = {
210220
lut_int_disable,
211221
lut_get_shmhandle,
212222
lut_get_dmahandle,
223+
lut_unsuported, /* DMA Start Stream */
224+
lut_unsuported, /* DMA Stop Stream */
225+
lut_unsuported, /* DMA Get Stream Status */
226+
lut_shm_get_infos,
213227
};
214228

215229
#define SYSCALL_NUM ARRAY_SIZE(svc_lut)

kernel/src/managers/memory/memory_shm.c

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,111 @@ kstatus_t mgr_mm_shm_declare_user(shmh_t shm, taskh_t task)
143143
return status;
144144
}
145145

146+
/**
147+
* @fn get base address of the given SHM
148+
*
149+
* @param[in] shm: Shared memory handle that identify the SHM
150+
* @param[out] base: base address of the SHM returned when found
151+
*/
152+
kstatus_t mgr_mm_shm_get_baseaddr(shmh_t shm, size_t *base)
153+
{
154+
kstatus_t status = K_ERROR_INVPARAM;
155+
kshmh_t const *kshm = shmh_to_kshmh(&shm);
156+
157+
/*@ assert \valid_read(kshm); */
158+
159+
if (unlikely(mgr_mm_configured() == SECURE_FALSE)) {
160+
status = K_ERROR_BADSTATE;
161+
goto end;
162+
}
163+
if (unlikely(base == NULL)) {
164+
goto end;
165+
}
166+
/*@ assert \valid(base); */
167+
/* check that id exsits */
168+
if (unlikely(kshm->id >= SHM_LIST_SIZE)) {
169+
goto end;
170+
}
171+
/* check that handle matches */
172+
if (unlikely(shm_table[kshm->id].handle != shm)) {
173+
goto end;
174+
}
175+
*base = shm_table[kshm->id].meta->baseaddr;
176+
status = K_STATUS_OKAY;
177+
end:
178+
return status;
179+
}
180+
181+
/**
182+
* @fn get size in bytes of the given SHM
183+
*
184+
* @param[in] shm: Shared memory handle that identify the SHM
185+
* @param[out] size: length in bytes of the SHM returned when found
186+
*/
187+
kstatus_t mgr_mm_shm_get_size(shmh_t shm, size_t *size)
188+
{
189+
kstatus_t status = K_ERROR_INVPARAM;
190+
kshmh_t const *kshm = shmh_to_kshmh(&shm);
191+
192+
/*@ assert \valid_read(kshm); */
193+
194+
if (unlikely(mgr_mm_configured() == SECURE_FALSE)) {
195+
status = K_ERROR_BADSTATE;
196+
goto end;
197+
}
198+
if (unlikely(size == NULL)) {
199+
goto end;
200+
}
201+
/*@ assert \valid(size); */
202+
/* check that id exsits */
203+
if (unlikely(kshm->id >= SHM_LIST_SIZE)) {
204+
goto end;
205+
}
206+
/* check that handle matches */
207+
if (unlikely(shm_table[kshm->id].handle != shm)) {
208+
goto end;
209+
}
210+
*size = shm_table[kshm->id].meta->size;
211+
status = K_STATUS_OKAY;
212+
end:
213+
return status;
214+
}
215+
216+
/**
217+
* @fn get label defined in DTS for the given SHM
218+
*
219+
* @param[in] shm: Shared memory handle that identify the SHM
220+
* @param[out] label: identifier of the SHM as declared in the DTS, returned when found
221+
*/
222+
kstatus_t mgr_mm_shm_get_label(shmh_t shm, uint32_t *label)
223+
{
224+
kstatus_t status = K_ERROR_INVPARAM;
225+
kshmh_t const *kshm = shmh_to_kshmh(&shm);
226+
227+
/*@ assert \valid_read(kshm); */
228+
229+
if (unlikely(mgr_mm_configured() == SECURE_FALSE)) {
230+
status = K_ERROR_BADSTATE;
231+
goto end;
232+
}
233+
if (unlikely(label == NULL)) {
234+
goto end;
235+
}
236+
/*@ assert \valid(label); */
237+
/* check that id exsits */
238+
if (unlikely(kshm->id >= SHM_LIST_SIZE)) {
239+
goto end;
240+
}
241+
/* check that handle matches */
242+
if (unlikely(shm_table[kshm->id].handle != shm)) {
243+
goto end;
244+
}
245+
*label = shm_table[kshm->id].meta->shm_label;
246+
status = K_STATUS_OKAY;
247+
end:
248+
return status;
249+
}
250+
146251
/**
147252
* @brief specify if the given SHM can be mapped by owner or user
148253
*

0 commit comments

Comments
 (0)