1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-01-10 05:18:36 +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 40f8cf3f7c
commit 747060fe19
2 changed files with 28 additions and 5 deletions

View File

@ -1,5 +1,6 @@
Version 2.02.89 - Version 2.02.89 -
================================== ==================================
Fix clvmd processing of invalid request on local socket.
Fix command line option decoding. Fix command line option decoding.
Reset LV status when unlinking LV from VG. Reset LV status when unlinking LV from VG.
Fix overly strict extent-count divisibility requirements for striped mirrors. 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; int missing_len;
char buffer[PIPE_BUF]; char buffer[PIPE_BUF];
memset(buffer, 0, PIPE_BUF);
len = read(thisfd->fd, buffer, sizeof(buffer)); len = read(thisfd->fd, buffer, sizeof(buffer));
if (len == -1 && errno == EINTR) if (len == -1 && errno == EINTR)
return 1; return 1;
@ -1169,9 +1170,6 @@ static int read_from_local_sock(struct local_client *thisfd)
return len; return len;
} }
/* Free any old buffer space */
free(thisfd->bits.localsock.cmd);
/* See if we have the whole message */ /* See if we have the whole message */
argslen = argslen =
len - strlen(inheader->node) - sizeof(struct clvm_header); 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) if (missing_len < 0)
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 */ /* Save the message */
thisfd->bits.localsock.cmd = malloc(len + missing_len); thisfd->bits.localsock.cmd = malloc(len + missing_len);
@ -1203,15 +1217,23 @@ static int read_from_local_sock(struct local_client *thisfd)
char *argptr = char *argptr =
inheader->node + strlen(inheader->node) + 1; inheader->node + strlen(inheader->node) + 1;
while (missing_len > 0 && len >= 0) { while (missing_len > 0) {
DEBUGLOG DEBUGLOG
("got %d bytes, need another %d (total %d)\n", ("got %d bytes, need another %d (total %d)\n",
argslen, missing_len, inheader->arglen); argslen, missing_len, inheader->arglen);
len = read(thisfd->fd, argptr + argslen, len = read(thisfd->fd, argptr + argslen,
missing_len); missing_len);
if (len >= 0) { if (len == -1 && errno == EINTR)
continue;
if (len > 0) {
missing_len -= len; missing_len -= len;
argslen += 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;
} }
} }
} }