diff options
Diffstat (limited to 'lib9p/types.c')
-rw-r--r-- | lib9p/types.c | 31 |
1 files changed, 25 insertions, 6 deletions
diff --git a/lib9p/types.c b/lib9p/types.c index 18dcbfe..50ac1cf 100644 --- a/lib9p/types.c +++ b/lib9p/types.c @@ -384,6 +384,17 @@ static ALWAYS_INLINE bool validate_stat(struct _validate_ctx *ctx) { || ( (ctx->ctx->version==LIB9P_VER_9P2000_u) && validate_4(ctx) ); } +static ALWAYS_INLINE bool validate_o(struct _validate_ctx *ctx) { + if (validate_1(ctx)) + return true; + static const lib9p_o_t mask = 0b01010011; + lib9p_o_t val = decode_u8le(&ctx->net_bytes[ctx->net_offset-1]); + if (val & ~mask) + return lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "unknown bits in o bitfield: %#01"PRIx8, + val & ~mask); + return false; +} + static FLATTEN bool validate_Tversion(struct _validate_ctx *ctx) { return validate_4(ctx) || validate_s(ctx); @@ -443,7 +454,7 @@ static FLATTEN bool validate_Rwalk(struct _validate_ctx *ctx) { static FLATTEN bool validate_Topen(struct _validate_ctx *ctx) { return validate_4(ctx) - || validate_1(ctx); + || validate_o(ctx); } static FLATTEN bool validate_Ropen(struct _validate_ctx *ctx) { @@ -455,7 +466,7 @@ static FLATTEN bool validate_Tcreate(struct _validate_ctx *ctx) { return validate_4(ctx) || validate_s(ctx) || validate_4(ctx) - || validate_1(ctx); + || validate_o(ctx); } static FLATTEN bool validate_Rcreate(struct _validate_ctx *ctx) { @@ -616,6 +627,10 @@ static ALWAYS_INLINE void unmarshal_stat(struct _unmarshal_ctx *ctx, struct lib9 if ( (ctx->ctx->version==LIB9P_VER_9P2000_u) ) unmarshal_4(ctx, &out->file_last_modified_n_uid); } +static ALWAYS_INLINE void unmarshal_o(struct _unmarshal_ctx *ctx, lib9p_o_t *out) { + unmarshal_1(ctx, (uint8_t *)out); +} + static FLATTEN void unmarshal_Tversion(struct _unmarshal_ctx *ctx, struct lib9p_msg_Tversion *out) { memset(out, 0, sizeof(*out)); unmarshal_4(ctx, &out->max_msg_size); @@ -692,7 +707,7 @@ static FLATTEN void unmarshal_Rwalk(struct _unmarshal_ctx *ctx, struct lib9p_msg static FLATTEN void unmarshal_Topen(struct _unmarshal_ctx *ctx, struct lib9p_msg_Topen *out) { memset(out, 0, sizeof(*out)); unmarshal_4(ctx, &out->fid); - unmarshal_1(ctx, &out->mode); + unmarshal_o(ctx, &out->mode); } static FLATTEN void unmarshal_Ropen(struct _unmarshal_ctx *ctx, struct lib9p_msg_Ropen *out) { @@ -706,7 +721,7 @@ static FLATTEN void unmarshal_Tcreate(struct _unmarshal_ctx *ctx, struct lib9p_m unmarshal_4(ctx, &out->fid); unmarshal_s(ctx, &out->name); unmarshal_4(ctx, &out->perm); - unmarshal_1(ctx, &out->mode); + unmarshal_o(ctx, &out->mode); } static FLATTEN void unmarshal_Rcreate(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rcreate *out) { @@ -908,6 +923,10 @@ static ALWAYS_INLINE bool marshal_stat(struct _marshal_ctx *ctx, struct lib9p_st || ( (ctx->ctx->version==LIB9P_VER_9P2000_u) && marshal_4(ctx, &val->file_last_modified_n_uid) ); } +static ALWAYS_INLINE bool marshal_o(struct _marshal_ctx *ctx, lib9p_o_t *val) { + return marshal_1(ctx, (uint8_t *)val); +} + static FLATTEN bool marshal_Tversion(struct _marshal_ctx *ctx, struct lib9p_msg_Tversion *val) { return marshal_4(ctx, &val->max_msg_size) || marshal_s(ctx, &val->version); @@ -977,7 +996,7 @@ static FLATTEN bool marshal_Rwalk(struct _marshal_ctx *ctx, struct lib9p_msg_Rwa static FLATTEN bool marshal_Topen(struct _marshal_ctx *ctx, struct lib9p_msg_Topen *val) { return marshal_4(ctx, &val->fid) - || marshal_1(ctx, &val->mode); + || marshal_o(ctx, &val->mode); } static FLATTEN bool marshal_Ropen(struct _marshal_ctx *ctx, struct lib9p_msg_Ropen *val) { @@ -989,7 +1008,7 @@ static FLATTEN bool marshal_Tcreate(struct _marshal_ctx *ctx, struct lib9p_msg_T return marshal_4(ctx, &val->fid) || marshal_s(ctx, &val->name) || marshal_4(ctx, &val->perm) - || marshal_1(ctx, &val->mode); + || marshal_o(ctx, &val->mode); } static FLATTEN bool marshal_Rcreate(struct _marshal_ctx *ctx, struct lib9p_msg_Rcreate *val) { |