static int check_config(struct dlm_ls *ls, struct dlm_rcom *rc, int nodeid)
{
struct rcom_config *rf = (struct rcom_config *) rc->rc_buf;
+ size_t conf_size = sizeof(struct dlm_rcom) + sizeof(struct rcom_config);
if ((rc->rc_header.h_version & 0xFFFF0000) != DLM_HEADER_MAJOR) {
log_error(ls, "version mismatch: %x nodeid %d: %x",
return -EPROTO;
}
+ if (rc->rc_header.h_length < conf_size) {
+ log_error(ls, "config too short: %d nodeid %d",
+ rc->rc_header.h_length, nodeid);
+ return -EPROTO;
+ }
+
if (le32_to_cpu(rf->rf_lvblen) != ls->ls_lvblen ||
le32_to_cpu(rf->rf_lsflags) != ls->ls_exflags) {
log_error(ls, "config mismatch: %d,%x nodeid %d: %d,%x",
ls->ls_recover_nodeid = nodeid;
if (nodeid == dlm_our_nodeid()) {
+ ls->ls_recover_buf->rc_header.h_length =
+ dlm_config.ci_buffer_size;
dlm_copy_master_names(ls, last_name, last_len,
ls->ls_recover_buf->rc_buf,
max_size, nodeid);
rl->rl_status = lkb->lkb_status;
rl->rl_wait_type = cpu_to_le16(lkb->lkb_wait_type);
- if (lkb->lkb_bastaddr)
+ if (lkb->lkb_bastfn)
rl->rl_asts |= AST_BAST;
- if (lkb->lkb_astaddr)
+ if (lkb->lkb_astfn)
rl->rl_asts |= AST_COMP;
rl->rl_namelen = cpu_to_le16(r->res_length);
return error;
}
+/* needs at least dlm_rcom + rcom_lock */
static void receive_rcom_lock(struct dlm_ls *ls, struct dlm_rcom *rc_in)
{
struct dlm_rcom *rc;
void dlm_receive_rcom(struct dlm_ls *ls, struct dlm_rcom *rc, int nodeid)
{
+ int lock_size = sizeof(struct dlm_rcom) + sizeof(struct rcom_lock);
+
if (dlm_recovery_stopped(ls) && (rc->rc_type != DLM_RCOM_STATUS)) {
log_debug(ls, "ignoring recovery message %x from %d",
rc->rc_type, nodeid);
break;
case DLM_RCOM_LOCK:
+ if (rc->rc_header.h_length < lock_size)
+ goto Eshort;
receive_rcom_lock(ls, rc);
break;
break;
case DLM_RCOM_LOCK_REPLY:
+ if (rc->rc_header.h_length < lock_size)
+ goto Eshort;
dlm_recover_process_copy(ls, rc);
break;
default:
log_error(ls, "receive_rcom bad type %d", rc->rc_type);
}
- out:
+out:
return;
+Eshort:
+ log_error(ls, "recovery message %x from %d is too short",
+ rc->rc_type, nodeid);
}