diff options
author | Mathias Krause <minipli@googlemail.com> | 2013-03-09 00:52:21 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-03-10 05:19:26 -0400 |
commit | 29cd8ae0e1a39e239a3a7b67da1986add1199fc0 (patch) | |
tree | b3e9cf667e8f13d15bc2fb76d8f44557a6f65202 /net/dcb | |
parent | 84d73cd3fb142bf1298a8c13fd4ca50fd2432372 (diff) |
dcbnl: fix various netlink info leaks
The dcb netlink interface leaks stack memory in various places:
* perm_addr[] buffer is only filled at max with 12 of the 32 bytes but
copied completely,
* no in-kernel driver fills all fields of an IEEE 802.1Qaz subcommand,
so we're leaking up to 58 bytes for ieee_ets structs, up to 136 bytes
for ieee_pfc structs, etc.,
* the same is true for CEE -- no in-kernel driver fills the whole
struct,
Prevent all of the above stack info leaks by properly initializing the
buffers/structures involved.
Signed-off-by: Mathias Krause <minipli@googlemail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/dcb')
-rw-r--r-- | net/dcb/dcbnl.c | 8 |
1 files changed, 8 insertions, 0 deletions
diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c index 1b588e23cf80..21291f1abcd6 100644 --- a/net/dcb/dcbnl.c +++ b/net/dcb/dcbnl.c | |||
@@ -284,6 +284,7 @@ static int dcbnl_getperm_hwaddr(struct net_device *netdev, struct nlmsghdr *nlh, | |||
284 | if (!netdev->dcbnl_ops->getpermhwaddr) | 284 | if (!netdev->dcbnl_ops->getpermhwaddr) |
285 | return -EOPNOTSUPP; | 285 | return -EOPNOTSUPP; |
286 | 286 | ||
287 | memset(perm_addr, 0, sizeof(perm_addr)); | ||
287 | netdev->dcbnl_ops->getpermhwaddr(netdev, perm_addr); | 288 | netdev->dcbnl_ops->getpermhwaddr(netdev, perm_addr); |
288 | 289 | ||
289 | return nla_put(skb, DCB_ATTR_PERM_HWADDR, sizeof(perm_addr), perm_addr); | 290 | return nla_put(skb, DCB_ATTR_PERM_HWADDR, sizeof(perm_addr), perm_addr); |
@@ -1042,6 +1043,7 @@ static int dcbnl_ieee_fill(struct sk_buff *skb, struct net_device *netdev) | |||
1042 | 1043 | ||
1043 | if (ops->ieee_getets) { | 1044 | if (ops->ieee_getets) { |
1044 | struct ieee_ets ets; | 1045 | struct ieee_ets ets; |
1046 | memset(&ets, 0, sizeof(ets)); | ||
1045 | err = ops->ieee_getets(netdev, &ets); | 1047 | err = ops->ieee_getets(netdev, &ets); |
1046 | if (!err && | 1048 | if (!err && |
1047 | nla_put(skb, DCB_ATTR_IEEE_ETS, sizeof(ets), &ets)) | 1049 | nla_put(skb, DCB_ATTR_IEEE_ETS, sizeof(ets), &ets)) |
@@ -1050,6 +1052,7 @@ static int dcbnl_ieee_fill(struct sk_buff *skb, struct net_device *netdev) | |||
1050 | 1052 | ||
1051 | if (ops->ieee_getmaxrate) { | 1053 | if (ops->ieee_getmaxrate) { |
1052 | struct ieee_maxrate maxrate; | 1054 | struct ieee_maxrate maxrate; |
1055 | memset(&maxrate, 0, sizeof(maxrate)); | ||
1053 | err = ops->ieee_getmaxrate(netdev, &maxrate); | 1056 | err = ops->ieee_getmaxrate(netdev, &maxrate); |
1054 | if (!err) { | 1057 | if (!err) { |
1055 | err = nla_put(skb, DCB_ATTR_IEEE_MAXRATE, | 1058 | err = nla_put(skb, DCB_ATTR_IEEE_MAXRATE, |
@@ -1061,6 +1064,7 @@ static int dcbnl_ieee_fill(struct sk_buff *skb, struct net_device *netdev) | |||
1061 | 1064 | ||
1062 | if (ops->ieee_getpfc) { | 1065 | if (ops->ieee_getpfc) { |
1063 | struct ieee_pfc pfc; | 1066 | struct ieee_pfc pfc; |
1067 | memset(&pfc, 0, sizeof(pfc)); | ||
1064 | err = ops->ieee_getpfc(netdev, &pfc); | 1068 | err = ops->ieee_getpfc(netdev, &pfc); |
1065 | if (!err && | 1069 | if (!err && |
1066 | nla_put(skb, DCB_ATTR_IEEE_PFC, sizeof(pfc), &pfc)) | 1070 | nla_put(skb, DCB_ATTR_IEEE_PFC, sizeof(pfc), &pfc)) |
@@ -1094,6 +1098,7 @@ static int dcbnl_ieee_fill(struct sk_buff *skb, struct net_device *netdev) | |||
1094 | /* get peer info if available */ | 1098 | /* get peer info if available */ |
1095 | if (ops->ieee_peer_getets) { | 1099 | if (ops->ieee_peer_getets) { |
1096 | struct ieee_ets ets; | 1100 | struct ieee_ets ets; |
1101 | memset(&ets, 0, sizeof(ets)); | ||
1097 | err = ops->ieee_peer_getets(netdev, &ets); | 1102 | err = ops->ieee_peer_getets(netdev, &ets); |
1098 | if (!err && | 1103 | if (!err && |
1099 | nla_put(skb, DCB_ATTR_IEEE_PEER_ETS, sizeof(ets), &ets)) | 1104 | nla_put(skb, DCB_ATTR_IEEE_PEER_ETS, sizeof(ets), &ets)) |
@@ -1102,6 +1107,7 @@ static int dcbnl_ieee_fill(struct sk_buff *skb, struct net_device *netdev) | |||
1102 | 1107 | ||
1103 | if (ops->ieee_peer_getpfc) { | 1108 | if (ops->ieee_peer_getpfc) { |
1104 | struct ieee_pfc pfc; | 1109 | struct ieee_pfc pfc; |
1110 | memset(&pfc, 0, sizeof(pfc)); | ||
1105 | err = ops->ieee_peer_getpfc(netdev, &pfc); | 1111 | err = ops->ieee_peer_getpfc(netdev, &pfc); |
1106 | if (!err && | 1112 | if (!err && |
1107 | nla_put(skb, DCB_ATTR_IEEE_PEER_PFC, sizeof(pfc), &pfc)) | 1113 | nla_put(skb, DCB_ATTR_IEEE_PEER_PFC, sizeof(pfc), &pfc)) |
@@ -1280,6 +1286,7 @@ static int dcbnl_cee_fill(struct sk_buff *skb, struct net_device *netdev) | |||
1280 | /* peer info if available */ | 1286 | /* peer info if available */ |
1281 | if (ops->cee_peer_getpg) { | 1287 | if (ops->cee_peer_getpg) { |
1282 | struct cee_pg pg; | 1288 | struct cee_pg pg; |
1289 | memset(&pg, 0, sizeof(pg)); | ||
1283 | err = ops->cee_peer_getpg(netdev, &pg); | 1290 | err = ops->cee_peer_getpg(netdev, &pg); |
1284 | if (!err && | 1291 | if (!err && |
1285 | nla_put(skb, DCB_ATTR_CEE_PEER_PG, sizeof(pg), &pg)) | 1292 | nla_put(skb, DCB_ATTR_CEE_PEER_PG, sizeof(pg), &pg)) |
@@ -1288,6 +1295,7 @@ static int dcbnl_cee_fill(struct sk_buff *skb, struct net_device *netdev) | |||
1288 | 1295 | ||
1289 | if (ops->cee_peer_getpfc) { | 1296 | if (ops->cee_peer_getpfc) { |
1290 | struct cee_pfc pfc; | 1297 | struct cee_pfc pfc; |
1298 | memset(&pfc, 0, sizeof(pfc)); | ||
1291 | err = ops->cee_peer_getpfc(netdev, &pfc); | 1299 | err = ops->cee_peer_getpfc(netdev, &pfc); |
1292 | if (!err && | 1300 | if (!err && |
1293 | nla_put(skb, DCB_ATTR_CEE_PEER_PFC, sizeof(pfc), &pfc)) | 1301 | nla_put(skb, DCB_ATTR_CEE_PEER_PFC, sizeof(pfc), &pfc)) |