mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] phonet: pep: fix out-of-bounds reads in pep_ctrlreq_error() and pep_sock_accept()
@ 2026-09-19 21:28 Hui Peng
  0 siblings, 0 replies; only message in thread
From: Hui Peng @ 2026-09-19 21:28 UTC (permalink / raw)
  To: courmisch, davem, edumazet, kuba, pabeni; +Cc: horms, netdev, linux-kernel

Fix three packet-parsing and locking bugs in Phonet Pipe End Point
(`net/phonet/pep.c`):

1. In `pep_ctrlreq_error()`, `oph = pnp_hdr(oskb)` is dereferenced at
   `oph->pep_type` (`oph->data[0]`, offset 4 from `pnp_hdr(oskb)`)
   before verifying that `oph->data[0]` lies within the linear `oskb`
   data area. When called from `pep_do_rcv()`
   (`PN_PIPE_INVALID_HANDLE`), `oskb->data` still points to `oph` and
   only `pskb_may_pull(skb, sizeof(*hdr))` (4 bytes) was checked,
   causing `oph->pep_type` to read 1 byte past `oskb->tail` and echo it
   back to the peer in `PNS_PEP_CTRL_RESP`. Ensure `pskb_may_pull()`
   covers `(oph->data + 1) - oskb->data` bytes (and `sizeof(*hdr) + 1`
   in `pipe_do_rcv()`).
2. In `pep_sock_accept()`, `n_sb = hdr->data[3]` is read from the
   `PNS_PIPE_CONNECT_REQ` header, but `__skb_pull(skb, sizeof(*hdr) +
   4)` is omitted before the `pep_get_sb()` loop, causing `pep_get_sb()`
   to parse the 8-byte `pnpipehdr` and connect-request header as
   sub-blocks, and `PN_PIPE_SB_ALIGNED_DATA` reads `data[0]` without
   checking `len >= 1`.
3. In `pep_setsockopt()` (`PNPIPE_ENCAP`), `release_sock(sk)` is dropped
   around `gprs_attach(sk)`, and `pn->ifindex` is assigned afterwards
   without re-acquiring `lock_sock(sk)` or checking `SOCK_DEAD` /
   concurrent attachment.

Fixes: 9641458d3ec4 ("Phonet: Pipe End Point for Phonet Pipes protocol")
Assisted-by: LLM
Signed-off-by: Hui Peng <benquike@gmail.com>

---
 net/phonet/pep.c | 35 +++++++++++++++++++++++++++--------
 1 file changed, 27 insertions(+), 8 deletions(-)

diff --git a/net/phonet/pep.c b/net/phonet/pep.c
index bd1cdd00edfa..5511770bb21c 100644
--- a/net/phonet/pep.c
+++ b/net/phonet/pep.c
@@ -192,15 +192,21 @@ static int pep_reject_conn(struct sock *sk, struct sk_buff *skb, u8 code,
 static int pep_ctrlreq_error(struct sock *sk, struct sk_buff *oskb, u8 code,
 				gfp_t priority)
 {
-	const struct pnpipehdr *oph = pnp_hdr(oskb);
+	const struct pnpipehdr *oph;
 	struct sk_buff *skb;
 	struct pnpipehdr *ph;
 	struct sockaddr_pn dst;
-	u8 data[4] = {
-		oph->pep_type, /* PEP type */
-		code, /* error code, at an unusual offset */
-		PAD, PAD,
-	};
+	u8 data[4];
+
+	oph = pnp_hdr(oskb);
+	if (!pskb_may_pull(oskb, (unsigned int)((oph->data + 1) - oskb->data)))
+		return -EINVAL;
+
+	oph = pnp_hdr(oskb);
+	data[0] = oph->pep_type; /* PEP type */
+	data[1] = code; /* error code, at an unusual offset */
+	data[2] = PAD;
+	data[3] = PAD;
 
 	skb = pep_alloc_skb(sk, data, 4, priority);
 	if (!skb)
@@ -377,6 +383,8 @@ static int pipe_do_rcv(struct sock *sk, struct sk_buff *skb)
 		break;
 
 	case PNS_PEP_CTRL_REQ:
+		if (!pskb_may_pull(skb, sizeof(*hdr) + 1))
+			break;
 		if (skb_queue_len(&pn->ctrlreq_queue) >= PNPIPE_CTRLREQ_MAX) {
 			sk_drops_inc(sk);
 			break;
@@ -823,6 +831,7 @@ static struct sock *pep_sock_accept(struct sock *sk,
 
 	/* Parse sub-blocks (options) */
 	n_sb = hdr->data[3];
+	__skb_pull(skb, sizeof(*hdr) + 4);
 	while (n_sb > 0) {
 		u8 type, buf[1], len = sizeof(buf);
 		const u8 *data = pep_get_sb(skb, &type, &len, buf);
@@ -836,6 +845,8 @@ static struct sock *pep_sock_accept(struct sock *sk,
 			peer_type = (peer_type & 0xff00) | data[0];
 			break;
 		case PN_PIPE_SB_ALIGNED_DATA:
+			if (len < 1)
+				goto drop;
 			aligned = data[0] != 0;
 			break;
 		}
@@ -1048,8 +1059,16 @@ static int pep_setsockopt(struct sock *sk, int level, int optname,
 			release_sock(sk);
 			err = gprs_attach(sk);
 			if (err > 0) {
-				pn->ifindex = err;
-				err = 0;
+				lock_sock(sk);
+				if (sock_flag(sk, SOCK_DEAD) || pn->ifindex) {
+					release_sock(sk);
+					gprs_detach(sk);
+					err = -EINVAL;
+				} else {
+					pn->ifindex = err;
+					err = 0;
+					release_sock(sk);
+				}
 			}
 		} else {
 			pn->ifindex = 0;

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2026-09-19 21:28 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-19 21:28 [PATCH] phonet: pep: fix out-of-bounds reads in pep_ctrlreq_error() and pep_sock_accept() Hui Peng

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®