aboutsummaryrefslogtreecommitdiffstats
path: root/fs/dlm/midcomms.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2008-01-25 00:58:46 -0500
committerDavid Teigland <teigland@redhat.com>2008-02-04 02:22:42 -0500
commiteef7d739c218cb2546cf95686db77de0d76e4122 (patch)
tree4d6c0e65e8aff1afb2c6428c729a98274ccb1a6d /fs/dlm/midcomms.c
parent8b0d8e03f847d9c1677b8a193cd124debbc54633 (diff)
dlm: dlm_process_incoming_buffer() fixes
* check that length is large enough to cover the non-variable part of message or rcom resp. (after checking that it's large enough to cover the header, of course). * kill more pointless casts Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: David Teigland <teigland@redhat.com>
Diffstat (limited to 'fs/dlm/midcomms.c')
-rw-r--r--fs/dlm/midcomms.c33
1 files changed, 20 insertions, 13 deletions
diff --git a/fs/dlm/midcomms.c b/fs/dlm/midcomms.c
index e69926e984db..07ac709f3ed7 100644
--- a/fs/dlm/midcomms.c
+++ b/fs/dlm/midcomms.c
@@ -61,9 +61,9 @@ int dlm_process_incoming_buffer(int nodeid, const void *base,
61 union { 61 union {
62 unsigned char __buf[DLM_INBUF_LEN]; 62 unsigned char __buf[DLM_INBUF_LEN];
63 /* this is to force proper alignment on some arches */ 63 /* this is to force proper alignment on some arches */
64 struct dlm_header dlm; 64 union dlm_packet p;
65 } __tmp; 65 } __tmp;
66 struct dlm_header *msg = &__tmp.dlm; 66 union dlm_packet *p = &__tmp.p;
67 int ret = 0; 67 int ret = 0;
68 int err = 0; 68 int err = 0;
69 uint16_t msglen; 69 uint16_t msglen;
@@ -75,15 +75,22 @@ int dlm_process_incoming_buffer(int nodeid, const void *base,
75 message may wrap around the end of the buffer back to the 75 message may wrap around the end of the buffer back to the
76 start, so we need to use a temp buffer and copy_from_cb. */ 76 start, so we need to use a temp buffer and copy_from_cb. */
77 77
78 copy_from_cb(msg, base, offset, sizeof(struct dlm_header), 78 copy_from_cb(p, base, offset, sizeof(struct dlm_header),
79 limit); 79 limit);
80 80
81 msglen = le16_to_cpu(msg->h_length); 81 msglen = le16_to_cpu(p->header.h_length);
82 lockspace = msg->h_lockspace; 82 lockspace = p->header.h_lockspace;
83 83
84 err = -EINVAL; 84 err = -EINVAL;
85 if (msglen < sizeof(struct dlm_header)) 85 if (msglen < sizeof(struct dlm_header))
86 break; 86 break;
87 if (p->header.h_cmd == DLM_MSG) {
88 if (msglen < sizeof(struct dlm_message))
89 break;
90 } else {
91 if (msglen < sizeof(struct dlm_rcom))
92 break;
93 }
87 err = -E2BIG; 94 err = -E2BIG;
88 if (msglen > dlm_config.ci_buffer_size) { 95 if (msglen > dlm_config.ci_buffer_size) {
89 log_print("message size %d from %d too big, buf len %d", 96 log_print("message size %d from %d too big, buf len %d",
@@ -104,26 +111,26 @@ int dlm_process_incoming_buffer(int nodeid, const void *base,
104 in the buffer on the stack (which should work for most 111 in the buffer on the stack (which should work for most
105 ordinary messages). */ 112 ordinary messages). */
106 113
107 if (msglen > DLM_INBUF_LEN && msg == &__tmp.dlm) { 114 if (msglen > sizeof(__tmp) && p == &__tmp.p) {
108 msg = kmalloc(dlm_config.ci_buffer_size, GFP_KERNEL); 115 p = kmalloc(dlm_config.ci_buffer_size, GFP_KERNEL);
109 if (msg == NULL) 116 if (p == NULL)
110 return ret; 117 return ret;
111 } 118 }
112 119
113 copy_from_cb(msg, base, offset, msglen, limit); 120 copy_from_cb(p, base, offset, msglen, limit);
114 121
115 BUG_ON(lockspace != msg->h_lockspace); 122 BUG_ON(lockspace != p->header.h_lockspace);
116 123
117 ret += msglen; 124 ret += msglen;
118 offset += msglen; 125 offset += msglen;
119 offset &= (limit - 1); 126 offset &= (limit - 1);
120 len -= msglen; 127 len -= msglen;
121 128
122 dlm_receive_buffer(msg, nodeid); 129 dlm_receive_buffer(p, nodeid);
123 } 130 }
124 131
125 if (msg != &__tmp.dlm) 132 if (p != &__tmp.p)
126 kfree(msg); 133 kfree(p);
127 134
128 return err ? err : ret; 135 return err ? err : ret;
129} 136}