diff options
Diffstat (limited to 'lib9p')
-rw-r--r-- | lib9p/9p.c | 20 | ||||
-rw-r--r-- | lib9p/include/lib9p/9p.h | 19 | ||||
-rw-r--r-- | lib9p/internal.h | 11 | ||||
-rw-r--r-- | lib9p/types.c | 264 | ||||
-rwxr-xr-x | lib9p/types.gen | 46 |
5 files changed, 187 insertions, 173 deletions
@@ -45,9 +45,9 @@ int lib9p_errorf(struct lib9p_ctx *ctx, uint32_t linux_errno, char const *fmt, . return -1; } -ssize_t lib9p_unmarshal_size(struct lib9p_ctx *ctx, uint8_t *net_bytes) { +ssize_t lib9p_validate(struct lib9p_ctx *ctx, uint8_t *net_bytes) { /* Header */ - struct _checksize_ctx subctx = { + struct _validate_ctx subctx = { .ctx = ctx, .net_size = decode_u32le(net_bytes), .net_bytes = net_bytes, @@ -61,13 +61,21 @@ ssize_t lib9p_unmarshal_size(struct lib9p_ctx *ctx, uint8_t *net_bytes) { /* Body */ struct _vtable_msg vtable = _lib9p_vtables[ctx->version].msgs[typ]; - if (!vtable.unmarshal_extrasize) + if (!vtable.validate) return lib9p_errorf(ctx, LINUX_EOPNOTSUPP, "unknown message type %s", lib9p_msg_type_str(typ)); - if (vtable.unmarshal_extrasize(&subctx)) + if (vtable.validate(&subctx)) return -1; + assert(subctx.net_offset <= subctx.net_size); + if (subctx.net_offset < subctx.net_size) + return lib9p_error(ctx, LINUX_EBADMSG, "message has %"PRIu32" extra bytes", + subctx.net_size - subctx.net_offset); - return (ssize_t)(vtable.unmarshal_basesize + subctx.host_extra); + ssize_t ret; + if (__builtin_add_overflow(vtable.basesize, subctx.host_extra, &ret)) + return lib9p_error(ctx, LINUX_EMSGSIZE, "unmarshalled payload overflows SSIZE_MAX"); + + return ret; } void lib9p_unmarshal(struct lib9p_ctx *ctx, uint8_t *net_bytes, @@ -98,7 +106,7 @@ bool lib9p_marshal(struct lib9p_ctx *ctx, enum lib9p_msg_type typ, uint16_t tag, }; ret_bytes[4] = typ; encode_u16le(tag, &ret_bytes[5]); - + /* Body */ struct _vtable_msg vtable = _lib9p_vtables[ctx->version].msgs[typ]; if (vtable.marshal(&subctx, body)) diff --git a/lib9p/include/lib9p/9p.h b/lib9p/include/lib9p/9p.h index b33ae96..1c8f2e5 100644 --- a/lib9p/include/lib9p/9p.h +++ b/lib9p/include/lib9p/9p.h @@ -26,9 +26,12 @@ int lib9p_error(struct lib9p_ctx *ctx, uint32_t linux_errno, char const *msg); int lib9p_errorf(struct lib9p_ctx *ctx, uint32_t linux_errno, char const *fmt, ...); /** - * Return how much space the message at net_bytes will take when - * unmarshaled. This number may be larger than net_bytes due to (1) - * struct padding, (2) nul-terminator byes for strings. + * Validate a message's structure; it's size, string encodings, enums, + * and bitfields. + * + * Return how much space the message will take when unmarshaled. This + * number may be larger than net_bytes due to (1) struct padding, (2) + * nul-terminator bytes for strings. * * Emits an error (return -1, set ctx->err_num and ctx->err_msg) if * either the message type is unknown, or if net_bytes is too short @@ -39,10 +42,12 @@ int lib9p_errorf(struct lib9p_ctx *ctx, uint32_t linux_errno, char const *fmt, . * * @return required size, or -1 on error * - * @errno LINUX_EBADMSG: message is too short for content + * @errno LINUX_EBADMSG: message is wrong size for content * @errno LINUX_EBADMSG: message contains invalid UTF-8 + * @errno LINUX_EBADMSG: message contains a bitfield with unknown bits + * @errno LINUX_EMSGSIZE: would-be return value overflows SSIZE_MAX */ -ssize_t lib9p_unmarshal_size(struct lib9p_ctx *ctx, uint8_t *net_bytes); +ssize_t lib9p_validate(struct lib9p_ctx *ctx, uint8_t *net_bytes); /** * Unmarshal the 9P message `net_bytes` into the C struct `ret_body`. @@ -55,13 +60,13 @@ ssize_t lib9p_unmarshal_size(struct lib9p_ctx *ctx, uint8_t *net_bytes); * * @return ret_typ : the mesage type * @return ret_tag : the message-ID tag - * @return ret_body : the message body, must be at least lib9p_unmarshal_size() bytes + * @return ret_body : the message body, must be at least lib9p_validate() bytes */ void lib9p_unmarshal(struct lib9p_ctx *ctx, uint8_t *net_bytes, enum lib9p_msg_type *ret_typ, uint16_t *ret_tag, void *ret_body); /** - * Marshal a `struct lib9p_msg_{typ}` structure into a byte-array. + * Marshal a `struct lib9p_msg_{typ}` structure into a byte-array. * * @param ctx : negotiated protocol parameters, where to record errors * @param typ : the message type diff --git a/lib9p/internal.h b/lib9p/internal.h index d1da014..d1c36cf 100644 --- a/lib9p/internal.h +++ b/lib9p/internal.h @@ -17,7 +17,8 @@ #define USE_CONFIG_COROUTINE #include "config.h" static_assert(CONFIG_9P_MAX_ERR_SIZE <= UINT16_MAX); -static_assert(CONFIG_9P_MAX_MSG_SIZE <= SSIZE_MAX); +static_assert(CONFIG_9P_MAX_MSG_SIZE <= CONFIG_9P_MAX_HOSTMSG_SIZE); +static_assert(CONFIG_9P_MAX_HOSTMSG_SIZE <= SSIZE_MAX); static_assert(CONFIG_9P_MAX_ERR_SIZE + CONFIG_9P_MAX_MSG_SIZE + 2*CONFIG_9P_MAX_HOSTMSG_SIZE < CONFIG_COROUTINE_DEFAULT_STACK_SIZE); /* C language *****************************************************************/ @@ -43,7 +44,7 @@ struct lib9p_ctx { /* vtables ********************************************************************/ -struct _checksize_ctx { +struct _validate_ctx { struct lib9p_ctx *ctx; uint32_t net_size; uint8_t *net_bytes; @@ -53,7 +54,7 @@ struct _checksize_ctx { * "extra" beyond sizeof(). */ size_t host_extra; }; -typedef bool (*_checksize_fn_t)(struct _checksize_ctx *ctx); +typedef bool (*_validate_fn_t)(struct _validate_ctx *ctx); struct _unmarshal_ctx { struct lib9p_ctx *ctx; @@ -74,8 +75,8 @@ struct _marshal_ctx { typedef bool (*_marshal_fn_t)(struct _marshal_ctx *ctx, void *host_val); struct _vtable_msg { - size_t unmarshal_basesize; - _checksize_fn_t unmarshal_extrasize; + size_t basesize; + _validate_fn_t validate; _unmarshal_fn_t unmarshal; _marshal_fn_t marshal; }; diff --git a/lib9p/types.c b/lib9p/types.c index c4812d1..8582161 100644 --- a/lib9p/types.c +++ b/lib9p/types.c @@ -288,9 +288,9 @@ const char *lib9p_msg_type_str(enum lib9p_msg_type typ) { return msg_type_strs[typ]; } -/* checksize_* (internals of unmarshal_size()) ********************************/ +/* validate_* *****************************************************************/ -static ALWAYS_INLINE bool _checksize_net(struct _checksize_ctx *ctx, uint32_t n) { +static ALWAYS_INLINE bool _validate_size_net(struct _validate_ctx *ctx, uint32_t n) { if (__builtin_add_overflow(ctx->net_offset, n, &ctx->net_offset)) /* If needed-net-size overflowed uint32_t, then * there's no way that actual-net-size will live up to @@ -301,7 +301,7 @@ static ALWAYS_INLINE bool _checksize_net(struct _checksize_ctx *ctx, uint32_t n) return false; } -static ALWAYS_INLINE bool _checksize_host(struct _checksize_ctx *ctx, size_t n) { +static ALWAYS_INLINE bool _validate_size_host(struct _validate_ctx *ctx, size_t n) { if (__builtin_add_overflow(ctx->host_extra, n, &ctx->host_extra)) /* If needed-host-size overflowed size_t, then there's * no way that actual-net-size will live up to @@ -310,223 +310,223 @@ static ALWAYS_INLINE bool _checksize_host(struct _checksize_ctx *ctx, size_t n) return false; } -static ALWAYS_INLINE bool _checksize_list(struct _checksize_ctx *ctx, - size_t cnt, _checksize_fn_t item_fn, size_t item_host_size) { +static ALWAYS_INLINE bool _validate_list(struct _validate_ctx *ctx, + size_t cnt, _validate_fn_t item_fn, size_t item_host_size) { for (size_t i = 0; i < cnt; i++) - if (_checksize_host(ctx, item_host_size) || item_fn(ctx)) + if (_validate_size_host(ctx, item_host_size) || item_fn(ctx)) return true; return false; } -#define checksize_1(ctx) _checksize_net(ctx, 1) -#define checksize_2(ctx) _checksize_net(ctx, 2) -#define checksize_4(ctx) _checksize_net(ctx, 4) -#define checksize_8(ctx) _checksize_net(ctx, 8) +#define validate_1(ctx) _validate_size_net(ctx, 1) +#define validate_2(ctx) _validate_size_net(ctx, 2) +#define validate_4(ctx) _validate_size_net(ctx, 4) +#define validate_8(ctx) _validate_size_net(ctx, 8) -static ALWAYS_INLINE bool checksize_d(struct _checksize_ctx *ctx) { +static ALWAYS_INLINE bool validate_d(struct _validate_ctx *ctx) { uint32_t base_offset = ctx->net_offset; - if (checksize_4(ctx)) + if (validate_4(ctx)) return true; uint32_t len = decode_u32le(&ctx->net_bytes[base_offset]); - return _checksize_net(ctx, len) || _checksize_host(ctx, len); + return _validate_size_net(ctx, len) || _validate_size_host(ctx, len); } -static ALWAYS_INLINE bool checksize_s(struct _checksize_ctx *ctx) { +static ALWAYS_INLINE bool validate_s(struct _validate_ctx *ctx) { uint32_t base_offset = ctx->net_offset; - if (checksize_2(ctx)) + if (validate_2(ctx)) return true; uint16_t len = decode_u16le(&ctx->net_bytes[base_offset]); - if (_checksize_net(ctx, len) || _checksize_host(ctx, ((size_t)len)+1)) + if (_validate_size_net(ctx, len) || _validate_size_host(ctx, ((size_t)len)+1)) return true; if (!is_valid_utf8_without_nul(&ctx->net_bytes[base_offset+2], len)) return lib9p_error(ctx->ctx, LINUX_EBADMSG, "message contains invalid UTF-8"); return false; } -static ALWAYS_INLINE bool checksize_qid(struct _checksize_ctx *ctx) { - return checksize_qt(ctx) - || checksize_4(ctx) - || checksize_8(ctx); +static ALWAYS_INLINE bool validate_qid(struct _validate_ctx *ctx) { + return validate_qt(ctx) + || validate_4(ctx) + || validate_8(ctx); } -static ALWAYS_INLINE bool checksize_stat(struct _checksize_ctx *ctx) { - return checksize_2(ctx) - || checksize_2(ctx) - || checksize_4(ctx) - || checksize_qid(ctx) - || checksize_4(ctx) - || checksize_4(ctx) - || checksize_4(ctx) - || checksize_8(ctx) - || checksize_s(ctx) - || checksize_s(ctx) - || checksize_s(ctx) - || checksize_s(ctx) - || ( (ctx->ctx->version==LIB9P_VER_9P2000_u) && checksize_s(ctx) ) - || ( (ctx->ctx->version==LIB9P_VER_9P2000_u) && checksize_4(ctx) ) - || ( (ctx->ctx->version==LIB9P_VER_9P2000_u) && checksize_4(ctx) ) - || ( (ctx->ctx->version==LIB9P_VER_9P2000_u) && checksize_4(ctx) ); +static ALWAYS_INLINE bool validate_stat(struct _validate_ctx *ctx) { + return validate_2(ctx) + || validate_2(ctx) + || validate_4(ctx) + || validate_qid(ctx) + || validate_4(ctx) + || validate_4(ctx) + || validate_4(ctx) + || validate_8(ctx) + || validate_s(ctx) + || validate_s(ctx) + || validate_s(ctx) + || validate_s(ctx) + || ( (ctx->ctx->version==LIB9P_VER_9P2000_u) && validate_s(ctx) ) + || ( (ctx->ctx->version==LIB9P_VER_9P2000_u) && validate_4(ctx) ) + || ( (ctx->ctx->version==LIB9P_VER_9P2000_u) && validate_4(ctx) ) + || ( (ctx->ctx->version==LIB9P_VER_9P2000_u) && validate_4(ctx) ); } -static FLATTEN bool checksize_Tversion(struct _checksize_ctx *ctx) { - return checksize_4(ctx) - || checksize_s(ctx); +static FLATTEN bool validate_Tversion(struct _validate_ctx *ctx) { + return validate_4(ctx) + || validate_s(ctx); } -static FLATTEN bool checksize_Rversion(struct _checksize_ctx *ctx) { - return checksize_4(ctx) - || checksize_s(ctx); +static FLATTEN bool validate_Rversion(struct _validate_ctx *ctx) { + return validate_4(ctx) + || validate_s(ctx); } -static FLATTEN bool checksize_Tauth(struct _checksize_ctx *ctx) { - return checksize_4(ctx) - || checksize_s(ctx) - || checksize_s(ctx) - || ( (ctx->ctx->version==LIB9P_VER_9P2000_u) && checksize_4(ctx) ); +static FLATTEN bool validate_Tauth(struct _validate_ctx *ctx) { + return validate_4(ctx) + || validate_s(ctx) + || validate_s(ctx) + || ( (ctx->ctx->version==LIB9P_VER_9P2000_u) && validate_4(ctx) ); } -static FLATTEN bool checksize_Rauth(struct _checksize_ctx *ctx) { - return checksize_qid(ctx); +static FLATTEN bool validate_Rauth(struct _validate_ctx *ctx) { + return validate_qid(ctx); } -static FLATTEN bool checksize_Tattach(struct _checksize_ctx *ctx) { - return checksize_4(ctx) - || checksize_4(ctx) - || checksize_s(ctx) - || checksize_s(ctx); +static FLATTEN bool validate_Tattach(struct _validate_ctx *ctx) { + return validate_4(ctx) + || validate_4(ctx) + || validate_s(ctx) + || validate_s(ctx); } -static FLATTEN bool checksize_Rattach(struct _checksize_ctx *ctx) { - return checksize_qid(ctx); +static FLATTEN bool validate_Rattach(struct _validate_ctx *ctx) { + return validate_qid(ctx); } -static FLATTEN bool checksize_Rerror(struct _checksize_ctx *ctx) { - return checksize_s(ctx) - || ( (ctx->ctx->version==LIB9P_VER_9P2000_u) && checksize_4(ctx) ); +static FLATTEN bool validate_Rerror(struct _validate_ctx *ctx) { + return validate_s(ctx) + || ( (ctx->ctx->version==LIB9P_VER_9P2000_u) && validate_4(ctx) ); } -static FLATTEN bool checksize_Tflush(struct _checksize_ctx *ctx) { - return checksize_2(ctx); +static FLATTEN bool validate_Tflush(struct _validate_ctx *ctx) { + return validate_2(ctx); } -static FLATTEN bool checksize_Rflush(struct _checksize_ctx *UNUSED(ctx)) { +static FLATTEN bool validate_Rflush(struct _validate_ctx *UNUSED(ctx)) { return false; } -static FLATTEN bool checksize_Twalk(struct _checksize_ctx *ctx) { - return checksize_4(ctx) - || checksize_4(ctx) - || checksize_2(ctx) - || _checksize_list(ctx, decode_u16le(&ctx->net_bytes[ctx->net_offset-2]), checksize_s, sizeof(struct lib9p_s)); +static FLATTEN bool validate_Twalk(struct _validate_ctx *ctx) { + return validate_4(ctx) + || validate_4(ctx) + || validate_2(ctx) + || _validate_list(ctx, decode_u16le(&ctx->net_bytes[ctx->net_offset-2]), validate_s, sizeof(struct lib9p_s)); } -static FLATTEN bool checksize_Rwalk(struct _checksize_ctx *ctx) { - return checksize_2(ctx) - || _checksize_list(ctx, decode_u16le(&ctx->net_bytes[ctx->net_offset-2]), checksize_qid, sizeof(struct lib9p_qid)); +static FLATTEN bool validate_Rwalk(struct _validate_ctx *ctx) { + return validate_2(ctx) + || _validate_list(ctx, decode_u16le(&ctx->net_bytes[ctx->net_offset-2]), validate_qid, sizeof(struct lib9p_qid)); } -static FLATTEN bool checksize_Topen(struct _checksize_ctx *ctx) { - return checksize_4(ctx) - || checksize_1(ctx); +static FLATTEN bool validate_Topen(struct _validate_ctx *ctx) { + return validate_4(ctx) + || validate_1(ctx); } -static FLATTEN bool checksize_Ropen(struct _checksize_ctx *ctx) { - return checksize_qid(ctx) - || checksize_4(ctx); +static FLATTEN bool validate_Ropen(struct _validate_ctx *ctx) { + return validate_qid(ctx) + || validate_4(ctx); } -static FLATTEN bool checksize_Tcreate(struct _checksize_ctx *ctx) { - return checksize_4(ctx) - || checksize_s(ctx) - || checksize_4(ctx) - || checksize_1(ctx); +static FLATTEN bool validate_Tcreate(struct _validate_ctx *ctx) { + return validate_4(ctx) + || validate_s(ctx) + || validate_4(ctx) + || validate_1(ctx); } -static FLATTEN bool checksize_Rcreate(struct _checksize_ctx *ctx) { - return checksize_qid(ctx) - || checksize_4(ctx); +static FLATTEN bool validate_Rcreate(struct _validate_ctx *ctx) { + return validate_qid(ctx) + || validate_4(ctx); } -static FLATTEN bool checksize_Tread(struct _checksize_ctx *ctx) { - return checksize_4(ctx) - || checksize_8(ctx) - || checksize_4(ctx); +static FLATTEN bool validate_Tread(struct _validate_ctx *ctx) { + return validate_4(ctx) + || validate_8(ctx) + || validate_4(ctx); } -static FLATTEN bool checksize_Rread(struct _checksize_ctx *ctx) { - return checksize_d(ctx); +static FLATTEN bool validate_Rread(struct _validate_ctx *ctx) { + return validate_d(ctx); } -static FLATTEN bool checksize_Twrite(struct _checksize_ctx *ctx) { - return checksize_4(ctx) - || checksize_8(ctx) - || checksize_d(ctx); +static FLATTEN bool validate_Twrite(struct _validate_ctx *ctx) { + return validate_4(ctx) + || validate_8(ctx) + || validate_d(ctx); } -static FLATTEN bool checksize_Rwrite(struct _checksize_ctx *ctx) { - return checksize_4(ctx); +static FLATTEN bool validate_Rwrite(struct _validate_ctx *ctx) { + return validate_4(ctx); } -static FLATTEN bool checksize_Tclunk(struct _checksize_ctx *ctx) { - return checksize_4(ctx); +static FLATTEN bool validate_Tclunk(struct _validate_ctx *ctx) { + return validate_4(ctx); } -static FLATTEN bool checksize_Rclunk(struct _checksize_ctx *UNUSED(ctx)) { +static FLATTEN bool validate_Rclunk(struct _validate_ctx *UNUSED(ctx)) { return false; } -static FLATTEN bool checksize_Tremove(struct _checksize_ctx *ctx) { - return checksize_4(ctx); +static FLATTEN bool validate_Tremove(struct _validate_ctx *ctx) { + return validate_4(ctx); } -static FLATTEN bool checksize_Rremove(struct _checksize_ctx *UNUSED(ctx)) { +static FLATTEN bool validate_Rremove(struct _validate_ctx *UNUSED(ctx)) { return false; } -static FLATTEN bool checksize_Tstat(struct _checksize_ctx *ctx) { - return checksize_4(ctx); +static FLATTEN bool validate_Tstat(struct _validate_ctx *ctx) { + return validate_4(ctx); } -static FLATTEN bool checksize_Rstat(struct _checksize_ctx *ctx) { - return checksize_stat(ctx); +static FLATTEN bool validate_Rstat(struct _validate_ctx *ctx) { + return validate_stat(ctx); } -static FLATTEN bool checksize_Twstat(struct _checksize_ctx *ctx) { - return checksize_4(ctx) - || checksize_stat(ctx); +static FLATTEN bool validate_Twstat(struct _validate_ctx *ctx) { + return validate_4(ctx) + || validate_stat(ctx); } -static FLATTEN bool checksize_Rwstat(struct _checksize_ctx *UNUSED(ctx)) { +static FLATTEN bool validate_Rwstat(struct _validate_ctx *UNUSED(ctx)) { return false; } -static FLATTEN bool checksize_Tsession(struct _checksize_ctx *ctx) { - return checksize_8(ctx); +static FLATTEN bool validate_Tsession(struct _validate_ctx *ctx) { + return validate_8(ctx); } -static FLATTEN bool checksize_Rsession(struct _checksize_ctx *UNUSED(ctx)) { +static FLATTEN bool validate_Rsession(struct _validate_ctx *UNUSED(ctx)) { return false; } -static FLATTEN bool checksize_Tsread(struct _checksize_ctx *ctx) { - return checksize_4(ctx) - || checksize_2(ctx) - || _checksize_list(ctx, decode_u16le(&ctx->net_bytes[ctx->net_offset-2]), checksize_s, sizeof(struct lib9p_s)); +static FLATTEN bool validate_Tsread(struct _validate_ctx *ctx) { + return validate_4(ctx) + || validate_2(ctx) + || _validate_list(ctx, decode_u16le(&ctx->net_bytes[ctx->net_offset-2]), validate_s, sizeof(struct lib9p_s)); } -static FLATTEN bool checksize_Rsread(struct _checksize_ctx *ctx) { - return checksize_d(ctx); +static FLATTEN bool validate_Rsread(struct _validate_ctx *ctx) { + return validate_d(ctx); } -static FLATTEN bool checksize_Tswrite(struct _checksize_ctx *ctx) { - return checksize_4(ctx) - || checksize_2(ctx) - || _checksize_list(ctx, decode_u16le(&ctx->net_bytes[ctx->net_offset-2]), checksize_s, sizeof(struct lib9p_s)) - || checksize_d(ctx); +static FLATTEN bool validate_Tswrite(struct _validate_ctx *ctx) { + return validate_4(ctx) + || validate_2(ctx) + || _validate_list(ctx, decode_u16le(&ctx->net_bytes[ctx->net_offset-2]), validate_s, sizeof(struct lib9p_s)) + || validate_d(ctx); } -static FLATTEN bool checksize_Rswrite(struct _checksize_ctx *ctx) { - return checksize_4(ctx); +static FLATTEN bool validate_Rswrite(struct _validate_ctx *ctx) { + return validate_4(ctx); } /* unmarshal_* ****************************************************************/ @@ -1067,11 +1067,11 @@ static FLATTEN bool marshal_Rswrite(struct _marshal_ctx *ctx, struct lib9p_msg_R /* vtables ********************************************************************/ -#define _MSG(typ) [LIB9P_TYP_##typ] = { \ - .unmarshal_basesize = sizeof(struct lib9p_msg_##typ), \ - .unmarshal_extrasize = checksize_##typ, \ - .unmarshal = (_unmarshal_fn_t)unmarshal_##typ, \ - .marshal = (_marshal_fn_t)marshal_##typ, \ +#define _MSG(typ) [LIB9P_TYP_##typ] = { \ + .basesize = sizeof(struct lib9p_msg_##typ), \ + .validate = validate_##typ, \ + .unmarshal = (_unmarshal_fn_t)unmarshal_##typ, \ + .marshal = (_marshal_fn_t)marshal_##typ, \ } struct _vtable_version _lib9p_vtables[LIB9P_VER_NUM] = { diff --git a/lib9p/types.gen b/lib9p/types.gen index 7d74558..a594e45 100755 --- a/lib9p/types.gen +++ b/lib9p/types.gen @@ -468,11 +468,11 @@ const char *{idprefix}msg_type_str(enum {idprefix}msg_type typ) {{ }} """ - # checksize_* ############################################################## + # validate_* ############################################################### ret += """ -/* checksize_* (internals of unmarshal_size()) ********************************/ +/* validate_* *****************************************************************/ -static ALWAYS_INLINE bool _checksize_net(struct _checksize_ctx *ctx, uint32_t n) { +static ALWAYS_INLINE bool _validate_size_net(struct _validate_ctx *ctx, uint32_t n) { if (__builtin_add_overflow(ctx->net_offset, n, &ctx->net_offset)) /* If needed-net-size overflowed uint32_t, then * there's no way that actual-net-size will live up to @@ -483,7 +483,7 @@ static ALWAYS_INLINE bool _checksize_net(struct _checksize_ctx *ctx, uint32_t n) return false; } -static ALWAYS_INLINE bool _checksize_host(struct _checksize_ctx *ctx, size_t n) { +static ALWAYS_INLINE bool _validate_size_host(struct _validate_ctx *ctx, size_t n) { if (__builtin_add_overflow(ctx->host_extra, n, &ctx->host_extra)) /* If needed-host-size overflowed size_t, then there's * no way that actual-net-size will live up to @@ -492,24 +492,24 @@ static ALWAYS_INLINE bool _checksize_host(struct _checksize_ctx *ctx, size_t n) return false; } -static ALWAYS_INLINE bool _checksize_list(struct _checksize_ctx *ctx, - size_t cnt, _checksize_fn_t item_fn, size_t item_host_size) { +static ALWAYS_INLINE bool _validate_list(struct _validate_ctx *ctx, + size_t cnt, _validate_fn_t item_fn, size_t item_host_size) { for (size_t i = 0; i < cnt; i++) - if (_checksize_host(ctx, item_host_size) || item_fn(ctx)) + if (_validate_size_host(ctx, item_host_size) || item_fn(ctx)) return true; return false; } -#define checksize_1(ctx) _checksize_net(ctx, 1) -#define checksize_2(ctx) _checksize_net(ctx, 2) -#define checksize_4(ctx) _checksize_net(ctx, 4) -#define checksize_8(ctx) _checksize_net(ctx, 8) +#define validate_1(ctx) _validate_size_net(ctx, 1) +#define validate_2(ctx) _validate_size_net(ctx, 2) +#define validate_4(ctx) _validate_size_net(ctx, 4) +#define validate_8(ctx) _validate_size_net(ctx, 8) """ for struct in just_structs_all(typs): inline = " ALWAYS_INLINE" if struct.msgid is None else " FLATTEN" argfn = used if struct.members else unused ret += "\n" - ret += f"static{inline} bool checksize_{struct.name}(struct _checksize_ctx *{argfn('ctx')}) {{" + ret += f"static{inline} bool validate_{struct.name}(struct _validate_ctx *{argfn('ctx')}) {{" if len(struct.members) == 0: ret += "\n\treturn false;\n" ret += "}\n" @@ -520,10 +520,10 @@ static ALWAYS_INLINE bool _checksize_list(struct _checksize_ctx *ctx, # this, but let's make it obvious. ret += "\n" ret += "\tuint32_t base_offset = ctx->net_offset;\n" - ret += "\tif (checksize_4(ctx))\n" + ret += "\tif (validate_4(ctx))\n" ret += "\t\treturn true;\n" ret += "\tuint32_t len = decode_u32le(&ctx->net_bytes[base_offset]);\n" - ret += "\treturn _checksize_net(ctx, len) || _checksize_host(ctx, len);\n" + ret += "\treturn _validate_size_net(ctx, len) || _validate_size_host(ctx, len);\n" ret += "}\n" continue if struct.name == "s": # SPECIAL @@ -531,10 +531,10 @@ static ALWAYS_INLINE bool _checksize_list(struct _checksize_ctx *ctx, # (also, similar optimization to "d"). ret += "\n" ret += "\tuint32_t base_offset = ctx->net_offset;\n" - ret += "\tif (checksize_2(ctx))\n" + ret += "\tif (validate_2(ctx))\n" ret += "\t\treturn true;\n" ret += "\tuint16_t len = decode_u16le(&ctx->net_bytes[base_offset]);\n" - ret += "\tif (_checksize_net(ctx, len) || _checksize_host(ctx, ((size_t)len)+1))\n" + ret += "\tif (_validate_size_net(ctx, len) || _validate_size_host(ctx, ((size_t)len)+1))\n" ret += "\t\treturn true;\n" ret += "\tif (!is_valid_utf8_without_nul(&ctx->net_bytes[base_offset+2], len))\n" ret += '\t\treturn lib9p_error(ctx->ctx, LINUX_EBADMSG, "message contains invalid UTF-8");\n' @@ -555,9 +555,9 @@ static ALWAYS_INLINE bool _checksize_list(struct _checksize_ctx *ctx, ret += "( " + c_vercond(idprefix, member.ver) + " && " if member.cnt is not None: assert prev_size - ret += f"_checksize_list(ctx, decode_u{prev_size*8}le(&ctx->net_bytes[ctx->net_offset-{prev_size}]), checksize_{member.typ.name}, sizeof({c_typename(idprefix, member.typ)}))" + ret += f"_validate_list(ctx, decode_u{prev_size*8}le(&ctx->net_bytes[ctx->net_offset-{prev_size}]), validate_{member.typ.name}, sizeof({c_typename(idprefix, member.typ)}))" else: - ret += f"checksize_{member.typ.name}(ctx)" + ret += f"validate_{member.typ.name}(ctx)" if member.ver != struct_versions: ret += " )" prefix = prefix1 @@ -698,11 +698,11 @@ static ALWAYS_INLINE bool marshal_8(struct _marshal_ctx *ctx, uint64_t *val) { ret += f""" /* vtables ********************************************************************/ -#define _MSG(typ) [{idprefix.upper()}TYP_##typ] = {{ \\ - .unmarshal_basesize = sizeof(struct {idprefix}msg_##typ), \\ - .unmarshal_extrasize = checksize_##typ, \\ - .unmarshal = (_unmarshal_fn_t)unmarshal_##typ, \\ - .marshal = (_marshal_fn_t)marshal_##typ, \\ +#define _MSG(typ) [{idprefix.upper()}TYP_##typ] = {{ \\ + .basesize = sizeof(struct {idprefix}msg_##typ), \\ + .validate = validate_##typ, \\ + .unmarshal = (_unmarshal_fn_t)unmarshal_##typ, \\ + .marshal = (_marshal_fn_t)marshal_##typ, \\ }} struct _vtable_version _{idprefix}vtables[{c_verenum(idprefix, 'NUM')}] = {{ |