@@ -13,6 +13,7 @@ import system.random;
1313import system.chrono;
1414import system.sched;
1515import system.sysctl;
16+ import magic_enum;
1617
1718namespace syscall ::misc
1819{
@@ -227,7 +228,7 @@ namespace syscall::misc
227228 unsigned long arg4, unsigned long arg5
228229 )
229230 {
230- lib::unused (arg3, arg4, arg5);
231+ lib::unused (arg4, arg5);
231232 switch (option)
232233 {
233234 case 3 : // PR_GET_DUMPABLE
@@ -243,15 +244,6 @@ namespace syscall::misc
243244 static_cast <sched::dumpable_t >(arg2), std::memory_order_relaxed
244245 );
245246 return 0 ;
246- case 23 : // PR_CAPBSET_READ
247- {
248- if (arg2 >= 64 )
249- return -EINVAL;
250- const auto cap = static_cast <sched::cap_t >(1ul << arg2);
251- if (!sched::cap_valid (cap))
252- return -EINVAL;
253- return sched::has_cap (sched::current_process ()->cred ->bounding , cap);
254- }
255247 case 15 : // PR_SET_NAME
256248 {
257249 constexpr std::size_t comm_max = 15 ;
@@ -287,6 +279,26 @@ namespace syscall::misc
287279 case 22 : // PR_SET_SECCOMP
288280 // TODO
289281 return -EINVAL;
282+ case 23 : // PR_CAPBSET_READ
283+ {
284+ if (arg2 >= 64 )
285+ return -EINVAL;
286+ const auto cap = static_cast <sched::cap_t >(1ul << arg2);
287+ if (!sched::cap_valid (cap))
288+ return -EINVAL;
289+ return sched::has_cap (sched::current_process ()->cred ->bounding , cap);
290+ }
291+ case 24 : // PR_CAPBSET_DROP
292+ {
293+ if (arg2 >= 64 )
294+ return -EINVAL;
295+ const auto cap = static_cast <sched::cap_t >(1ul << arg2);
296+ if (!sched::cap_valid (cap))
297+ return -EINVAL;
298+ if (const auto ret = sched::cap_bounding_drop (cap); !ret)
299+ return -lib::map_error (ret.error ());
300+ return 0 ;
301+ }
290302 case 38 : // PR_SET_NO_NEW_PRIVS
291303 if (arg2 != 1 )
292304 return -EINVAL;
@@ -295,6 +307,47 @@ namespace syscall::misc
295307 return 0 ;
296308 case 39 : // PR_GET_NO_NEW_PRIVS
297309 return sched::current_process ()->no_new_privs ;
310+ case 47 : // PR_CAP_AMBIENT
311+ switch (arg2)
312+ {
313+ case 1 : // PR_CAP_AMBIENT_IS_SET
314+ {
315+ if (arg3 >= 64 )
316+ return -EINVAL;
317+ const auto cap = static_cast <sched::cap_t >(1ul << arg3);
318+ if (!sched::cap_valid (cap))
319+ return -EINVAL;
320+ const auto ambient = sched::current_process ()->cred ->ambient ;
321+ return sched::has_cap (ambient, cap);
322+ }
323+ case 2 : // PR_CAP_AMBIENT_RAISE
324+ {
325+ if (arg3 >= 64 )
326+ return -EINVAL;
327+ const auto cap = static_cast <sched::cap_t >(1ul << arg3);
328+ if (!sched::cap_valid (cap))
329+ return -EINVAL;
330+ if (const auto ret = sched::cap_ambient_raise (cap); !ret)
331+ return -lib::map_error (ret.error ());
332+ return 0 ;
333+ }
334+ case 3 : // PR_CAP_AMBIENT_LOWER
335+ {
336+ if (arg3 >= 64 )
337+ return -EINVAL;
338+ const auto cap = static_cast <sched::cap_t >(1ul << arg3);
339+ if (!sched::cap_valid (cap))
340+ return -EINVAL;
341+ sched::cap_ambient_lower (cap);
342+ return 0 ;
343+ }
344+ case 4 : // PR_CAP_AMBIENT_CLEAR_ALL
345+ sched::cap_ambient_lower (sched::cap_t ::all);
346+ return 0 ;
347+ default :
348+ return -EINVAL;
349+ }
350+ std::unreachable ();
298351 default :
299352 lib::error (" prctl: unhandled option: 0x{:X}" , option);
300353 return -EINVAL;
0 commit comments