linux-can-fixes-for-5.0-20190122
-----BEGIN PGP SIGNATURE----- iQFHBAABCgAxFiEENrCndlB/VnAEWuH5k9IU1zQoZfEFAlxHFuoTHG1rbEBwZW5n dXRyb25peC5kZQAKCRCT0hTXNChl8eRAB/9Sp32xbjIVeyyEro8+vmlJ/HlSNgcC txqmmh0ce4n1gglV3G5ll8mDYJsk5Qz+ur8wbud7CVxFmpeGqkAA7qoYeD8DawSp /77dBG8yX/t8vxU5jGK9l5FomVcrqKSVbK20R6u0MLeZhF+VdJCu7cDElgIsKDqX N76Df/mTnfdhReoM05CXEwzvEN8StHljm+oecyunxfw3XPtqDkO7QHEVYpk2zwVI 4U2aYu9L1gDbj5yGXNu8l/WwEL4ttyC7rqoW9we1hsDVtxRh1/o+Tond6/HPxIcN voO/fm97ZKxpDL3cE0Jg6Grq9jUek7GT8oRRkAdWO4YaLr3f70kibQ3s =d+ps -----END PGP SIGNATURE----- Merge tag 'linux-can-fixes-for-5.0-20190122' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can Marc Kleine-Budde says: ==================== pull-request: can 2019-01-22 this is a pull request of 4 patches for net/master. The first patch by is by Manfred Schlaegl and reverts a patch that caused wrong warning messages in certain use cases. The next patch is by Oliver Hartkopp for the bcm that adds sanity checks for the timer value before using it to detect potential interger overflows. The last two patches are for the flexcan driver, YueHaibing's patch fixes the the return value in the error path of the flexcan_setup_stop_mode() function. The second patch is by Uwe Kleine-König and fixes a NULL pointer deref on older flexcan cores in flexcan_chip_start(). ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
9620d6f683
|
@ -480,8 +480,6 @@ EXPORT_SYMBOL_GPL(can_put_echo_skb);
|
||||||
struct sk_buff *__can_get_echo_skb(struct net_device *dev, unsigned int idx, u8 *len_ptr)
|
struct sk_buff *__can_get_echo_skb(struct net_device *dev, unsigned int idx, u8 *len_ptr)
|
||||||
{
|
{
|
||||||
struct can_priv *priv = netdev_priv(dev);
|
struct can_priv *priv = netdev_priv(dev);
|
||||||
struct sk_buff *skb = priv->echo_skb[idx];
|
|
||||||
struct canfd_frame *cf;
|
|
||||||
|
|
||||||
if (idx >= priv->echo_skb_max) {
|
if (idx >= priv->echo_skb_max) {
|
||||||
netdev_err(dev, "%s: BUG! Trying to access can_priv::echo_skb out of bounds (%u/max %u)\n",
|
netdev_err(dev, "%s: BUG! Trying to access can_priv::echo_skb out of bounds (%u/max %u)\n",
|
||||||
|
@ -489,20 +487,21 @@ struct sk_buff *__can_get_echo_skb(struct net_device *dev, unsigned int idx, u8
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!skb) {
|
if (priv->echo_skb[idx]) {
|
||||||
netdev_err(dev, "%s: BUG! Trying to echo non existing skb: can_priv::echo_skb[%u]\n",
|
/* Using "struct canfd_frame::len" for the frame
|
||||||
__func__, idx);
|
* length is supported on both CAN and CANFD frames.
|
||||||
return NULL;
|
*/
|
||||||
|
struct sk_buff *skb = priv->echo_skb[idx];
|
||||||
|
struct canfd_frame *cf = (struct canfd_frame *)skb->data;
|
||||||
|
u8 len = cf->len;
|
||||||
|
|
||||||
|
*len_ptr = len;
|
||||||
|
priv->echo_skb[idx] = NULL;
|
||||||
|
|
||||||
|
return skb;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Using "struct canfd_frame::len" for the frame
|
return NULL;
|
||||||
* length is supported on both CAN and CANFD frames.
|
|
||||||
*/
|
|
||||||
cf = (struct canfd_frame *)skb->data;
|
|
||||||
*len_ptr = cf->len;
|
|
||||||
priv->echo_skb[idx] = NULL;
|
|
||||||
|
|
||||||
return skb;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -1106,7 +1106,7 @@ static int flexcan_chip_start(struct net_device *dev)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* clear and invalidate unused mailboxes first */
|
/* clear and invalidate unused mailboxes first */
|
||||||
for (i = FLEXCAN_TX_MB_RESERVED_OFF_FIFO; i <= priv->mb_count; i++) {
|
for (i = FLEXCAN_TX_MB_RESERVED_OFF_FIFO; i < priv->mb_count; i++) {
|
||||||
mb = flexcan_get_mb(priv, i);
|
mb = flexcan_get_mb(priv, i);
|
||||||
priv->write(FLEXCAN_MB_CODE_RX_INACTIVE,
|
priv->write(FLEXCAN_MB_CODE_RX_INACTIVE,
|
||||||
&mb->can_ctrl);
|
&mb->can_ctrl);
|
||||||
|
@ -1432,7 +1432,7 @@ static int flexcan_setup_stop_mode(struct platform_device *pdev)
|
||||||
gpr_np = of_find_node_by_phandle(phandle);
|
gpr_np = of_find_node_by_phandle(phandle);
|
||||||
if (!gpr_np) {
|
if (!gpr_np) {
|
||||||
dev_dbg(&pdev->dev, "could not find gpr node by phandle\n");
|
dev_dbg(&pdev->dev, "could not find gpr node by phandle\n");
|
||||||
return PTR_ERR(gpr_np);
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
priv = netdev_priv(dev);
|
priv = netdev_priv(dev);
|
||||||
|
|
|
@ -67,6 +67,9 @@
|
||||||
*/
|
*/
|
||||||
#define MAX_NFRAMES 256
|
#define MAX_NFRAMES 256
|
||||||
|
|
||||||
|
/* limit timers to 400 days for sending/timeouts */
|
||||||
|
#define BCM_TIMER_SEC_MAX (400 * 24 * 60 * 60)
|
||||||
|
|
||||||
/* use of last_frames[index].flags */
|
/* use of last_frames[index].flags */
|
||||||
#define RX_RECV 0x40 /* received data for this element */
|
#define RX_RECV 0x40 /* received data for this element */
|
||||||
#define RX_THR 0x80 /* element not been sent due to throttle feature */
|
#define RX_THR 0x80 /* element not been sent due to throttle feature */
|
||||||
|
@ -140,6 +143,22 @@ static inline ktime_t bcm_timeval_to_ktime(struct bcm_timeval tv)
|
||||||
return ktime_set(tv.tv_sec, tv.tv_usec * NSEC_PER_USEC);
|
return ktime_set(tv.tv_sec, tv.tv_usec * NSEC_PER_USEC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* check limitations for timeval provided by user */
|
||||||
|
static bool bcm_is_invalid_tv(struct bcm_msg_head *msg_head)
|
||||||
|
{
|
||||||
|
if ((msg_head->ival1.tv_sec < 0) ||
|
||||||
|
(msg_head->ival1.tv_sec > BCM_TIMER_SEC_MAX) ||
|
||||||
|
(msg_head->ival1.tv_usec < 0) ||
|
||||||
|
(msg_head->ival1.tv_usec >= USEC_PER_SEC) ||
|
||||||
|
(msg_head->ival2.tv_sec < 0) ||
|
||||||
|
(msg_head->ival2.tv_sec > BCM_TIMER_SEC_MAX) ||
|
||||||
|
(msg_head->ival2.tv_usec < 0) ||
|
||||||
|
(msg_head->ival2.tv_usec >= USEC_PER_SEC))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
#define CFSIZ(flags) ((flags & CAN_FD_FRAME) ? CANFD_MTU : CAN_MTU)
|
#define CFSIZ(flags) ((flags & CAN_FD_FRAME) ? CANFD_MTU : CAN_MTU)
|
||||||
#define OPSIZ sizeof(struct bcm_op)
|
#define OPSIZ sizeof(struct bcm_op)
|
||||||
#define MHSIZ sizeof(struct bcm_msg_head)
|
#define MHSIZ sizeof(struct bcm_msg_head)
|
||||||
|
@ -873,6 +892,10 @@ static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
|
||||||
if (msg_head->nframes < 1 || msg_head->nframes > MAX_NFRAMES)
|
if (msg_head->nframes < 1 || msg_head->nframes > MAX_NFRAMES)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
/* check timeval limitations */
|
||||||
|
if ((msg_head->flags & SETTIMER) && bcm_is_invalid_tv(msg_head))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
/* check the given can_id */
|
/* check the given can_id */
|
||||||
op = bcm_find_op(&bo->tx_ops, msg_head, ifindex);
|
op = bcm_find_op(&bo->tx_ops, msg_head, ifindex);
|
||||||
if (op) {
|
if (op) {
|
||||||
|
@ -1053,6 +1076,10 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
|
||||||
(!(msg_head->can_id & CAN_RTR_FLAG))))
|
(!(msg_head->can_id & CAN_RTR_FLAG))))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
/* check timeval limitations */
|
||||||
|
if ((msg_head->flags & SETTIMER) && bcm_is_invalid_tv(msg_head))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
/* check the given can_id */
|
/* check the given can_id */
|
||||||
op = bcm_find_op(&bo->rx_ops, msg_head, ifindex);
|
op = bcm_find_op(&bo->rx_ops, msg_head, ifindex);
|
||||||
if (op) {
|
if (op) {
|
||||||
|
|
Loading…
Reference in New Issue