diff options
Diffstat (limited to 'lib9p')
-rw-r--r-- | lib9p/srv.c | 32 |
1 files changed, 16 insertions, 16 deletions
diff --git a/lib9p/srv.c b/lib9p/srv.c index 61b40ea..c624fa8 100644 --- a/lib9p/srv.c +++ b/lib9p/srv.c @@ -131,7 +131,7 @@ struct _lib9p_srv_req { /* immutable */ struct _srv_sess *parent_sess; uint16_t tag; - uint8_t *net_bytes; /* CONFIG_9P_MAX_MSG_SIZE-sized */ + uint8_t *net_bytes; /* mutable */ struct lib9p_srv_ctx ctx; }; @@ -212,8 +212,6 @@ static bool read_exactly(lo_interface net_stream_conn fd, uint8_t *buf, size_t g static void handle_message(struct _lib9p_srv_req *ctx); [[noreturn]] void lib9p_srv_read_cr(struct lib9p_srv *srv, lo_interface net_stream_listener listener) { - uint8_t buf[CONFIG_9P_MAX_MSG_SIZE]; - assert(srv); assert(srv->rootdir); assert(!LO_IS_NULL(listener)); @@ -248,6 +246,7 @@ static void handle_message(struct _lib9p_srv_req *ctx); nextmsg: /* Read the message. */ size_t done = 0; + uint8_t buf[7]; if (read_exactly(conn.fd, buf, 4, &done)) goto close; size_t goal = uint32le_decode(buf); @@ -277,11 +276,16 @@ static void handle_message(struct _lib9p_srv_req *ctx); respond_error(&req); goto nextmsg; } - if (read_exactly(conn.fd, buf, goal, &done)) + req.net_bytes = malloc(goal); + assert(req.net_bytes); + memcpy(req.net_bytes, buf, done); + if (read_exactly(conn.fd, req.net_bytes, goal, &done)) { + free(req.net_bytes); goto close; + } /* Handle the message... */ - if (buf[4] == LIB9P_TYP_Tversion) + if (req.net_bytes[4] == LIB9P_TYP_Tversion) /* ...in this coroutine for Tversion, */ handle_message(&req); else @@ -302,7 +306,6 @@ static void handle_message(struct _lib9p_srv_req *ctx); /* write coroutine ************************************************************/ COROUTINE lib9p_srv_write_cr(void *_srv) { - uint8_t net[CONFIG_9P_MAX_MSG_SIZE]; struct _lib9p_srv_req req; _lib9p_srv_reqch_req_t rpc_handle; @@ -321,11 +324,9 @@ COROUTINE lib9p_srv_write_cr(void *_srv) { _lib9p_srv_reqch_send_resp(rpc_handle, 0); cr_exit(); } - /* Deep-copy the request from the reader coroutine's + /* Copy the request from the reader coroutine's * stack to our stack. */ req = *rpc_handle.req; - memcpy(net, req.net_bytes, uint32le_decode(req.net_bytes)); - req.net_bytes = net; /* Record that we have it. */ reqmap_store(&req.parent_sess->reqs, req.tag, &req); /* Notify the reader coroutine that we're done with @@ -393,19 +394,15 @@ static tmessage_handler tmessage_handlers[0x100] = { }; static void handle_message(struct _lib9p_srv_req *ctx) { - uint8_t host_req[CONFIG_9P_MAX_HOSTMSG_SIZE]; + uint8_t *host_req = NULL; uint8_t host_resp[CONFIG_9P_MAX_HOSTMSG_SIZE]; /* Unmarshal it. */ ssize_t host_size = lib9p_Tmsg_validate(&ctx->ctx.basectx, ctx->net_bytes); if (host_size < 0) goto write; - if ((size_t)host_size > sizeof(host_req)) { - lib9p_errorf(&ctx->ctx.basectx, - LINUX_EMSGSIZE, "unmarshalled payload larger than server limit (%zu > %zu)", - host_size, sizeof(host_req)); - goto write; - } + host_req = malloc(host_size); + assert(host_req); enum lib9p_msg_type typ; lib9p_Tmsg_unmarshal(&ctx->ctx.basectx, ctx->net_bytes, &typ, host_req); @@ -424,6 +421,9 @@ static void handle_message(struct _lib9p_srv_req *ctx) { goto write; write_Rmsg(ctx, &net_resp); } + if (host_req) + free(host_req); + free(ctx->net_bytes); } #define util_handler_common(ctx, req, resp) do { \ |