1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-21 13:34:40 +03:00

Fix clvmd processing of invalid request on local socket. (rommer)

Code now detects small packet and wrong arglen and reply with
error intead of infinite loop.

https://bugzilla.redhat.com/show_bug.cgi?id=738484
This commit is contained in:
Milan Broz 2011-09-16 14:40:06 +00:00
parent 5170efd1ee
commit 63b8ed7c37
2 changed files with 28 additions and 5 deletions

View File

@ -1,5 +1,6 @@
Version 2.02.89 -
==================================
Fix clvmd processing of invalid request on local socket.
Fix command line option decoding.
Reset LV status when unlinking LV from VG.
Fix overly strict extent-count divisibility requirements for striped mirrors.

View File

@ -1061,6 +1061,7 @@ static int read_from_local_sock(struct local_client *thisfd)
int missing_len;
char buffer[PIPE_BUF];
memset(buffer, 0, PIPE_BUF);
len = read(thisfd->fd, buffer, sizeof(buffer));
if (len == -1 && errno == EINTR)
return 1;
@ -1169,9 +1170,6 @@ static int read_from_local_sock(struct local_client *thisfd)
return len;
}
/* Free any old buffer space */
free(thisfd->bits.localsock.cmd);
/* See if we have the whole message */
argslen =
len - strlen(inheader->node) - sizeof(struct clvm_header);
@ -1180,6 +1178,22 @@ static int read_from_local_sock(struct local_client *thisfd)
if (missing_len < 0)
missing_len = 0;
/* We need at least sizeof(struct clvm_header) bytes in buffer */
if (len < sizeof(struct clvm_header) || argslen < 0) {
struct clvm_header reply;
reply.cmd = CLVMD_CMD_REPLY;
reply.status = EINVAL;
reply.arglen = 0;
reply.flags = 0;
send_message(&reply, sizeof(reply), our_csid,
thisfd->fd,
"Error sending EINVAL reply to local user");
return 0;
}
/* Free any old buffer space */
free(thisfd->bits.localsock.cmd);
/* Save the message */
thisfd->bits.localsock.cmd = malloc(len + missing_len);
@ -1203,15 +1217,23 @@ static int read_from_local_sock(struct local_client *thisfd)
char *argptr =
inheader->node + strlen(inheader->node) + 1;
while (missing_len > 0 && len >= 0) {
while (missing_len > 0) {
DEBUGLOG
("got %d bytes, need another %d (total %d)\n",
argslen, missing_len, inheader->arglen);
len = read(thisfd->fd, argptr + argslen,
missing_len);
if (len >= 0) {
if (len == -1 && errno == EINTR)
continue;
if (len > 0) {
missing_len -= len;
argslen += len;
} else {
/* EOF or error on socket */
DEBUGLOG("EOF on local socket\n");
free(thisfd->bits.localsock.cmd);
thisfd->bits.localsock.cmd = NULL;
return 0;
}
}
}