diff options
-rw-r--r-- | drivers/w1/w1_netlink.c | 44 |
1 files changed, 26 insertions, 18 deletions
diff --git a/drivers/w1/w1_netlink.c b/drivers/w1/w1_netlink.c index 5234964fe001..a02704a59321 100644 --- a/drivers/w1/w1_netlink.c +++ b/drivers/w1/w1_netlink.c | |||
@@ -300,12 +300,6 @@ static int w1_process_command_root(struct cn_msg *msg, | |||
300 | struct w1_netlink_msg *w; | 300 | struct w1_netlink_msg *w; |
301 | u32 *id; | 301 | u32 *id; |
302 | 302 | ||
303 | if (mcmd->type != W1_LIST_MASTERS) { | ||
304 | printk(KERN_NOTICE "%s: msg: %x.%x, wrong type: %u, len: %u.\n", | ||
305 | __func__, msg->id.idx, msg->id.val, mcmd->type, mcmd->len); | ||
306 | return -EPROTO; | ||
307 | } | ||
308 | |||
309 | cn = kmalloc(PAGE_SIZE, GFP_KERNEL); | 303 | cn = kmalloc(PAGE_SIZE, GFP_KERNEL); |
310 | if (!cn) | 304 | if (!cn) |
311 | return -ENOMEM; | 305 | return -ENOMEM; |
@@ -441,6 +435,9 @@ static void w1_process_cb(struct w1_master *dev, struct w1_async_cmd *async_cmd) | |||
441 | w1_netlink_send_error(&node->block->msg, node->m, cmd, | 435 | w1_netlink_send_error(&node->block->msg, node->m, cmd, |
442 | node->block->portid, err); | 436 | node->block->portid, err); |
443 | 437 | ||
438 | /* ref taken in w1_search_slave or w1_search_master_id when building | ||
439 | * the block | ||
440 | */ | ||
444 | if (sl) | 441 | if (sl) |
445 | w1_unref_slave(sl); | 442 | w1_unref_slave(sl); |
446 | else | 443 | else |
@@ -503,30 +500,42 @@ static void w1_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp) | |||
503 | 500 | ||
504 | msg_len = msg->len; | 501 | msg_len = msg->len; |
505 | while (msg_len && !err) { | 502 | while (msg_len && !err) { |
506 | struct w1_reg_num id; | ||
507 | u16 mlen = m->len; | ||
508 | 503 | ||
509 | dev = NULL; | 504 | dev = NULL; |
510 | sl = NULL; | 505 | sl = NULL; |
511 | 506 | ||
512 | memcpy(&id, m->id.id, sizeof(id)); | ||
513 | #if 0 | ||
514 | printk("%s: %02x.%012llx.%02x: type=%02x, len=%u.\n", | ||
515 | __func__, id.family, (unsigned long long)id.id, id.crc, m->type, m->len); | ||
516 | #endif | ||
517 | if (m->len + sizeof(struct w1_netlink_msg) > msg_len) { | 507 | if (m->len + sizeof(struct w1_netlink_msg) > msg_len) { |
518 | err = -E2BIG; | 508 | err = -E2BIG; |
519 | break; | 509 | break; |
520 | } | 510 | } |
521 | 511 | ||
512 | /* execute on this thread, no need to process later */ | ||
513 | if (m->type == W1_LIST_MASTERS) { | ||
514 | err = w1_process_command_root(msg, m, nsp->portid); | ||
515 | goto out_cont; | ||
516 | } | ||
517 | |||
518 | /* All following message types require additional data, | ||
519 | * check here before references are taken. | ||
520 | */ | ||
521 | if (!m->len) { | ||
522 | err = -EPROTO; | ||
523 | goto out_cont; | ||
524 | } | ||
525 | |||
526 | /* both search calls take reference counts */ | ||
522 | if (m->type == W1_MASTER_CMD) { | 527 | if (m->type == W1_MASTER_CMD) { |
523 | dev = w1_search_master_id(m->id.mst.id); | 528 | dev = w1_search_master_id(m->id.mst.id); |
524 | } else if (m->type == W1_SLAVE_CMD) { | 529 | } else if (m->type == W1_SLAVE_CMD) { |
525 | sl = w1_search_slave(&id); | 530 | sl = w1_search_slave((struct w1_reg_num *)m->id.id); |
526 | if (sl) | 531 | if (sl) |
527 | dev = sl->master; | 532 | dev = sl->master; |
528 | } else { | 533 | } else { |
529 | err = w1_process_command_root(msg, m, nsp->portid); | 534 | printk(KERN_NOTICE |
535 | "%s: msg: %x.%x, wrong type: %u, len: %u.\n", | ||
536 | __func__, msg->id.idx, msg->id.val, | ||
537 | m->type, m->len); | ||
538 | err = -EPROTO; | ||
530 | goto out_cont; | 539 | goto out_cont; |
531 | } | 540 | } |
532 | 541 | ||
@@ -536,8 +545,6 @@ static void w1_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp) | |||
536 | } | 545 | } |
537 | 546 | ||
538 | err = 0; | 547 | err = 0; |
539 | if (!mlen) | ||
540 | goto out_cont; | ||
541 | 548 | ||
542 | atomic_inc(&block->refcnt); | 549 | atomic_inc(&block->refcnt); |
543 | node->async.cb = w1_process_cb; | 550 | node->async.cb = w1_process_cb; |
@@ -557,7 +564,8 @@ out_cont: | |||
557 | if (err) | 564 | if (err) |
558 | w1_netlink_send_error(msg, m, NULL, nsp->portid, err); | 565 | w1_netlink_send_error(msg, m, NULL, nsp->portid, err); |
559 | msg_len -= sizeof(struct w1_netlink_msg) + m->len; | 566 | msg_len -= sizeof(struct w1_netlink_msg) + m->len; |
560 | m = (struct w1_netlink_msg *)(((u8 *)m) + sizeof(struct w1_netlink_msg) + m->len); | 567 | m = (struct w1_netlink_msg *)(((u8 *)m) + |
568 | sizeof(struct w1_netlink_msg) + m->len); | ||
561 | 569 | ||
562 | /* | 570 | /* |
563 | * Let's allow requests for nonexisting devices. | 571 | * Let's allow requests for nonexisting devices. |