aboutsummaryrefslogtreecommitdiffstats
path: root/net/core
diff options
context:
space:
mode:
authorRichard Cochran <richard.cochran@omicron.at>2011-10-19 17:00:35 -0400
committerDavid S. Miller <davem@davemloft.net>2011-10-19 17:00:35 -0400
commit4dc360c5e7e155373bffbb3c1f7ea0022dee650c (patch)
tree626d89398ae24a6995acb1b179d8cbed39199263 /net/core
parent850a545bd8a41648445bfc5541afe36ca105b0b8 (diff)
net: validate HWTSTAMP ioctl parameters
This patch adds a sanity check on the values provided by user space for the hardware time stamping configuration. If the values lie outside of the absolute limits, then the ioctl request will be denied. Signed-off-by: Richard Cochran <richard.cochran@omicron.at> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core')
-rw-r--r--net/core/dev.c58
1 files changed, 58 insertions, 0 deletions
diff --git a/net/core/dev.c b/net/core/dev.c
index 09aef266d4d1..40d439524f49 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -136,6 +136,7 @@
136#include <linux/if_tunnel.h> 136#include <linux/if_tunnel.h>
137#include <linux/if_pppox.h> 137#include <linux/if_pppox.h>
138#include <linux/ppp_defs.h> 138#include <linux/ppp_defs.h>
139#include <linux/net_tstamp.h>
139 140
140#include "net-sysfs.h" 141#include "net-sysfs.h"
141 142
@@ -1477,6 +1478,57 @@ static inline void net_timestamp_check(struct sk_buff *skb)
1477 __net_timestamp(skb); 1478 __net_timestamp(skb);
1478} 1479}
1479 1480
1481static int net_hwtstamp_validate(struct ifreq *ifr)
1482{
1483 struct hwtstamp_config cfg;
1484 enum hwtstamp_tx_types tx_type;
1485 enum hwtstamp_rx_filters rx_filter;
1486 int tx_type_valid = 0;
1487 int rx_filter_valid = 0;
1488
1489 if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg)))
1490 return -EFAULT;
1491
1492 if (cfg.flags) /* reserved for future extensions */
1493 return -EINVAL;
1494
1495 tx_type = cfg.tx_type;
1496 rx_filter = cfg.rx_filter;
1497
1498 switch (tx_type) {
1499 case HWTSTAMP_TX_OFF:
1500 case HWTSTAMP_TX_ON:
1501 case HWTSTAMP_TX_ONESTEP_SYNC:
1502 tx_type_valid = 1;
1503 break;
1504 }
1505
1506 switch (rx_filter) {
1507 case HWTSTAMP_FILTER_NONE:
1508 case HWTSTAMP_FILTER_ALL:
1509 case HWTSTAMP_FILTER_SOME:
1510 case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
1511 case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
1512 case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
1513 case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
1514 case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
1515 case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
1516 case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
1517 case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
1518 case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
1519 case HWTSTAMP_FILTER_PTP_V2_EVENT:
1520 case HWTSTAMP_FILTER_PTP_V2_SYNC:
1521 case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
1522 rx_filter_valid = 1;
1523 break;
1524 }
1525
1526 if (!tx_type_valid || !rx_filter_valid)
1527 return -ERANGE;
1528
1529 return 0;
1530}
1531
1480static inline bool is_skb_forwardable(struct net_device *dev, 1532static inline bool is_skb_forwardable(struct net_device *dev,
1481 struct sk_buff *skb) 1533 struct sk_buff *skb)
1482{ 1534{
@@ -4921,6 +4973,12 @@ static int dev_ifsioc(struct net *net, struct ifreq *ifr, unsigned int cmd)
4921 ifr->ifr_newname[IFNAMSIZ-1] = '\0'; 4973 ifr->ifr_newname[IFNAMSIZ-1] = '\0';
4922 return dev_change_name(dev, ifr->ifr_newname); 4974 return dev_change_name(dev, ifr->ifr_newname);
4923 4975
4976 case SIOCSHWTSTAMP:
4977 err = net_hwtstamp_validate(ifr);
4978 if (err)
4979 return err;
4980 /* fall through */
4981
4924 /* 4982 /*
4925 * Unknown or private ioctl 4983 * Unknown or private ioctl
4926 */ 4984 */