summaryrefslogtreecommitdiff
path: root/lib9p
diff options
context:
space:
mode:
authorLuke T. Shumaker <lukeshu@lukeshu.com>2024-10-02 13:12:16 -0600
committerLuke T. Shumaker <lukeshu@lukeshu.com>2024-10-02 13:19:04 -0600
commitfa7f6a5176a386f8847810f34538d5c0e56f0fb1 (patch)
treeebcab0fd2b7936a53c77ad7c6614f548b0436103 /lib9p
parent50cfe77ace4caa424352a163f90bbf7a684b60d6 (diff)
lib9p: Rename checksize to validate
Diffstat (limited to 'lib9p')
-rw-r--r--lib9p/9p.c20
-rw-r--r--lib9p/include/lib9p/9p.h19
-rw-r--r--lib9p/internal.h11
-rw-r--r--lib9p/types.c264
-rwxr-xr-xlib9p/types.gen46
5 files changed, 187 insertions, 173 deletions
diff --git a/lib9p/9p.c b/lib9p/9p.c
index 90a2b0d..e1303bd 100644
--- a/lib9p/9p.c
+++ b/lib9p/9p.c
@@ -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')}] = {{