summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke T. Shumaker <lukeshu@lukeshu.com>2025-04-21 17:28:01 -0600
committerLuke T. Shumaker <lukeshu@lukeshu.com>2025-04-21 17:28:49 -0600
commit1a55efa8be3769d9e31724be31db8f967813133d (patch)
tree8028357729649fcf8678c69b63342aa13c34e635
parent05f170fc9382dc619a6a3f7ea22c423456a96580 (diff)
lib9p_srv: Cap Tread->count
-rw-r--r--lib9p/core.c9
-rw-r--r--lib9p/core_gen/c.py15
-rw-r--r--lib9p/core_generated.c12
-rw-r--r--lib9p/core_include/lib9p/core.h3
-rw-r--r--lib9p/core_tables.h3
-rw-r--r--lib9p/srv.c16
6 files changed, 33 insertions, 25 deletions
diff --git a/lib9p/core.c b/lib9p/core.c
index adf7ecf..03cdea5 100644
--- a/lib9p/core.c
+++ b/lib9p/core.c
@@ -125,9 +125,14 @@ const char *lib9p_version_str(enum lib9p_version ver) {
return _lib9p_table_ver[ver].name;
}
-uint32_t lib9p_version_min_msg_size(enum lib9p_version ver) {
+uint32_t lib9p_version_min_Rerror_size(enum lib9p_version ver) {
assert_ver(ver);
- return _lib9p_table_ver[ver].min_msg_size;
+ return _lib9p_table_ver[ver].min_Rerror_size;
+}
+
+uint32_t lib9p_version_min_Rread_size(enum lib9p_version ver) {
+ assert_ver(ver);
+ return _lib9p_table_ver[ver].min_Rread_size;
}
const char *lib9p_msgtype_str(enum lib9p_version ver, enum lib9p_msg_type typ) {
diff --git a/lib9p/core_gen/c.py b/lib9p/core_gen/c.py
index 998031b..b0ff871 100644
--- a/lib9p/core_gen/c.py
+++ b/lib9p/core_gen/c.py
@@ -123,18 +123,15 @@ def gen_c(versions: set[str], typs: list[idl.UserType]) -> str:
ret += "\n"
ret += f"const struct {c9util.ident('_ver_tentry')} {c9util.ident('_table_ver')}[{c9util.ver_enum('NUM')}] = {{\n"
rerror = next(typ for typ in typs if typ.typname == "Rerror")
+ rlerror = next(typ for typ in typs if typ.typname == "Rlerror")
+ rread = next(typ for typ in typs if typ.typname == "Rread")
for ver in sorted(versions):
- # XXX: There are good arguments that min_msg_size should be
- # something larger than rerror.min_size().
- # srv.c:respond_error() assumes that min_msg_size is
- # rerror.min_size(); if you do change min_msg_size to
- # something larger, then be sure to update respond_error().
ret += cutil.ifdef_push(1, c9util.ver_ifdef({ver}))
- min_msg_size = rerror.min_size(ver)
+ min_rerror_size = rerror.min_size(ver)
if ver == "9P2000.L": # SPECIAL (9P2000.L)
- rlerror = next(typ for typ in typs if typ.typname == "Rlerror")
- min_msg_size = rlerror.min_size(ver)
- ret += f'\t[{c9util.ver_enum(ver)}] = {{.name="{ver}", .min_msg_size={min_msg_size}}},\n'
+ min_rerror_size = rlerror.min_size(ver)
+ min_rread_size = rread.min_size(ver)
+ ret += f'\t[{c9util.ver_enum(ver)}] = {{.name="{ver}", .min_Rerror_size={min_rerror_size}, .min_Rread_size={min_rread_size}}},\n'
ret += cutil.ifdef_pop(0)
ret += "};\n"
diff --git a/lib9p/core_generated.c b/lib9p/core_generated.c
index 4d9ba6a..1de7c67 100644
--- a/lib9p/core_generated.c
+++ b/lib9p/core_generated.c
@@ -7851,22 +7851,22 @@ static void lib9p_msg_Rswrite_format(struct lib9p_msg_Rswrite *self, struct fmt_
const struct _lib9p_ver_tentry _lib9p_table_ver[LIB9P_VER_NUM] = {
#if CONFIG_9P_ENABLE_9P2000
- [LIB9P_VER_9P2000] = {.name="9P2000", .min_msg_size=9},
+ [LIB9P_VER_9P2000] = {.name="9P2000", .min_Rerror_size=9, .min_Rread_size=11},
#endif /* CONFIG_9P_ENABLE_9P2000 */
#if CONFIG_9P_ENABLE_9P2000_L
- [LIB9P_VER_9P2000_L] = {.name="9P2000.L", .min_msg_size=11},
+ [LIB9P_VER_9P2000_L] = {.name="9P2000.L", .min_Rerror_size=11, .min_Rread_size=11},
#endif /* CONFIG_9P_ENABLE_9P2000_L */
#if CONFIG_9P_ENABLE_9P2000_e
- [LIB9P_VER_9P2000_e] = {.name="9P2000.e", .min_msg_size=9},
+ [LIB9P_VER_9P2000_e] = {.name="9P2000.e", .min_Rerror_size=9, .min_Rread_size=11},
#endif /* CONFIG_9P_ENABLE_9P2000_e */
#if CONFIG_9P_ENABLE_9P2000_p9p
- [LIB9P_VER_9P2000_p9p] = {.name="9P2000.p9p", .min_msg_size=9},
+ [LIB9P_VER_9P2000_p9p] = {.name="9P2000.p9p", .min_Rerror_size=9, .min_Rread_size=11},
#endif /* CONFIG_9P_ENABLE_9P2000_p9p */
#if CONFIG_9P_ENABLE_9P2000_u
- [LIB9P_VER_9P2000_u] = {.name="9P2000.u", .min_msg_size=13},
+ [LIB9P_VER_9P2000_u] = {.name="9P2000.u", .min_Rerror_size=13, .min_Rread_size=11},
#endif /* CONFIG_9P_ENABLE_9P2000_u */
#if CONFIG_9P_ENABLE_uninitialized
- [LIB9P_VER_uninitialized] = {.name="uninitialized", .min_msg_size=9},
+ [LIB9P_VER_uninitialized] = {.name="uninitialized", .min_Rerror_size=9, .min_Rread_size=0},
#endif /* CONFIG_9P_ENABLE_uninitialized */
};
diff --git a/lib9p/core_include/lib9p/core.h b/lib9p/core_include/lib9p/core.h
index b6d149b..549411f 100644
--- a/lib9p/core_include/lib9p/core.h
+++ b/lib9p/core_include/lib9p/core.h
@@ -77,7 +77,8 @@ bool lib9p_ctx_has_error(struct lib9p_ctx *ctx);
/* misc utilities *************************************************************/
-uint32_t lib9p_version_min_msg_size(enum lib9p_version);
+uint32_t lib9p_version_min_Rerror_size(enum lib9p_version);
+uint32_t lib9p_version_min_Rread_size(enum lib9p_version);
lo_interface fmt_formatter lo_box_lib9p_msg_as_fmt_formatter(struct lib9p_ctx *ctx, enum lib9p_msg_type typ, void *body);
diff --git a/lib9p/core_tables.h b/lib9p/core_tables.h
index 17e9398..da2027a 100644
--- a/lib9p/core_tables.h
+++ b/lib9p/core_tables.h
@@ -13,7 +13,8 @@
struct _lib9p_ver_tentry {
const char *name;
- uint32_t min_msg_size;
+ uint32_t min_Rerror_size;
+ uint32_t min_Rread_size;
};
extern const struct _lib9p_ver_tentry _lib9p_table_ver[LIB9P_VER_NUM];
diff --git a/lib9p/srv.c b/lib9p/srv.c
index befeb6a..6d9d992 100644
--- a/lib9p/srv.c
+++ b/lib9p/srv.c
@@ -393,10 +393,7 @@ static void srv_respond_error(struct srv_req *req) {
struct srv_sess *sess = req->parent_sess;
- /* XXX: This assumes that a version's min_msg_size is the
- * Rerror overhead. That's true for the current
- * implementation of core_gen, but is a sneaky assumption. */
- uint32_t overhead = lib9p_version_min_msg_size(sess->version);
+ uint32_t overhead = lib9p_version_min_Rerror_size(sess->version);
/* Truncate the error-string if necessary to avoid needing to
* return LIB9P_ERRNO_L_ERANGE. */
@@ -748,7 +745,11 @@ static void handle_Tversion(struct srv_req *ctx,
#endif
}
- uint32_t min_msg_size = lib9p_version_min_msg_size(version);
+ /* XXX: There are good arguments that min_msg_size should be
+ * something larger than max(rerror.min_size(),
+ * rread.min_size()+1). */
+ uint32_t min_msg_size = _LIB9P_MAX(lib9p_version_min_Rerror_size(ctx->basectx.version),
+ lib9p_version_min_Rread_size(ctx->basectx.version)+1);
if (req->max_msg_size < min_msg_size) {
lib9p_errorf(&ctx->basectx,
LIB9P_ERRNO_L_EDOM, "requested max_msg_size is less than minimum for %s (%"PRIu32" < %"PRIu32")",
@@ -1175,6 +1176,9 @@ static void handle_Tread(struct srv_req *ctx,
/* TODO: serialize simultaneous reads to the same FID */
+ if (req->count > ctx->basectx.max_msg_size - lib9p_version_min_Rread_size(ctx->basectx.version))
+ req->count = ctx->basectx.max_msg_size - lib9p_version_min_Rread_size(ctx->basectx.version);
+
/* Check that the FID is valid for this. */
struct srv_fidinfo *fidinfo = map_load(&ctx->parent_sess->fids, req->fid);
if (!fidinfo) {
@@ -1205,7 +1209,7 @@ static void handle_Tread(struct srv_req *ctx,
goto tread_return;
}
/* Read. */
- resp.data = heap = malloc(req->count); /* TODO: cap req->count */
+ resp.data = heap = malloc(req->count);
resp.count = 0;
struct srv_pathinfo *dir_pathinfo = NULL;
for (;;) {