Applied. On Fri, Jan 20, 2017 at 2:39 PM, Gris Ge <[email protected]> wrote:
> Problem: > > mpath_recv_reply() from libmpathcmd return -EINVAL on command 'show > maps json' with 2k paths. No error will be triggered for command > `multipathd -k'show maps json` as multipathd is using their own > implementation on recv_packet() which does not have size limitation. > > Root cause: > > Commit 174e717d351789a3cb29e1417f8e910baabcdb16 introduced the > limitation on max bytes(65535) of reply string from multipathd. > With 2k paths(1k mpaths) simulated by scsi_debug, the 'show maps json' > requires 2066784 bytes which trigged the EINVAL error. > > Fix: > * Remove the limitation of MAX_REPLY_LEN in libmpathcmd. > > * New functions `recv_packet_from_client()` in uxsock.h of libmultipath > which enforce the limitation of buffer size to 512(_MAX_CMD_LEN). > > * Change multipathd socket listener to use > `recv_packet_from_client()`. > > Signed-off-by: Gris Ge <[email protected]> > --- > libmpathcmd/mpath_cmd.c | 2 -- > libmultipath/uxsock.c | 39 ++++++++++++++++++++++++++++++--------- > libmultipath/uxsock.h | 9 +++++++++ > multipathd/uxlsnr.c | 8 +++++--- > 4 files changed, 44 insertions(+), 14 deletions(-) > > diff --git a/libmpathcmd/mpath_cmd.c b/libmpathcmd/mpath_cmd.c > index d9c5790..7fc9e98 100644 > --- a/libmpathcmd/mpath_cmd.c > +++ b/libmpathcmd/mpath_cmd.c > @@ -142,8 +142,6 @@ int mpath_recv_reply(int fd, char **reply, unsigned > int timeout) > len = mpath_recv_reply_len(fd, timeout); > if (len <= 0) > return len; > - if (len > MAX_REPLY_LEN) > - return -EINVAL; > *reply = malloc(len); > if (!*reply) > return -1; > diff --git a/libmultipath/uxsock.c b/libmultipath/uxsock.c > index 0ca9e50..492f4b9 100644 > --- a/libmultipath/uxsock.c > +++ b/libmultipath/uxsock.c > @@ -24,6 +24,16 @@ > #include "memory.h" > #include "uxsock.h" > #include "debug.h" > + > +/* > + * Code is similar with mpath_recv_reply() with data size limitation > + * and debug-able malloc. > + * When limit == 0, it means no limit on data size, used for socket client > + * to receiving data from multipathd. > + */ > +static int _recv_packet(int fd, char **buf, unsigned int timeout, > + ssize_t limit); > + > /* > * create a unix domain socket and start listening on it > * return a file descriptor open on the socket > @@ -81,26 +91,37 @@ int send_packet(int fd, const char *buf) > return mpath_send_cmd(fd, buf); > } > > -/* > - * receive a packet in length prefix format > - */ > -int recv_packet(int fd, char **buf, unsigned int timeout) > +static int _recv_packet(int fd, char **buf, unsigned int timeout, ssize_t > limit) > { > - int err; > - ssize_t len; > + int err = 0; > + ssize_t len = 0; > > *buf = NULL; > len = mpath_recv_reply_len(fd, timeout); > if (len <= 0) > return len; > + if ((limit > 0) && (len > limit)) > + return -EINVAL; > (*buf) = MALLOC(len); > if (!*buf) > return -ENOMEM; > err = mpath_recv_reply_data(fd, *buf, len, timeout); > - if (err) { > + if (err != 0) { > FREE(*buf); > (*buf) = NULL; > - return err; > } > - return 0; > + return err; > +} > + > +/* > + * receive a packet in length prefix format > + */ > +int recv_packet(int fd, char **buf, unsigned int timeout) > +{ > + return _recv_packet(fd, buf, timeout, 0 /* no limit */); > +} > + > +int recv_packet_from_client(int fd, char **buf, unsigned int timeout) > +{ > + return _recv_packet(fd, buf, timeout, _MAX_CMD_LEN); > } > diff --git a/libmultipath/uxsock.h b/libmultipath/uxsock.h > index 442b564..8e7401d 100644 > --- a/libmultipath/uxsock.h > +++ b/libmultipath/uxsock.h > @@ -2,3 +2,12 @@ > int ux_socket_listen(const char *name); > int send_packet(int fd, const char *buf); > int recv_packet(int fd, char **buf, unsigned int timeout); > + > +#define _MAX_CMD_LEN 512 > + > +/* > + * Used for receiving socket command from untrusted socket client where > data > + * size is restricted to 512(_MAX_CMD_LEN) at most. > + * Return -EINVAL if data length requested by client exceeded the > _MAX_CMD_LEN. > + */ > +int recv_packet_from_client(int fd, char **buf, unsigned int timeout); > diff --git a/multipathd/uxlsnr.c b/multipathd/uxlsnr.c > index dfef03e..6ca62af 100644 > --- a/multipathd/uxlsnr.c > +++ b/multipathd/uxlsnr.c > @@ -241,13 +241,15 @@ void * uxsock_listen(uxsock_trigger_fn > uxsock_trigger, void * trigger_data) > if (clock_gettime(CLOCK_MONOTONIC, > &start_time) > != 0) > start_time.tv_sec = 0; > - if (recv_packet(c->fd, &inbuf, > - uxsock_timeout) != 0) { > + if (recv_packet_from_client(c->fd, &inbuf, > + uxsock_timeout) > + != 0) { > dead_client(c); > continue; > } > if (!inbuf) { > - condlog(4, "recv_packet get null > request"); > + condlog(4, > "recv_packet_from_client " > + "get null request"); > continue; > } > condlog(4, "cli[%d]: Got request [%s]", > -- > 1.8.3.1 > > -- > dm-devel mailing list > [email protected] > https://www.redhat.com/mailman/listinfo/dm-devel >
-- dm-devel mailing list [email protected] https://www.redhat.com/mailman/listinfo/dm-devel
