aboutsummaryrefslogtreecommitdiffstats
path: root/target
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2010-01-18 00:12:07 +0000
committerFelix Fietkau <nbd@openwrt.org>2010-01-18 00:12:07 +0000
commitb228fd428a7881ed73152b0a6458210e78744bc4 (patch)
treec78d02919859919507ec88ff1f7aeb6ea5e941f5 /target
parent8394a3281524dad20c5e6209267f63880200d24c (diff)
downloadupstream-b228fd428a7881ed73152b0a6458210e78744bc4.tar.gz
upstream-b228fd428a7881ed73152b0a6458210e78744bc4.tar.bz2
upstream-b228fd428a7881ed73152b0a6458210e78744bc4.zip
rtl8366_smi: fix excessive stack usage and buffer handling bugs
SVN-Revision: 19205
Diffstat (limited to 'target')
-rw-r--r--target/linux/ar71xx/files/drivers/net/phy/rtl8366_smi.c102
1 files changed, 52 insertions, 50 deletions
diff --git a/target/linux/ar71xx/files/drivers/net/phy/rtl8366_smi.c b/target/linux/ar71xx/files/drivers/net/phy/rtl8366_smi.c
index e2172f1b90..72ead316c5 100644
--- a/target/linux/ar71xx/files/drivers/net/phy/rtl8366_smi.c
+++ b/target/linux/ar71xx/files/drivers/net/phy/rtl8366_smi.c
@@ -209,6 +209,7 @@ struct rtl8366_smi {
struct mii_bus *mii_bus;
struct switch_dev dev;
int mii_irq[PHY_MAX_ADDR];
+ char buf[4096];
#ifdef DEBUG
struct dentry *debugfs_root;
#endif
@@ -975,44 +976,44 @@ static ssize_t rtl8366_read_debugfs_mibs(struct file *file,
char __user *user_buf,
size_t count, loff_t *ppos)
{
- char buf[4096];
int i, j, len = 0;
struct rtl8366_smi *smi = (struct rtl8366_smi *)file->private_data;
+ char *buf = smi->buf;
- len += snprintf(buf + len, sizeof(buf) - len, "MIB Counters:\n");
- len += snprintf(buf + len, sizeof(buf) - len, "Counter"
+ len += snprintf(buf + len, sizeof(smi->buf) - len, "MIB Counters:\n");
+ len += snprintf(buf + len, sizeof(smi->buf) - len, "Counter"
" "
"Port 0 \t\t Port 1 \t\t Port 2 \t\t Port 3 \t\t "
"Port 4\n");
for (i = 0; i < 33; ++i) {
- len += snprintf(buf + len, sizeof(buf) - len, "%d:%s ",
+ len += snprintf(buf + len, sizeof(smi->buf) - len, "%d:%s ",
i, MIBCOUNTERS[i]);
for (j = 0; j < RTL8366_NUM_PORTS; ++j) {
unsigned long long counter = 0;
if (!rtl8366_get_mib_counter(smi, i, j, &counter))
- len += snprintf(buf + len, sizeof(buf) - len,
+ len += snprintf(buf + len, sizeof(smi->buf) - len,
"[%llu]", counter);
else
- len += snprintf(buf + len, sizeof(buf) - len,
+ len += snprintf(buf + len, sizeof(smi->buf) - len,
"[error]");
if (j != RTL8366_NUM_PORTS - 1) {
if (counter < 100000)
len += snprintf(buf + len,
- sizeof(buf) - len,
+ sizeof(smi->buf) - len,
"\t");
- len += snprintf(buf + len, sizeof(buf) - len,
+ len += snprintf(buf + len, sizeof(smi->buf) - len,
"\t");
}
}
- len += snprintf(buf + len, sizeof(buf) - len, "\n");
+ len += snprintf(buf + len, sizeof(smi->buf) - len, "\n");
}
- len += snprintf(buf + len, sizeof(buf) - len, "\n");
+ len += snprintf(buf + len, sizeof(smi->buf) - len, "\n");
return simple_read_from_buffer(user_buf, count, ppos, buf, len);
}
@@ -1021,12 +1022,12 @@ static ssize_t rtl8366_read_debugfs_vlan(struct file *file,
char __user *user_buf,
size_t count, loff_t *ppos)
{
- char buf[4096];
int i, j, len = 0;
struct rtl8366_smi *smi = (struct rtl8366_smi *)file->private_data;
+ char *buf = smi->buf;
- len += snprintf(buf + len, sizeof(buf) - len, "VLAN Member Config:\n");
- len += snprintf(buf + len, sizeof(buf) - len,
+ len += snprintf(buf + len, sizeof(smi->buf) - len, "VLAN Member Config:\n");
+ len += snprintf(buf + len, sizeof(smi->buf) - len,
"\t id \t vid \t prio \t member \t untag \t fid "
"\tports\n");
@@ -1035,7 +1036,7 @@ static ssize_t rtl8366_read_debugfs_vlan(struct file *file,
rtl8366s_get_vlan_member_config(smi, i, &vlanmc);
- len += snprintf(buf + len, sizeof(buf) - len,
+ len += snprintf(buf + len, sizeof(smi->buf) - len,
"\t[%d] \t %d \t %d \t 0x%04x \t 0x%04x \t %d "
"\t", i, vlanmc.vid, vlanmc.priority,
vlanmc.member, vlanmc.untag, vlanmc.fid);
@@ -1045,11 +1046,11 @@ static ssize_t rtl8366_read_debugfs_vlan(struct file *file,
if (!rtl8366_get_port_vlan_index(smi, j, &index)) {
if (index == i)
len += snprintf(buf + len,
- sizeof(buf) - len,
+ sizeof(smi->buf) - len,
"%d", j);
}
}
- len += snprintf(buf + len, sizeof(buf) - len, "\n");
+ len += snprintf(buf + len, sizeof(smi->buf) - len, "\n");
}
return simple_read_from_buffer(user_buf, count, ppos, buf, len);
@@ -1061,19 +1062,19 @@ static ssize_t rtl8366_read_debugfs_reg(struct file *file,
{
u32 t, reg = g_dbg_reg;
int err, len = 0;
- char buf[512];
struct rtl8366_smi *smi = (struct rtl8366_smi *)file->private_data;
+ char *buf = smi->buf;
- memset(buf, '\0', sizeof(buf));
+ memset(buf, '\0', sizeof(smi->buf));
err = rtl8366_smi_read_reg(smi, reg, &t);
if (err) {
- len += snprintf(buf, sizeof(buf),
+ len += snprintf(buf, sizeof(smi->buf),
"Read failed (reg: 0x%04x)\n", reg);
return simple_read_from_buffer(user_buf, count, ppos, buf, len);
}
- len += snprintf(buf, sizeof(buf), "reg = 0x%04x, val = 0x%04x\n",
+ len += snprintf(buf, sizeof(smi->buf), "reg = 0x%04x, val = 0x%04x\n",
reg, t);
return simple_read_from_buffer(user_buf, count, ppos, buf, len);
@@ -1086,11 +1087,11 @@ static ssize_t rtl8366_write_debugfs_reg(struct file *file,
unsigned long data;
u32 reg = g_dbg_reg;
int err;
- char buf[50];
size_t len;
struct rtl8366_smi *smi = (struct rtl8366_smi *)file->private_data;
+ char *buf = smi->buf;
- len = min(count, sizeof(buf) - 1);
+ len = min(count, sizeof(smi->buf) - 1);
if (copy_from_user(buf, user_buf, len)) {
dev_err(&smi->pdev->dev, "copy from user failed\n");
return -EFAULT;
@@ -1290,15 +1291,15 @@ static int rtl8366_attr_get_port_link(struct switch_dev *dev,
const struct switch_attr *attr,
struct switch_val *val)
{
- char buf[1024];
u32 len = 0, data = 0;
int speed, duplex, link, txpause, rxpause, nway;
struct rtl8366_smi *smi = to_rtl8366(dev);
+ char *buf = smi->buf;
if (val->port_vlan >= RTL8366_NUM_PORTS)
return -EINVAL;
- memset(buf, '\0', sizeof(buf));
+ memset(buf, '\0', sizeof(smi->buf));
rtl8366_smi_read_reg(smi, RTL8366S_PORT_LINK_STATUS_BASE +
(val->port_vlan >> 1),
&data);
@@ -1313,34 +1314,34 @@ static int rtl8366_attr_get_port_link(struct switch_dev *dev,
rxpause = (data & RTL8366S_PORT_STATUS_RXPAUSE_MASK) >> 6;
nway = (data & RTL8366S_PORT_STATUS_AN_MASK) >> 7;
- len += snprintf(buf + len, sizeof(buf) - len, "Port %d: ",
+ len += snprintf(buf + len, sizeof(smi->buf) - len, "Port %d: ",
val->port_vlan);
if (link)
- len += snprintf(buf + len, sizeof(buf) - len,
+ len += snprintf(buf + len, sizeof(smi->buf) - len,
"Link UP, Speed: ");
else
- len += snprintf(buf + len, sizeof(buf) - len,
+ len += snprintf(buf + len, sizeof(smi->buf) - len,
"Link DOWN, Speed: ");
if (speed == 0)
- len += snprintf(buf + len, sizeof(buf) - len, "10Base-TX ");
+ len += snprintf(buf + len, sizeof(smi->buf) - len, "10Base-TX ");
else if (speed == 1)
- len += snprintf(buf + len, sizeof(buf) - len, "100Base-TX ");
+ len += snprintf(buf + len, sizeof(smi->buf) - len, "100Base-TX ");
else if (speed == 2)
- len += snprintf(buf + len, sizeof(buf) - len, "1000Base-TX ");
+ len += snprintf(buf + len, sizeof(smi->buf) - len, "1000Base-TX ");
if (duplex)
- len += snprintf(buf + len, sizeof(buf) - len, "Full-Duplex, ");
+ len += snprintf(buf + len, sizeof(smi->buf) - len, "Full-Duplex, ");
else
- len += snprintf(buf + len, sizeof(buf) - len, "Half-Duplex, ");
+ len += snprintf(buf + len, sizeof(smi->buf) - len, "Half-Duplex, ");
if (txpause)
- len += snprintf(buf + len, sizeof(buf) - len, "TX-Pause ");
+ len += snprintf(buf + len, sizeof(smi->buf) - len, "TX-Pause ");
if (rxpause)
- len += snprintf(buf + len, sizeof(buf) - len, "RX-Pause ");
+ len += snprintf(buf + len, sizeof(smi->buf) - len, "RX-Pause ");
if (nway)
- len += snprintf(buf + len, sizeof(buf) - len, "nway ");
+ len += snprintf(buf + len, sizeof(smi->buf) - len, "nway ");
val->value.s = buf;
val->len = len;
@@ -1353,40 +1354,40 @@ static int rtl8366_attr_get_vlan_info(struct switch_dev *dev,
struct switch_val *val)
{
int i;
- char buf[1024];
u32 len = 0;
struct rtl8366s_vlanconfig vlanmc;
struct rtl8366s_vlan4kentry vlan4k;
struct rtl8366_smi *smi = to_rtl8366(dev);
+ char *buf = smi->buf;
if (val->port_vlan >= RTL8366_NUM_PORTS)
return -EINVAL;
- memset(buf, '\0', sizeof(buf));
+ memset(buf, '\0', sizeof(smi->buf));
rtl8366s_get_vlan_member_config(smi, val->port_vlan, &vlanmc);
rtl8366s_get_vlan_4k_entry(smi, vlanmc.vid, &vlan4k);
- len += snprintf(buf + len, sizeof(buf) - len, "VLAN %d: Ports: ",
+ len += snprintf(buf + len, sizeof(smi->buf) - len, "VLAN %d: Ports: ",
val->port_vlan);
for (i = 0; i < RTL8366_NUM_PORTS; ++i) {
int index = 0;
if (!rtl8366_get_port_vlan_index(smi, i, &index) &&
index == val->port_vlan)
- len += snprintf(buf + len, sizeof(buf) - len, "%d", i);
+ len += snprintf(buf + len, sizeof(smi->buf) - len, "%d", i);
}
- len += snprintf(buf + len, sizeof(buf) - len, "\n");
+ len += snprintf(buf + len, sizeof(smi->buf) - len, "\n");
- len += snprintf(buf + len, sizeof(buf) - len,
+ len += snprintf(buf + len, sizeof(smi->buf) - len,
"\t\t vid \t prio \t member \t untag \t fid\n");
- len += snprintf(buf + len, sizeof(buf) - len, "\tMC:\t");
- len += snprintf(buf + len, sizeof(buf) - len,
+ len += snprintf(buf + len, sizeof(smi->buf) - len, "\tMC:\t");
+ len += snprintf(buf + len, sizeof(smi->buf) - len,
"%d \t %d \t 0x%04x \t 0x%04x \t %d\n",
vlanmc.vid, vlanmc.priority, vlanmc.member,
vlanmc.untag, vlanmc.fid);
- len += snprintf(buf + len, sizeof(buf) - len, "\t4K:\t");
- len += snprintf(buf + len, sizeof(buf) - len,
+ len += snprintf(buf + len, sizeof(smi->buf) - len, "\t4K:\t");
+ len += snprintf(buf + len, sizeof(smi->buf) - len,
"%d \t \t 0x%04x \t 0x%04x \t %d",
vlan4k.vid, vlan4k.member, vlan4k.untag, vlan4k.fid);
@@ -1455,24 +1456,25 @@ static int rtl8366_get_port_mib(struct switch_dev *dev,
const struct switch_attr *attr,
struct switch_val *val)
{
- char buf[2048];
int i, len = 0;
unsigned long long counter = 0;
struct rtl8366_smi *smi = to_rtl8366(dev);
+ char *buf = smi->buf;
+
if (val->port_vlan >= RTL8366_NUM_PORTS)
return -EINVAL;
- len += snprintf(buf + len, sizeof(buf) - len, "Port %d MIB counters\n",
+ len += snprintf(buf + len, sizeof(smi->buf) - len, "Port %d MIB counters\n",
val->port_vlan);
for (i = 0; i < RTL8366S_MIB_COUNT; ++i) {
- len += snprintf(buf + len, sizeof(buf) - len,
+ len += snprintf(buf + len, sizeof(smi->buf) - len,
"%d:%s\t", i, MIBCOUNTERS[i]);
if (!rtl8366_get_mib_counter(smi, i, val->port_vlan, &counter))
- len += snprintf(buf + len, sizeof(buf) - len,
+ len += snprintf(buf + len, sizeof(smi->buf) - len,
"[%llu]\n", counter);
else
- len += snprintf(buf + len, sizeof(buf) - len,
+ len += snprintf(buf + len, sizeof(smi->buf) - len,
"[error]\n");
}
616'>616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759