diff options
Diffstat (limited to 'fs/dlm/midcomms.c')
-rw-r--r-- | fs/dlm/midcomms.c | 33 |
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 | } |