aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--fs/dlm/dlm_internal.h6
-rw-r--r--fs/dlm/lock.c19
-rw-r--r--fs/dlm/lock.h2
-rw-r--r--fs/dlm/midcomms.c33
4 files changed, 36 insertions, 24 deletions
diff --git a/fs/dlm/dlm_internal.h b/fs/dlm/dlm_internal.h
index ec61bbaf25df..65499ceaa516 100644
--- a/fs/dlm/dlm_internal.h
+++ b/fs/dlm/dlm_internal.h
@@ -403,6 +403,12 @@ struct dlm_rcom {
403 char rc_buf[0]; 403 char rc_buf[0];
404}; 404};
405 405
406union dlm_packet {
407 struct dlm_header header; /* common to other two */
408 struct dlm_message message;
409 struct dlm_rcom rcom;
410};
411
406struct rcom_config { 412struct rcom_config {
407 uint32_t rf_lvblen; 413 uint32_t rf_lvblen;
408 uint32_t rf_lsflags; 414 uint32_t rf_lsflags;
diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c
index d9f07a42e3cf..2a28048252ed 100644
--- a/fs/dlm/lock.c
+++ b/fs/dlm/lock.c
@@ -3822,21 +3822,20 @@ void dlm_receive_message_saved(struct dlm_ls *ls, struct dlm_message *ms)
3822 standard locking activity) or an RCOM (recovery message sent as part of 3822 standard locking activity) or an RCOM (recovery message sent as part of
3823 lockspace recovery). */ 3823 lockspace recovery). */
3824 3824
3825void dlm_receive_buffer(struct dlm_header *hd, int nodeid) 3825void dlm_receive_buffer(union dlm_packet *p, int nodeid)
3826{ 3826{
3827 struct dlm_message *ms = (struct dlm_message *) hd; 3827 struct dlm_header *hd = &p->header;
3828 struct dlm_rcom *rc = (struct dlm_rcom *) hd;
3829 struct dlm_ls *ls; 3828 struct dlm_ls *ls;
3830 int type = 0; 3829 int type = 0;
3831 3830
3832 switch (hd->h_cmd) { 3831 switch (hd->h_cmd) {
3833 case DLM_MSG: 3832 case DLM_MSG:
3834 dlm_message_in(ms); 3833 dlm_message_in(&p->message);
3835 type = ms->m_type; 3834 type = p->message.m_type;
3836 break; 3835 break;
3837 case DLM_RCOM: 3836 case DLM_RCOM:
3838 dlm_rcom_in(rc); 3837 dlm_rcom_in(&p->rcom);
3839 type = rc->rc_type; 3838 type = p->rcom.rc_type;
3840 break; 3839 break;
3841 default: 3840 default:
3842 log_print("invalid h_cmd %d from %u", hd->h_cmd, nodeid); 3841 log_print("invalid h_cmd %d from %u", hd->h_cmd, nodeid);
@@ -3856,7 +3855,7 @@ void dlm_receive_buffer(struct dlm_header *hd, int nodeid)
3856 hd->h_lockspace, nodeid, hd->h_cmd, type); 3855 hd->h_lockspace, nodeid, hd->h_cmd, type);
3857 3856
3858 if (hd->h_cmd == DLM_RCOM && type == DLM_RCOM_STATUS) 3857 if (hd->h_cmd == DLM_RCOM && type == DLM_RCOM_STATUS)
3859 dlm_send_ls_not_ready(nodeid, rc); 3858 dlm_send_ls_not_ready(nodeid, &p->rcom);
3860 return; 3859 return;
3861 } 3860 }
3862 3861
@@ -3865,9 +3864,9 @@ void dlm_receive_buffer(struct dlm_header *hd, int nodeid)
3865 3864
3866 down_read(&ls->ls_recv_active); 3865 down_read(&ls->ls_recv_active);
3867 if (hd->h_cmd == DLM_MSG) 3866 if (hd->h_cmd == DLM_MSG)
3868 dlm_receive_message(ls, ms, nodeid); 3867 dlm_receive_message(ls, &p->message, nodeid);
3869 else 3868 else
3870 dlm_receive_rcom(ls, rc, nodeid); 3869 dlm_receive_rcom(ls, &p->rcom, nodeid);
3871 up_read(&ls->ls_recv_active); 3870 up_read(&ls->ls_recv_active);
3872 3871
3873 dlm_put_lockspace(ls); 3872 dlm_put_lockspace(ls);
diff --git a/fs/dlm/lock.h b/fs/dlm/lock.h
index 27b6ed302911..05d9c82e646b 100644
--- a/fs/dlm/lock.h
+++ b/fs/dlm/lock.h
@@ -17,7 +17,7 @@ void dlm_print_rsb(struct dlm_rsb *r);
17void dlm_dump_rsb(struct dlm_rsb *r); 17void dlm_dump_rsb(struct dlm_rsb *r);
18void dlm_print_lkb(struct dlm_lkb *lkb); 18void dlm_print_lkb(struct dlm_lkb *lkb);
19void dlm_receive_message_saved(struct dlm_ls *ls, struct dlm_message *ms); 19void dlm_receive_message_saved(struct dlm_ls *ls, struct dlm_message *ms);
20void dlm_receive_buffer(struct dlm_header *hd, int nodeid); 20void dlm_receive_buffer(union dlm_packet *p, int nodeid);
21int dlm_modes_compat(int mode1, int mode2); 21int dlm_modes_compat(int mode1, int mode2);
22void dlm_put_rsb(struct dlm_rsb *r); 22void dlm_put_rsb(struct dlm_rsb *r);
23void dlm_hold_rsb(struct dlm_rsb *r); 23void dlm_hold_rsb(struct dlm_rsb *r);
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}