diff options
author | Luke T. Shumaker <lukeshu@lukeshu.com> | 2025-01-12 21:10:34 -0700 |
---|---|---|
committer | Luke T. Shumaker <lukeshu@lukeshu.com> | 2025-01-14 20:01:31 -0700 |
commit | e1994d3d3f2bb80d039d0db567706e0739161e79 (patch) | |
tree | d5345e23564d3154b6ecb2abe2781ffbe563a2d1 | |
parent | 68a9773683ae975f03cac9f327c729b3149f2689 (diff) |
lib9p: Limit count and offset to INT{32,64}_MAX
-rw-r--r-- | lib9p/9p.generated.c | 167 | ||||
-rwxr-xr-x | lib9p/idl.gen | 16 | ||||
-rw-r--r-- | lib9p/idl/0000-README.md | 4 | ||||
-rw-r--r-- | lib9p/idl/1995-9P1.9p.wip | 4 | ||||
-rw-r--r-- | lib9p/idl/2002-9P2000.9p | 15 | ||||
-rw-r--r-- | lib9p/idl/__init__.py | 2 |
6 files changed, 116 insertions, 92 deletions
diff --git a/lib9p/9p.generated.c b/lib9p/9p.generated.c index 984ba7f..6757134 100644 --- a/lib9p/9p.generated.c +++ b/lib9p/9p.generated.c @@ -189,8 +189,8 @@ LM_ALWAYS_INLINE static bool validate_stat(struct _validate_ctx *ctx) { || ( (ctx->ctx->version==LIB9P_VER_9P2000_u) && validate_4(ctx) ) || ( (ctx->ctx->version==LIB9P_VER_9P2000_u) && validate_4(ctx) ) #endif /* CONFIG_9P_ENABLE_9P2000_u */ - || ({ uint32_t exp = ctx->net_offset - _kern_type_offset; (((uint32_t)stat_size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "stat_size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)stat_size, exp); }) + || ({ uint16_t exp = ctx->net_offset - _kern_type_offset; (((uint16_t)stat_size) != exp) && + lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "stat_size value is wrong (actual:%"PRIu16" != correct:%"PRIu16")", (uint16_t)stat_size, exp); }) ; } @@ -216,8 +216,8 @@ LM_FLATTEN static bool validate_Tversion(struct _validate_ctx *ctx) { || validate_s(ctx) || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint32_t exp = 100; (((uint32_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); }) + || ({ uint8_t exp = 100; (((uint8_t)typ) != exp) && + lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) ; } @@ -233,8 +233,8 @@ LM_FLATTEN static bool validate_Rversion(struct _validate_ctx *ctx) { || validate_s(ctx) || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint32_t exp = 101; (((uint32_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); }) + || ({ uint8_t exp = 101; (((uint8_t)typ) != exp) && + lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) ; } @@ -254,8 +254,8 @@ LM_FLATTEN static bool validate_Tauth(struct _validate_ctx *ctx) { #endif /* CONFIG_9P_ENABLE_9P2000_u */ || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint32_t exp = 102; (((uint32_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); }) + || ({ uint8_t exp = 102; (((uint8_t)typ) != exp) && + lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) ; } @@ -270,8 +270,8 @@ LM_FLATTEN static bool validate_Rauth(struct _validate_ctx *ctx) { || validate_qid(ctx) || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint32_t exp = 103; (((uint32_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); }) + || ({ uint8_t exp = 103; (((uint8_t)typ) != exp) && + lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) ; } @@ -292,8 +292,8 @@ LM_FLATTEN static bool validate_Tattach(struct _validate_ctx *ctx) { #endif /* CONFIG_9P_ENABLE_9P2000_u */ || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint32_t exp = 104; (((uint32_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); }) + || ({ uint8_t exp = 104; (((uint8_t)typ) != exp) && + lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) ; } @@ -308,8 +308,8 @@ LM_FLATTEN static bool validate_Rattach(struct _validate_ctx *ctx) { || validate_qid(ctx) || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint32_t exp = 105; (((uint32_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); }) + || ({ uint8_t exp = 105; (((uint8_t)typ) != exp) && + lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) ; } @@ -327,8 +327,8 @@ LM_FLATTEN static bool validate_Rerror(struct _validate_ctx *ctx) { #endif /* CONFIG_9P_ENABLE_9P2000_u */ || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint32_t exp = 107; (((uint32_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); }) + || ({ uint8_t exp = 107; (((uint8_t)typ) != exp) && + lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) ; } @@ -343,8 +343,8 @@ LM_FLATTEN static bool validate_Tflush(struct _validate_ctx *ctx) { || validate_2(ctx) || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint32_t exp = 108; (((uint32_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); }) + || ({ uint8_t exp = 108; (((uint8_t)typ) != exp) && + lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) ; } @@ -358,8 +358,8 @@ LM_FLATTEN static bool validate_Rflush(struct _validate_ctx *ctx) { || validate_tag(ctx) || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint32_t exp = 109; (((uint32_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); }) + || ({ uint8_t exp = 109; (((uint8_t)typ) != exp) && + lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) ; } @@ -378,10 +378,10 @@ LM_FLATTEN static bool validate_Twalk(struct _validate_ctx *ctx) { || _validate_list(ctx, decode_u16le(&ctx->net_bytes[ctx->net_offset-2]), validate_s, sizeof(struct lib9p_s)) || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint32_t exp = 110; (((uint32_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); }) - || ({ uint32_t max = 16; (((uint32_t)nwname) > max) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "nwname value is too large (%"PRIu32" > %"PRIu32")", nwname, max); }) + || ({ uint8_t exp = 110; (((uint8_t)typ) != exp) && + lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) + || ({ uint16_t max = 16; (((uint16_t)nwname) > max) && + lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "nwname value is too large (%"PRIu16" > %"PRIu16")", nwname, max); }) ; } @@ -398,10 +398,10 @@ LM_FLATTEN static bool validate_Rwalk(struct _validate_ctx *ctx) { || _validate_list(ctx, decode_u16le(&ctx->net_bytes[ctx->net_offset-2]), validate_qid, sizeof(struct lib9p_qid)) || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint32_t exp = 111; (((uint32_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); }) - || ({ uint32_t max = 16; (((uint32_t)nwqid) > max) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "nwqid value is too large (%"PRIu32" > %"PRIu32")", nwqid, max); }) + || ({ uint8_t exp = 111; (((uint8_t)typ) != exp) && + lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) + || ({ uint16_t max = 16; (((uint16_t)nwqid) > max) && + lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "nwqid value is too large (%"PRIu16" > %"PRIu16")", nwqid, max); }) ; } @@ -417,8 +417,8 @@ LM_FLATTEN static bool validate_Topen(struct _validate_ctx *ctx) { || validate_o(ctx) || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint32_t exp = 112; (((uint32_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); }) + || ({ uint8_t exp = 112; (((uint8_t)typ) != exp) && + lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) ; } @@ -434,8 +434,8 @@ LM_FLATTEN static bool validate_Ropen(struct _validate_ctx *ctx) { || validate_4(ctx) || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint32_t exp = 113; (((uint32_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); }) + || ({ uint8_t exp = 113; (((uint8_t)typ) != exp) && + lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) ; } @@ -453,8 +453,8 @@ LM_FLATTEN static bool validate_Tcreate(struct _validate_ctx *ctx) { || validate_o(ctx) || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint32_t exp = 114; (((uint32_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); }) + || ({ uint8_t exp = 114; (((uint8_t)typ) != exp) && + lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) ; } @@ -470,26 +470,32 @@ LM_FLATTEN static bool validate_Rcreate(struct _validate_ctx *ctx) { || validate_4(ctx) || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint32_t exp = 115; (((uint32_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); }) + || ({ uint8_t exp = 115; (((uint8_t)typ) != exp) && + lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) ; } LM_FLATTEN static bool validate_Tread(struct _validate_ctx *ctx) { uint32_t size; uint8_t typ; + uint64_t offset; + uint32_t count; uint32_t _size_offset; return false || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = decode_u32le(&ctx->net_bytes[ctx->net_offset-4]); false; })) || (validate_1(ctx) || ({ typ = decode_u8le(&ctx->net_bytes[ctx->net_offset-1]); false; })) || validate_tag(ctx) || validate_fid(ctx) - || validate_8(ctx) - || validate_4(ctx) + || (validate_8(ctx) || ({ offset = decode_u64le(&ctx->net_bytes[ctx->net_offset-8]); false; })) + || (validate_4(ctx) || ({ count = decode_u32le(&ctx->net_bytes[ctx->net_offset-4]); false; })) || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint32_t exp = 116; (((uint32_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); }) + || ({ uint8_t exp = 116; (((uint8_t)typ) != exp) && + lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) + || ({ uint64_t max = INT64_MAX; (((uint64_t)offset) > max) && + lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "offset value is too large (%"PRIu64" > %"PRIu64")", offset, max); }) + || ({ uint32_t max = INT32_MAX; (((uint32_t)count) > max) && + lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "count value is too large (%"PRIu32" > %"PRIu32")", count, max); }) ; } @@ -504,26 +510,29 @@ LM_FLATTEN static bool validate_Rread(struct _validate_ctx *ctx) { || validate_d(ctx) || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint32_t exp = 117; (((uint32_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); }) + || ({ uint8_t exp = 117; (((uint8_t)typ) != exp) && + lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) ; } LM_FLATTEN static bool validate_Twrite(struct _validate_ctx *ctx) { uint32_t size; uint8_t typ; + uint64_t offset; uint32_t _size_offset; return false || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = decode_u32le(&ctx->net_bytes[ctx->net_offset-4]); false; })) || (validate_1(ctx) || ({ typ = decode_u8le(&ctx->net_bytes[ctx->net_offset-1]); false; })) || validate_tag(ctx) || validate_fid(ctx) - || validate_8(ctx) + || (validate_8(ctx) || ({ offset = decode_u64le(&ctx->net_bytes[ctx->net_offset-8]); false; })) || validate_d(ctx) || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint32_t exp = 118; (((uint32_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); }) + || ({ uint8_t exp = 118; (((uint8_t)typ) != exp) && + lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) + || ({ uint64_t max = INT64_MAX; (((uint64_t)offset) > max) && + lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "offset value is too large (%"PRIu64" > %"PRIu64")", offset, max); }) ; } @@ -538,8 +547,8 @@ LM_FLATTEN static bool validate_Rwrite(struct _validate_ctx *ctx) { || validate_4(ctx) || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint32_t exp = 119; (((uint32_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); }) + || ({ uint8_t exp = 119; (((uint8_t)typ) != exp) && + lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) ; } @@ -554,8 +563,8 @@ LM_FLATTEN static bool validate_Tclunk(struct _validate_ctx *ctx) { || validate_fid(ctx) || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint32_t exp = 120; (((uint32_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); }) + || ({ uint8_t exp = 120; (((uint8_t)typ) != exp) && + lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) ; } @@ -569,8 +578,8 @@ LM_FLATTEN static bool validate_Rclunk(struct _validate_ctx *ctx) { || validate_tag(ctx) || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint32_t exp = 121; (((uint32_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); }) + || ({ uint8_t exp = 121; (((uint8_t)typ) != exp) && + lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) ; } @@ -585,8 +594,8 @@ LM_FLATTEN static bool validate_Tremove(struct _validate_ctx *ctx) { || validate_fid(ctx) || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint32_t exp = 122; (((uint32_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); }) + || ({ uint8_t exp = 122; (((uint8_t)typ) != exp) && + lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) ; } @@ -600,8 +609,8 @@ LM_FLATTEN static bool validate_Rremove(struct _validate_ctx *ctx) { || validate_tag(ctx) || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint32_t exp = 123; (((uint32_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); }) + || ({ uint8_t exp = 123; (((uint8_t)typ) != exp) && + lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) ; } @@ -616,8 +625,8 @@ LM_FLATTEN static bool validate_Tstat(struct _validate_ctx *ctx) { || validate_fid(ctx) || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint32_t exp = 124; (((uint32_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); }) + || ({ uint8_t exp = 124; (((uint8_t)typ) != exp) && + lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) ; } @@ -635,10 +644,10 @@ LM_FLATTEN static bool validate_Rstat(struct _validate_ctx *ctx) { || ({ _stat_offset = ctx->net_offset; validate_stat(ctx); }) || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint32_t exp = 125; (((uint32_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); }) - || ({ uint32_t exp = ctx->net_offset - _stat_offset; (((uint32_t)nstat) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "nstat value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)nstat, exp); }) + || ({ uint8_t exp = 125; (((uint8_t)typ) != exp) && + lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) + || ({ uint16_t exp = ctx->net_offset - _stat_offset; (((uint16_t)nstat) != exp) && + lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "nstat value is wrong (actual:%"PRIu16" != correct:%"PRIu16")", (uint16_t)nstat, exp); }) ; } @@ -657,10 +666,10 @@ LM_FLATTEN static bool validate_Twstat(struct _validate_ctx *ctx) { || ({ _stat_offset = ctx->net_offset; validate_stat(ctx); }) || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint32_t exp = 126; (((uint32_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); }) - || ({ uint32_t exp = ctx->net_offset - _stat_offset; (((uint32_t)nstat) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "nstat value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)nstat, exp); }) + || ({ uint8_t exp = 126; (((uint8_t)typ) != exp) && + lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) + || ({ uint16_t exp = ctx->net_offset - _stat_offset; (((uint16_t)nstat) != exp) && + lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "nstat value is wrong (actual:%"PRIu16" != correct:%"PRIu16")", (uint16_t)nstat, exp); }) ; } @@ -674,8 +683,8 @@ LM_FLATTEN static bool validate_Rwstat(struct _validate_ctx *ctx) { || validate_tag(ctx) || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint32_t exp = 127; (((uint32_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); }) + || ({ uint8_t exp = 127; (((uint8_t)typ) != exp) && + lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) ; } @@ -692,8 +701,8 @@ LM_FLATTEN static bool validate_Tsession(struct _validate_ctx *ctx) { || validate_8(ctx) || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint32_t exp = 150; (((uint32_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); }) + || ({ uint8_t exp = 150; (((uint8_t)typ) != exp) && + lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) ; } @@ -707,8 +716,8 @@ LM_FLATTEN static bool validate_Rsession(struct _validate_ctx *ctx) { || validate_tag(ctx) || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint32_t exp = 151; (((uint32_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); }) + || ({ uint8_t exp = 151; (((uint8_t)typ) != exp) && + lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) ; } @@ -725,8 +734,8 @@ LM_FLATTEN static bool validate_Tsread(struct _validate_ctx *ctx) { || _validate_list(ctx, decode_u16le(&ctx->net_bytes[ctx->net_offset-2]), validate_s, sizeof(struct lib9p_s)) || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint32_t exp = 152; (((uint32_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); }) + || ({ uint8_t exp = 152; (((uint8_t)typ) != exp) && + lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) ; } @@ -741,8 +750,8 @@ LM_FLATTEN static bool validate_Rsread(struct _validate_ctx *ctx) { || validate_d(ctx) || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint32_t exp = 153; (((uint32_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); }) + || ({ uint8_t exp = 153; (((uint8_t)typ) != exp) && + lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) ; } @@ -760,8 +769,8 @@ LM_FLATTEN static bool validate_Tswrite(struct _validate_ctx *ctx) { || validate_d(ctx) || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint32_t exp = 154; (((uint32_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); }) + || ({ uint8_t exp = 154; (((uint8_t)typ) != exp) && + lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) ; } @@ -776,8 +785,8 @@ LM_FLATTEN static bool validate_Rswrite(struct _validate_ctx *ctx) { || validate_4(ctx) || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint32_t exp = 155; (((uint32_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); }) + || ({ uint8_t exp = 155; (((uint8_t)typ) != exp) && + lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) ; } #endif /* CONFIG_9P_ENABLE_9P2000_e */ diff --git a/lib9p/idl.gen b/lib9p/idl.gen index e796855..27396b4 100755 --- a/lib9p/idl.gen +++ b/lib9p/idl.gen @@ -90,6 +90,10 @@ def c_expr(expr: idl.Expr) -> str: ret += [str(tok.val)] case idl.ExprSym(name="end"): ret += ["ctx->net_offset"] + case idl.ExprSym(name="s32_max"): + ret += ["INT32_MAX"] + case idl.ExprSym(name="s64_max"): + ret += ["INT64_MAX"] case idl.ExprSym(): ret += [f"_{tok.name[1:]}_offset"] return " ".join(ret) @@ -480,13 +484,17 @@ LM_ALWAYS_INLINE static bool _validate_list(struct _validate_ctx *ctx, # Pass 4 - validate ,max= and ,val= constraints for member in typ.members: if member.max: + assert member.static_size + nbits = member.static_size * 8 ret += ifdef_push(2, c_ver_ifdef(member.in_versions)) - ret += f"\t || ({{ uint32_t max = {c_expr(member.max)}; (((uint32_t){member.name}) > max) &&\n" - ret += f'\t lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "{member.name} value is too large (%"PRIu32" > %"PRIu32")", {member.name}, max); }})\n' + ret += f"\t || ({{ uint{nbits}_t max = {c_expr(member.max)}; (((uint{nbits}_t){member.name}) > max) &&\n" + ret += f'\t lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "{member.name} value is too large (%"PRIu{nbits}" > %"PRIu{nbits}")", {member.name}, max); }})\n' if member.val: + assert member.static_size + nbits = member.static_size * 8 ret += ifdef_push(2, c_ver_ifdef(member.in_versions)) - ret += f"\t || ({{ uint32_t exp = {c_expr(member.val)}; (((uint32_t){member.name}) != exp) &&\n" - ret += f'\t lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "{member.name} value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t){member.name}, exp); }})\n' + ret += f"\t || ({{ uint{nbits}_t exp = {c_expr(member.val)}; (((uint{nbits}_t){member.name}) != exp) &&\n" + ret += f'\t lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "{member.name} value is wrong (actual:%"PRIu{nbits}" != correct:%"PRIu{nbits}")", (uint{nbits}_t){member.name}, exp); }})\n' ret += ifdef_pop(1) ret += "\t ;\n" diff --git a/lib9p/idl/0000-README.md b/lib9p/idl/0000-README.md index a541006..036de22 100644 --- a/lib9p/idl/0000-README.md +++ b/lib9p/idl/0000-README.md @@ -54,6 +54,10 @@ can be - `&fieldname` to refer to the offset of a field name in that struct, - the special value `end` to refer to the offset of the end of the struct, + - the special value `s32_max` to refer to the constant value + `(1<<31)-1`, or + - the special value `s64_max` to refer to the constant value + `(1<<63)-1` A parser for this syntax is given in `__init__.py`. However, `__init__.py` places the somewhat arbitrary undocumented restrictions diff --git a/lib9p/idl/1995-9P1.9p.wip b/lib9p/idl/1995-9P1.9p.wip index 30b9112..4e3a6f5 100644 --- a/lib9p/idl/1995-9P1.9p.wip +++ b/lib9p/idl/1995-9P1.9p.wip @@ -1,6 +1,6 @@ # lib9p/idl/1995-9P1.9p - Definitions of 9P1 (Plan 9 2nd ed and 3rd ed) messages # -# Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com> +# Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com> # SPDX-License-Identifier: AGPL-3.0-or-later # https://man.cat-v.org/plan_9_2nd_ed/5/ @@ -38,7 +38,7 @@ msg Topen = "typ[1,val=TODO] tag[tag] fid[fid] mode[1]" msg Ropen = "typ[1,val=TODO] tag[tag] fid[fid] qid[8]" msg Tcreate = "typ[1,val=TODO] tag[tag] fid[fid] name[28] perm[4] mode[1]" msg Rcreate = "typ[1,val=TODO] tag[tag] fid[fid] qid[8]" -msg Tread = "typ[1,val=TODO] tag[tag] fid[fid] offset[8] count[2,max=8192]" +msg Tread = "typ[1,val=TODO] tag[tag] fid[fid] offset[8,max=s64_max] count[2,max=8192]" msg Rread = "typ[1,val=TODO] tag[tag] fid[fid] count[2,max=8192] pad[1] count*(data[1])" msg Twrite = "typ[1,val=TODO] tag[tag] fid[fid] offset[8] count[2,max=8192] pad[1] count*(data[1])" msg Rwrite = "typ[1,val=TODO] tag[tag] fid[fid] count[2,max=8192]" diff --git a/lib9p/idl/2002-9P2000.9p b/lib9p/idl/2002-9P2000.9p index c83f439..4b0738f 100644 --- a/lib9p/idl/2002-9P2000.9p +++ b/lib9p/idl/2002-9P2000.9p @@ -1,6 +1,6 @@ # lib9p/idl/2002-9P2000.9p - Definitions of 9P2000 messages # -# Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com> +# Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com> # SPDX-License-Identifier: AGPL-3.0-or-later # "9P2000" base protocol @@ -9,11 +9,14 @@ # # But due to incompleteness of the draft RFC, the Plan 9 manual # section-5 and the Plan 9 headers (particularly fcall.h) are often -# better references. +# better references. The s{32,64}_max limitations are not documented +# in the draft RFC or the manual pages, but have been enforced by +# lib9p/srv.c in every release of Plan 9 4e. # # https://github.com/plan9foundation/plan9/tree/main/sys/man/5 # https://man.cat-v.org/plan_9/5/ # https://github.com/plan9foundation/plan9/blob/main/sys/include/fcall.h +# https://github.com/plan9foundation/plan9/blob/main/sys/src/lib9p/srv.c version "9P2000" # tag - identify a request/response pair @@ -22,8 +25,8 @@ num tag = 2 # file identifier - like a UNIX file-descriptor num fid = 4 -# data - u32le `n`, then `n` bytes of data -struct d = "len[4] len*(dat[1])" +# data - s32le `n`, then `n` bytes of data +struct d = "len[4,max=s32_max] len*(dat[1])" # string - u16le `n`, then `n` bytes of UTF-8, without any nul-bytes struct s = "len[2] len*(utf8[1])" @@ -136,9 +139,9 @@ msg Topen = "size[4,val=end-&size] typ[1,val=112] tag[tag] fid[fid] mode[o]" msg Ropen = "size[4,val=end-&size] typ[1,val=113] tag[tag] qid[qid] iounit[4]" msg Tcreate = "size[4,val=end-&size] typ[1,val=114] tag[tag] fid[fid] name[s] perm[dm] mode[o]" msg Rcreate = "size[4,val=end-&size] typ[1,val=115] tag[tag] qid[qid] iounit[4]" -msg Tread = "size[4,val=end-&size] typ[1,val=116] tag[tag] fid[fid] offset[8] count[4]" +msg Tread = "size[4,val=end-&size] typ[1,val=116] tag[tag] fid[fid] offset[8,max=s64_max] count[4,max=s32_max]" msg Rread = "size[4,val=end-&size] typ[1,val=117] tag[tag] data[d]" # for directories `data` is the sequence "cnt*(entries[stat])" -msg Twrite = "size[4,val=end-&size] typ[1,val=118] tag[tag] fid[fid] offset[8] data[d]" +msg Twrite = "size[4,val=end-&size] typ[1,val=118] tag[tag] fid[fid] offset[8,max=s64_max] data[d]" msg Rwrite = "size[4,val=end-&size] typ[1,val=119] tag[tag] count[4]" msg Tclunk = "size[4,val=end-&size] typ[1,val=120] tag[tag] fid[fid]" msg Rclunk = "size[4,val=end-&size] typ[1,val=121] tag[tag]" diff --git a/lib9p/idl/__init__.py b/lib9p/idl/__init__.py index 3379bdf..c08a89e 100644 --- a/lib9p/idl/__init__.py +++ b/lib9p/idl/__init__.py @@ -447,7 +447,7 @@ def parse_file( typs: list[Type] = [x for x in env.values() if not isinstance(x, Primitive)] for typ in [typ for typ in typs if isinstance(typ, Struct)]: - valid_syms = ["end", *["&" + m.name for m in typ.members]] + valid_syms = ["end", "s32_max", "s64_max", *["&" + m.name for m in typ.members]] for member in typ.members: for tok in [*member.max.tokens, *member.val.tokens]: if isinstance(tok, ExprSym) and tok.name not in valid_syms: |