[kernel] Only accept invalid handles for optional syscall args

The syscall helpers.h get_handle functions should be returing
j6_err_invalid_arg if the handle they're given is j6_handle_invalid,
unless explicitly set to optional.
This commit is contained in:
Justin C. Miller
2023-02-06 01:13:55 -08:00
parent 8966380ef9
commit 359ee035d8
4 changed files with 29 additions and 16 deletions

View File

@@ -19,7 +19,7 @@ object mailbox : object {
method call [cap:send] { method call [cap:send] {
param tag uint64 [inout] param tag uint64 [inout]
param subtag uint64 [inout] param subtag uint64 [inout]
param give_handle ref object [inout handle] param give_handle ref object [optional inout handle]
} }
# Respond to a message sent using call, and wait for another # Respond to a message sent using call, and wait for another
@@ -29,7 +29,7 @@ object mailbox : object {
method respond [cap:receive] { method respond [cap:receive] {
param tag uint64 [inout] param tag uint64 [inout]
param subtag uint64 [inout] param subtag uint64 [inout]
param give_handle ref object [inout handle] param give_handle ref object [optional inout handle]
param reply_tag uint64 [inout] param reply_tag uint64 [inout]
param flags uint64 param flags uint64
} }

View File

@@ -90,7 +90,7 @@ for id, scope, method in syscalls.methods:
args = [] # The function call args to call the impl args = [] # The function call args to call the impl
argdefs = [] # The user-facing syscall args signature argdefs = [] # The user-facing syscall args signature
cxxargdefs = [] # The kernel syscall impl args signature cxxargdefs = [] # The kernel syscall impl args signature
refparams = [] # The list of params which are kobjects refparams = [] # The list of params which are pointers
handles = [] handles = []
objparams = [] objparams = []
@@ -111,7 +111,11 @@ for id, scope, method in syscalls.methods:
cxxargdefs.append(f"obj::{scope.cname} *self") cxxargdefs.append(f"obj::{scope.cname} *self")
objparams.append((f"obj::{scope.cname} *", "self")) objparams.append((f"obj::{scope.cname} *", "self"))
handles.append((scope.cname, "self", get_caps(method.options, scope))) handles.append((
scope.cname,
"self",
get_caps(method.options, scope),
False))
for param in method.params: for param in method.params:
needs_obj = param.type.needs_object(param.options) needs_obj = param.type.needs_object(param.options)
@@ -125,7 +129,12 @@ for id, scope, method in syscalls.methods:
arg = f"{param.name}{suffix}" arg = f"{param.name}{suffix}"
if needs_handle: if needs_handle:
handles.append((param.type.object.cname, arg, get_caps(param.options, param.type.object))) handles.append((
param.type.object.cname,
arg,
get_caps(param.options, param.type.object),
param.optional))
if needs_obj: if needs_obj:
objparams.append((type, arg)) objparams.append((type, arg))
args.append(f"{arg}_obj") args.append(f"{arg}_obj")
@@ -138,7 +147,9 @@ for id, scope, method in syscalls.methods:
if not needs_handle and param.caps: if not needs_handle and param.caps:
handles.append(( handles.append((
f"obj::{param.type.object.cname}", f"obj::{param.type.object.cname}",
arg, get_caps(param.options, param.type.object))) arg,
get_caps(param.options, param.type.object,
param.optional)))
if param.refparam: if param.refparam:
subs = param.type.c_names(param.options) subs = param.type.c_names(param.options)
@@ -173,13 +184,15 @@ for id, scope, method in syscalls.methods:
if handles: if handles:
cog.outl(f" j6_status_t res;") cog.outl(f" j6_status_t res;")
for type, arg, caps in handles: for type, arg, caps, optional in handles:
capsval = "0" capsval = "0"
if caps: if caps:
capsval = " | ".join(caps) capsval = " | ".join(caps)
optstr = (optional and "true") or "false"
cog.outl(f" obj::{type} *{arg}_obj = nullptr;") cog.outl(f" obj::{type} *{arg}_obj = nullptr;")
cog.outl(f" res = get_handle<typename obj::{type}>({arg}, {capsval}, {arg}_obj);") cog.outl(f" res = get_handle<typename obj::{type}>({arg}, {capsval}, {arg}_obj, {optstr});")
cog.outl(f" if (res != j6_status_ok) return res;") cog.outl(f" if (res != j6_status_ok) return res;")
cog.outl() cog.outl()
@@ -195,7 +208,7 @@ for id, scope, method in syscalls.methods:
cog.outl(f""" _retval = {name}({", ".join(args)});""") cog.outl(f""" _retval = {name}({", ".join(args)});""")
cog.outl(" }\n") cog.outl(" }\n")
for type, arg, caps in handles: for type, arg, caps, optional in handles:
cog.outl(f" release_handle({arg});") cog.outl(f" release_handle({arg});")
cog.outl(f""" return _retval;""") cog.outl(f""" return _retval;""")

View File

@@ -23,11 +23,11 @@ T * construct_handle(j6_handle_t *id, Args... args)
} }
template <typename T> template <typename T>
j6_status_t get_handle(j6_handle_t id, j6_cap_t caps, T *&object) j6_status_t get_handle(j6_handle_t id, j6_cap_t caps, T *&object, bool optional = false)
{ {
if (id == j6_handle_invalid) { if (id == j6_handle_invalid) {
object = nullptr; object = nullptr;
return j6_status_ok; return optional ? j6_status_ok : j6_err_invalid_arg;
} }
capability *capdata = g_cap_table.retain(id); capability *capdata = g_cap_table.retain(id);
@@ -43,17 +43,17 @@ j6_status_t get_handle(j6_handle_t id, j6_cap_t caps, T *&object)
} }
template <typename T> template <typename T>
inline j6_status_t get_handle(j6_handle_t *id, j6_cap_t caps, T *&object) inline j6_status_t get_handle(j6_handle_t *id, j6_cap_t caps, T *&object, bool optional = false)
{ {
return get_handle<T>(*id, caps, object); return get_handle<T>(*id, caps, object, optional);
} }
template <> template <>
inline j6_status_t get_handle<obj::kobject>(j6_handle_t id, j6_cap_t caps, obj::kobject *&object) inline j6_status_t get_handle<obj::kobject>(j6_handle_t id, j6_cap_t caps, obj::kobject *&object, bool optional)
{ {
if (id == j6_handle_invalid) { if (id == j6_handle_invalid) {
object = nullptr; object = nullptr;
return j6_status_ok; return optional ? j6_status_ok : j6_err_invalid_arg;
} }
capability *capdata = g_cap_table.retain(id); capability *capdata = g_cap_table.retain(id);

View File

@@ -41,7 +41,7 @@ int
channel_pump_loop() channel_pump_loop()
{ {
j6_status_t result; j6_status_t result;
constexpr size_t buffer_size = 512; static constexpr size_t buffer_size = 512;
char buffer[buffer_size]; char buffer[buffer_size];
j6_handle_t slp = j6_find_first_handle(j6_object_type_mailbox); j6_handle_t slp = j6_find_first_handle(j6_object_type_mailbox);