* [PATCH 1/3] can: isotp: sanitize CAN ID checks in isotp_bind()
@ 2022-03-16 16:42 Oliver Hartkopp
2022-03-16 16:42 ` [PATCH 2/3] can: isotp: return -EADDRNOTAVAIL when reading from unbound socket Oliver Hartkopp
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Oliver Hartkopp @ 2022-03-16 16:42 UTC (permalink / raw)
To: linux-can; +Cc: Oliver Hartkopp, syzbot+2339c27f5c66c652843e
Syzbot created an environment that lead to a state machine status that
can not be reached with a compliant CAN ID address configuration.
The provided address information consisted of CAN ID 0x6000001 and 0xC28001
which both boil down to 11 bit CAN IDs 0x001 in sending and receiving.
Sanitize the SFF/EFF CAN ID values before performing the address checks.
Fixes: e057dd3fc20f ("can: add ISO 15765-2:2016 transport protocol")
Reported-by: syzbot+2339c27f5c66c652843e@syzkaller.appspotmail.com
Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
---
net/can/isotp.c | 41 +++++++++++++++++++++--------------------
1 file changed, 21 insertions(+), 20 deletions(-)
diff --git a/net/can/isotp.c b/net/can/isotp.c
index d4c0b4704987..1662103ce125 100644
--- a/net/can/isotp.c
+++ b/net/can/isotp.c
@@ -1146,19 +1146,30 @@ static int isotp_bind(struct socket *sock, struct sockaddr *uaddr, int len)
struct sock *sk = sock->sk;
struct isotp_sock *so = isotp_sk(sk);
struct net *net = sock_net(sk);
int ifindex;
struct net_device *dev;
+ canid_t tx_id, rx_id;
int err = 0;
int notify_enetdown = 0;
int do_rx_reg = 1;
if (len < ISOTP_MIN_NAMELEN)
return -EINVAL;
- if (addr->can_addr.tp.tx_id & (CAN_ERR_FLAG | CAN_RTR_FLAG))
- return -EADDRNOTAVAIL;
+ /* sanitize tx/rx CAN identifiers */
+ tx_id = addr->can_addr.tp.tx_id;
+ if (tx_id & CAN_EFF_FLAG)
+ tx_id &= (CAN_EFF_FLAG | CAN_EFF_MASK);
+ else
+ tx_id &= CAN_SFF_MASK;
+
+ rx_id = addr->can_addr.tp.rx_id;
+ if (rx_id & CAN_EFF_FLAG)
+ rx_id &= (CAN_EFF_FLAG | CAN_EFF_MASK);
+ else
+ rx_id &= CAN_SFF_MASK;
if (!addr->can_ifindex)
return -ENODEV;
lock_sock(sk);
@@ -1166,25 +1177,17 @@ static int isotp_bind(struct socket *sock, struct sockaddr *uaddr, int len)
/* do not register frame reception for functional addressing */
if (so->opt.flags & CAN_ISOTP_SF_BROADCAST)
do_rx_reg = 0;
/* do not validate rx address for functional addressing */
- if (do_rx_reg) {
- if (addr->can_addr.tp.rx_id == addr->can_addr.tp.tx_id) {
- err = -EADDRNOTAVAIL;
- goto out;
- }
-
- if (addr->can_addr.tp.rx_id & (CAN_ERR_FLAG | CAN_RTR_FLAG)) {
- err = -EADDRNOTAVAIL;
- goto out;
- }
+ if (do_rx_reg && rx_id == tx_id) {
+ err = -EADDRNOTAVAIL;
+ goto out;
}
if (so->bound && addr->can_ifindex == so->ifindex &&
- addr->can_addr.tp.rx_id == so->rxid &&
- addr->can_addr.tp.tx_id == so->txid)
+ rx_id == so->rxid && tx_id == so->txid)
goto out;
dev = dev_get_by_index(net, addr->can_ifindex);
if (!dev) {
err = -ENODEV;
@@ -1204,20 +1207,18 @@ static int isotp_bind(struct socket *sock, struct sockaddr *uaddr, int len)
notify_enetdown = 1;
ifindex = dev->ifindex;
if (do_rx_reg) {
- can_rx_register(net, dev, addr->can_addr.tp.rx_id,
- SINGLE_MASK(addr->can_addr.tp.rx_id),
+ can_rx_register(net, dev, rx_id, SINGLE_MASK(rx_id),
isotp_rcv, sk, "isotp", sk);
/* no consecutive frame echo skb in flight */
so->cfecho = 0;
/* register for echo skb's */
- can_rx_register(net, dev, addr->can_addr.tp.tx_id,
- SINGLE_MASK(addr->can_addr.tp.tx_id),
+ can_rx_register(net, dev, tx_id, SINGLE_MASK(tx_id),
isotp_rcv_echo, sk, "isotpe", sk);
}
dev_put(dev);
@@ -1237,12 +1238,12 @@ static int isotp_bind(struct socket *sock, struct sockaddr *uaddr, int len)
}
}
/* switch to new settings */
so->ifindex = ifindex;
- so->rxid = addr->can_addr.tp.rx_id;
- so->txid = addr->can_addr.tp.tx_id;
+ so->rxid = rx_id;
+ so->txid = tx_id;
so->bound = 1;
out:
release_sock(sk);
--
2.30.2
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 2/3] can: isotp: return -EADDRNOTAVAIL when reading from unbound socket
2022-03-16 16:42 [PATCH 1/3] can: isotp: sanitize CAN ID checks in isotp_bind() Oliver Hartkopp
@ 2022-03-16 16:42 ` Oliver Hartkopp
2022-03-16 16:42 ` [PATCH 3/3] can: isotp: support MSG_TRUNC flag when reading from socket Oliver Hartkopp
2022-03-16 20:48 ` [PATCH 1/3] can: isotp: sanitize CAN ID checks in isotp_bind() Marc Kleine-Budde
2 siblings, 0 replies; 4+ messages in thread
From: Oliver Hartkopp @ 2022-03-16 16:42 UTC (permalink / raw)
To: linux-can; +Cc: Oliver Hartkopp, Derek Will
When reading from an unbound can-isotp socket the syscall blocked
indefinitely. As unbound sockets (without given CAN address information)
do not make sense anyway we directly return -EADDRNOTAVAIL on read()
analogue to the known behavior from sendmsg().
Fixes: e057dd3fc20f ("can: add ISO 15765-2:2016 transport protocol")
Link: https://github.com/linux-can/can-utils/issues/349
Suggested-by: Derek Will <derekrobertwill@gmail.com>
Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
---
net/can/isotp.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/net/can/isotp.c b/net/can/isotp.c
index 1662103ce125..6b6c82206c30 100644
--- a/net/can/isotp.c
+++ b/net/can/isotp.c
@@ -1044,16 +1044,20 @@ static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
static int isotp_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
int flags)
{
struct sock *sk = sock->sk;
struct sk_buff *skb;
+ struct isotp_sock *so = isotp_sk(sk);
int err = 0;
int noblock;
noblock = flags & MSG_DONTWAIT;
flags &= ~MSG_DONTWAIT;
+ if (!so->bound)
+ return -EADDRNOTAVAIL;
+
skb = skb_recv_datagram(sk, flags, noblock, &err);
if (!skb)
return err;
if (size < skb->len)
--
2.30.2
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 3/3] can: isotp: support MSG_TRUNC flag when reading from socket
2022-03-16 16:42 [PATCH 1/3] can: isotp: sanitize CAN ID checks in isotp_bind() Oliver Hartkopp
2022-03-16 16:42 ` [PATCH 2/3] can: isotp: return -EADDRNOTAVAIL when reading from unbound socket Oliver Hartkopp
@ 2022-03-16 16:42 ` Oliver Hartkopp
2022-03-16 20:48 ` [PATCH 1/3] can: isotp: sanitize CAN ID checks in isotp_bind() Marc Kleine-Budde
2 siblings, 0 replies; 4+ messages in thread
From: Oliver Hartkopp @ 2022-03-16 16:42 UTC (permalink / raw)
To: linux-can; +Cc: Oliver Hartkopp, Derek Will
When providing the MSG_TRUNC flag via recvmsg() syscall the return value
provides the real length of the packet or datagram, even when it was longer
than the passed buffer.
Fixes: e057dd3fc20f ("can: add ISO 15765-2:2016 transport protocol")
Link: https://github.com/linux-can/can-utils/issues/347#issuecomment-1065932671
Suggested-by: Derek Will <derekrobertwill@gmail.com>
Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
---
net/can/isotp.c | 27 +++++++++++++++------------
1 file changed, 15 insertions(+), 12 deletions(-)
diff --git a/net/can/isotp.c b/net/can/isotp.c
index 6b6c82206c30..f6f8ba1f816d 100644
--- a/net/can/isotp.c
+++ b/net/can/isotp.c
@@ -1045,45 +1045,48 @@ static int isotp_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
int flags)
{
struct sock *sk = sock->sk;
struct sk_buff *skb;
struct isotp_sock *so = isotp_sk(sk);
- int err = 0;
- int noblock;
+ int noblock = flags & MSG_DONTWAIT;
+ int ret = 0;
- noblock = flags & MSG_DONTWAIT;
- flags &= ~MSG_DONTWAIT;
+ if (flags & ~(MSG_DONTWAIT | MSG_TRUNC))
+ return -EINVAL;
if (!so->bound)
return -EADDRNOTAVAIL;
- skb = skb_recv_datagram(sk, flags, noblock, &err);
+ flags &= ~MSG_DONTWAIT;
+ skb = skb_recv_datagram(sk, flags, noblock, &ret);
if (!skb)
- return err;
+ return ret;
if (size < skb->len)
msg->msg_flags |= MSG_TRUNC;
else
size = skb->len;
- err = memcpy_to_msg(msg, skb->data, size);
- if (err < 0) {
- skb_free_datagram(sk, skb);
- return err;
- }
+ ret = memcpy_to_msg(msg, skb->data, size);
+ if (ret < 0)
+ goto out_err;
sock_recv_timestamp(msg, sk, skb);
if (msg->msg_name) {
__sockaddr_check_size(ISOTP_MIN_NAMELEN);
msg->msg_namelen = ISOTP_MIN_NAMELEN;
memcpy(msg->msg_name, skb->cb, msg->msg_namelen);
}
+ /* set length of return value */
+ ret = (flags & MSG_TRUNC) ? skb->len : size;
+
+out_err:
skb_free_datagram(sk, skb);
- return size;
+ return ret;
}
static int isotp_release(struct socket *sock)
{
struct sock *sk = sock->sk;
--
2.30.2
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH 1/3] can: isotp: sanitize CAN ID checks in isotp_bind()
2022-03-16 16:42 [PATCH 1/3] can: isotp: sanitize CAN ID checks in isotp_bind() Oliver Hartkopp
2022-03-16 16:42 ` [PATCH 2/3] can: isotp: return -EADDRNOTAVAIL when reading from unbound socket Oliver Hartkopp
2022-03-16 16:42 ` [PATCH 3/3] can: isotp: support MSG_TRUNC flag when reading from socket Oliver Hartkopp
@ 2022-03-16 20:48 ` Marc Kleine-Budde
2 siblings, 0 replies; 4+ messages in thread
From: Marc Kleine-Budde @ 2022-03-16 20:48 UTC (permalink / raw)
To: Oliver Hartkopp; +Cc: linux-can, syzbot+2339c27f5c66c652843e
[-- Attachment #1: Type: text/plain, Size: 953 bytes --]
On 16.03.2022 17:42:56, Oliver Hartkopp wrote:
> Syzbot created an environment that lead to a state machine status that
> can not be reached with a compliant CAN ID address configuration.
> The provided address information consisted of CAN ID 0x6000001 and 0xC28001
> which both boil down to 11 bit CAN IDs 0x001 in sending and receiving.
>
> Sanitize the SFF/EFF CAN ID values before performing the address checks.
>
> Fixes: e057dd3fc20f ("can: add ISO 15765-2:2016 transport protocol")
> Reported-by: syzbot+2339c27f5c66c652843e@syzkaller.appspotmail.com
> Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
Added to linux-can-next/testing.
Thanks,
Marc
--
Pengutronix e.K. | Marc Kleine-Budde |
Embedded Linux | https://www.pengutronix.de |
Vertretung West/Dortmund | Phone: +49-231-2826-924 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2022-03-16 20:49 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-03-16 16:42 [PATCH 1/3] can: isotp: sanitize CAN ID checks in isotp_bind() Oliver Hartkopp
2022-03-16 16:42 ` [PATCH 2/3] can: isotp: return -EADDRNOTAVAIL when reading from unbound socket Oliver Hartkopp
2022-03-16 16:42 ` [PATCH 3/3] can: isotp: support MSG_TRUNC flag when reading from socket Oliver Hartkopp
2022-03-16 20:48 ` [PATCH 1/3] can: isotp: sanitize CAN ID checks in isotp_bind() Marc Kleine-Budde
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.