diff options
author | Luke T. Shumaker <lukeshu@lukeshu.com> | 2024-10-02 21:09:07 -0600 |
---|---|---|
committer | Luke T. Shumaker <lukeshu@lukeshu.com> | 2024-10-02 21:09:07 -0600 |
commit | 4b8a9d80d37c892695f102a48898fe1beacb593c (patch) | |
tree | a8e56c0b91201897f0966256b3b7b1e039d647a6 /lib9p/types.c | |
parent | ba8f3ddba03ab93158c93f77ef98137e1dd6e8e9 (diff) |
lib9p: Add the DM bitfield
Diffstat (limited to 'lib9p/types.c')
-rw-r--r-- | lib9p/types.c | 36 |
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); } |