diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2008-01-25 00:58:46 -0500 |
---|---|---|
committer | David Teigland <teigland@redhat.com> | 2008-02-04 02:22:42 -0500 |
commit | eef7d739c218cb2546cf95686db77de0d76e4122 (patch) | |
tree | 4d6c0e65e8aff1afb2c6428c729a98274ccb1a6d /fs/dlm | |
parent | 8b0d8e03f847d9c1677b8a193cd124debbc54633 (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')
-rw-r--r-- | fs/dlm/dlm_internal.h | 6 | ||||
-rw-r--r-- | fs/dlm/lock.c | 19 | ||||
-rw-r--r-- | fs/dlm/lock.h | 2 | ||||
-rw-r--r-- | fs/dlm/midcomms.c | 33 |
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 | ||
406 | union dlm_packet { | ||
407 | struct dlm_header header; /* common to other two */ | ||
408 | struct dlm_message message; | ||
409 | struct dlm_rcom rcom; | ||
410 | }; | ||
411 | |||
406 | struct rcom_config { | 412 | struct 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 | ||
3825 | void dlm_receive_buffer(struct dlm_header *hd, int nodeid) | 3825 | void 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); | |||
17 | void dlm_dump_rsb(struct dlm_rsb *r); | 17 | void dlm_dump_rsb(struct dlm_rsb *r); |
18 | void dlm_print_lkb(struct dlm_lkb *lkb); | 18 | void dlm_print_lkb(struct dlm_lkb *lkb); |
19 | void dlm_receive_message_saved(struct dlm_ls *ls, struct dlm_message *ms); | 19 | void dlm_receive_message_saved(struct dlm_ls *ls, struct dlm_message *ms); |
20 | void dlm_receive_buffer(struct dlm_header *hd, int nodeid); | 20 | void dlm_receive_buffer(union dlm_packet *p, int nodeid); |
21 | int dlm_modes_compat(int mode1, int mode2); | 21 | int dlm_modes_compat(int mode1, int mode2); |
22 | void dlm_put_rsb(struct dlm_rsb *r); | 22 | void dlm_put_rsb(struct dlm_rsb *r); |
23 | void dlm_hold_rsb(struct dlm_rsb *r); | 23 | void 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 | } |