summaryrefslogtreecommitdiff
path: root/lib9p/types.c
diff options
context:
space:
mode:
authorLuke T. Shumaker <lukeshu@lukeshu.com>2024-10-02 21:09:07 -0600
committerLuke T. Shumaker <lukeshu@lukeshu.com>2024-10-02 21:09:07 -0600
commit4b8a9d80d37c892695f102a48898fe1beacb593c (patch)
treea8e56c0b91201897f0966256b3b7b1e039d647a6 /lib9p/types.c
parentba8f3ddba03ab93158c93f77ef98137e1dd6e8e9 (diff)
lib9p: Add the DM bitfield
Diffstat (limited to 'lib9p/types.c')
-rw-r--r--lib9p/types.c36
1 files changed, 30 insertions, 6 deletions
diff --git a/lib9p/types.c b/lib9p/types.c
index 50ac1cf..2d0bb1b 100644
--- a/lib9p/types.c
+++ b/lib9p/types.c
@@ -343,6 +343,22 @@ static ALWAYS_INLINE bool validate_s(struct _validate_ctx *ctx) {
return false;
}
+static ALWAYS_INLINE bool validate_dm(struct _validate_ctx *ctx) {
+ if (validate_4(ctx))
+ return true;
+ static const lib9p_dm_t masks[LIB9P_VER_NUM] = {
+ [LIB9P_VER_9P2000] = 0b11111100000000000000000111111111,
+ [LIB9P_VER_9P2000_e] = 0b11111100000000000000000111111111,
+ [LIB9P_VER_9P2000_u] = 0b11111100101111000000000111111111,
+ };
+ lib9p_dm_t mask = masks[ctx->ctx->version];
+ lib9p_dm_t val = decode_u32le(&ctx->net_bytes[ctx->net_offset-4]);
+ if (val & ~mask)
+ return lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "unknown bits in dm bitfield: %#04"PRIx32,
+ val & ~mask);
+ return false;
+}
+
static ALWAYS_INLINE bool validate_qt(struct _validate_ctx *ctx) {
if (validate_1(ctx))
return true;
@@ -370,7 +386,7 @@ static ALWAYS_INLINE bool validate_stat(struct _validate_ctx *ctx) {
|| validate_2(ctx)
|| validate_4(ctx)
|| validate_qid(ctx)
- || validate_4(ctx)
+ || validate_dm(ctx)
|| validate_4(ctx)
|| validate_4(ctx)
|| validate_8(ctx)
@@ -465,7 +481,7 @@ static FLATTEN bool validate_Ropen(struct _validate_ctx *ctx) {
static FLATTEN bool validate_Tcreate(struct _validate_ctx *ctx) {
return validate_4(ctx)
|| validate_s(ctx)
- || validate_4(ctx)
+ || validate_dm(ctx)
|| validate_o(ctx);
}
@@ -596,6 +612,10 @@ static ALWAYS_INLINE void unmarshal_s(struct _unmarshal_ctx *ctx, struct lib9p_s
unmarshal_1(ctx, &out->utf8[i]);
}
+static ALWAYS_INLINE void unmarshal_dm(struct _unmarshal_ctx *ctx, lib9p_dm_t *out) {
+ unmarshal_4(ctx, (uint32_t *)out);
+}
+
static ALWAYS_INLINE void unmarshal_qt(struct _unmarshal_ctx *ctx, lib9p_qt_t *out) {
unmarshal_1(ctx, (uint8_t *)out);
}
@@ -613,7 +633,7 @@ static ALWAYS_INLINE void unmarshal_stat(struct _unmarshal_ctx *ctx, struct lib9
unmarshal_2(ctx, &out->kern_type);
unmarshal_4(ctx, &out->kern_dev);
unmarshal_qid(ctx, &out->file_qid);
- unmarshal_4(ctx, &out->file_mode);
+ unmarshal_dm(ctx, &out->file_mode);
unmarshal_4(ctx, &out->file_atime);
unmarshal_4(ctx, &out->file_mtime);
unmarshal_8(ctx, &out->file_size);
@@ -720,7 +740,7 @@ static FLATTEN void unmarshal_Tcreate(struct _unmarshal_ctx *ctx, struct lib9p_m
memset(out, 0, sizeof(*out));
unmarshal_4(ctx, &out->fid);
unmarshal_s(ctx, &out->name);
- unmarshal_4(ctx, &out->perm);
+ unmarshal_dm(ctx, &out->perm);
unmarshal_o(ctx, &out->mode);
}
@@ -894,6 +914,10 @@ static ALWAYS_INLINE bool marshal_s(struct _marshal_ctx *ctx, struct lib9p_s *va
});
}
+static ALWAYS_INLINE bool marshal_dm(struct _marshal_ctx *ctx, lib9p_dm_t *val) {
+ return marshal_4(ctx, (uint32_t *)val);
+}
+
static ALWAYS_INLINE bool marshal_qt(struct _marshal_ctx *ctx, lib9p_qt_t *val) {
return marshal_1(ctx, (uint8_t *)val);
}
@@ -909,7 +933,7 @@ static ALWAYS_INLINE bool marshal_stat(struct _marshal_ctx *ctx, struct lib9p_st
|| marshal_2(ctx, &val->kern_type)
|| marshal_4(ctx, &val->kern_dev)
|| marshal_qid(ctx, &val->file_qid)
- || marshal_4(ctx, &val->file_mode)
+ || marshal_dm(ctx, &val->file_mode)
|| marshal_4(ctx, &val->file_atime)
|| marshal_4(ctx, &val->file_mtime)
|| marshal_8(ctx, &val->file_size)
@@ -1007,7 +1031,7 @@ static FLATTEN bool marshal_Ropen(struct _marshal_ctx *ctx, struct lib9p_msg_Rop
static FLATTEN bool marshal_Tcreate(struct _marshal_ctx *ctx, struct lib9p_msg_Tcreate *val) {
return marshal_4(ctx, &val->fid)
|| marshal_s(ctx, &val->name)
- || marshal_4(ctx, &val->perm)
+ || marshal_dm(ctx, &val->perm)
|| marshal_o(ctx, &val->mode);
}