aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/w1/w1_netlink.c44
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.