diff options
Diffstat (limited to 'drivers/w1/w1_netlink.c')
| -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. |
