aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/params.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/params.c')
-rw-r--r--kernel/params.c97
1 files changed, 46 insertions, 51 deletions
diff --git a/kernel/params.c b/kernel/params.c
index db97b791390f..0af9b2c4e56c 100644
--- a/kernel/params.c
+++ b/kernel/params.c
@@ -603,74 +603,67 @@ static __modinit int add_sysfs_param(struct module_kobject *mk,
603 const struct kernel_param *kp, 603 const struct kernel_param *kp,
604 const char *name) 604 const char *name)
605{ 605{
606 struct module_param_attrs *new; 606 struct module_param_attrs *new_mp;
607 struct attribute **attrs; 607 struct attribute **new_attrs;
608 int err, num; 608 unsigned int i;
609 609
610 /* We don't bother calling this with invisible parameters. */ 610 /* We don't bother calling this with invisible parameters. */
611 BUG_ON(!kp->perm); 611 BUG_ON(!kp->perm);
612 612
613 if (!mk->mp) { 613 if (!mk->mp) {
614 num = 0; 614 /* First allocation. */
615 attrs = NULL; 615 mk->mp = kzalloc(sizeof(*mk->mp), GFP_KERNEL);
616 } else { 616 if (!mk->mp)
617 num = mk->mp->num; 617 return -ENOMEM;
618 attrs = mk->mp->grp.attrs; 618 mk->mp->grp.name = "parameters";
619 /* NULL-terminated attribute array. */
620 mk->mp->grp.attrs = kzalloc(sizeof(mk->mp->grp.attrs[0]),
621 GFP_KERNEL);
622 /* Caller will cleanup via free_module_param_attrs */
623 if (!mk->mp->grp.attrs)
624 return -ENOMEM;
619 } 625 }
620 626
621 /* Enlarge. */ 627 /* Enlarge allocations. */
622 new = krealloc(mk->mp, 628 new_mp = krealloc(mk->mp,
623 sizeof(*mk->mp) + sizeof(mk->mp->attrs[0]) * (num+1), 629 sizeof(*mk->mp) +
624 GFP_KERNEL); 630 sizeof(mk->mp->attrs[0]) * (mk->mp->num + 1),
625 if (!new) { 631 GFP_KERNEL);
626 kfree(attrs); 632 if (!new_mp)
627 err = -ENOMEM; 633 return -ENOMEM;
628 goto fail; 634 mk->mp = new_mp;
629 }
630 /* Despite looking like the typical realloc() bug, this is safe.
631 * We *want* the old 'attrs' to be freed either way, and we'll store
632 * the new one in the success case. */
633 attrs = krealloc(attrs, sizeof(new->grp.attrs[0])*(num+2), GFP_KERNEL);
634 if (!attrs) {
635 err = -ENOMEM;
636 goto fail_free_new;
637 }
638 635
639 /* Sysfs wants everything zeroed. */ 636 /* Extra pointer for NULL terminator */
640 memset(new, 0, sizeof(*new)); 637 new_attrs = krealloc(mk->mp->grp.attrs,
641 memset(&new->attrs[num], 0, sizeof(new->attrs[num])); 638 sizeof(mk->mp->grp.attrs[0]) * (mk->mp->num + 2),
642 memset(&attrs[num], 0, sizeof(attrs[num])); 639 GFP_KERNEL);
643 new->grp.name = "parameters"; 640 if (!new_attrs)
644 new->grp.attrs = attrs; 641 return -ENOMEM;
642 mk->mp->grp.attrs = new_attrs;
645 643
646 /* Tack new one on the end. */ 644 /* Tack new one on the end. */
647 sysfs_attr_init(&new->attrs[num].mattr.attr); 645 sysfs_attr_init(&mk->mp->attrs[mk->mp->num].mattr.attr);
648 new->attrs[num].param = kp; 646 mk->mp->attrs[mk->mp->num].param = kp;
649 new->attrs[num].mattr.show = param_attr_show; 647 mk->mp->attrs[mk->mp->num].mattr.show = param_attr_show;
650 new->attrs[num].mattr.store = param_attr_store; 648 /* Do not allow runtime DAC changes to make param writable. */
651 new->attrs[num].mattr.attr.name = (char *)name; 649 if ((kp->perm & (S_IWUSR | S_IWGRP | S_IWOTH)) != 0)
652 new->attrs[num].mattr.attr.mode = kp->perm; 650 mk->mp->attrs[mk->mp->num].mattr.store = param_attr_store;
653 new->num = num+1; 651 mk->mp->attrs[mk->mp->num].mattr.attr.name = (char *)name;
652 mk->mp->attrs[mk->mp->num].mattr.attr.mode = kp->perm;
653 mk->mp->num++;
654 654
655 /* Fix up all the pointers, since krealloc can move us */ 655 /* Fix up all the pointers, since krealloc can move us */
656 for (num = 0; num < new->num; num++) 656 for (i = 0; i < mk->mp->num; i++)
657 new->grp.attrs[num] = &new->attrs[num].mattr.attr; 657 mk->mp->grp.attrs[i] = &mk->mp->attrs[i].mattr.attr;
658 new->grp.attrs[num] = NULL; 658 mk->mp->grp.attrs[mk->mp->num] = NULL;
659
660 mk->mp = new;
661 return 0; 659 return 0;
662
663fail_free_new:
664 kfree(new);
665fail:
666 mk->mp = NULL;
667 return err;
668} 660}
669 661
670#ifdef CONFIG_MODULES 662#ifdef CONFIG_MODULES
671static void free_module_param_attrs(struct module_kobject *mk) 663static void free_module_param_attrs(struct module_kobject *mk)
672{ 664{
673 kfree(mk->mp->grp.attrs); 665 if (mk->mp)
666 kfree(mk->mp->grp.attrs);
674 kfree(mk->mp); 667 kfree(mk->mp);
675 mk->mp = NULL; 668 mk->mp = NULL;
676} 669}
@@ -695,8 +688,10 @@ int module_param_sysfs_setup(struct module *mod,
695 if (kparam[i].perm == 0) 688 if (kparam[i].perm == 0)
696 continue; 689 continue;
697 err = add_sysfs_param(&mod->mkobj, &kparam[i], kparam[i].name); 690 err = add_sysfs_param(&mod->mkobj, &kparam[i], kparam[i].name);
698 if (err) 691 if (err) {
692 free_module_param_attrs(&mod->mkobj);
699 return err; 693 return err;
694 }
700 params = true; 695 params = true;
701 } 696 }
702 697