Skip to content

Commit 6482f55

Browse files
Rémi Denis-Courmontdavem330
authored andcommitted
Phonet: remove dangling pipe if an endpoint is closed early
Closing a pipe endpoint is not normally allowed by the Phonet pipe, other than as a side after-effect of removing the pipe between two endpoints. But there is no way to prevent Linux userspace processes from being killed or suffering from bugs, so this can still happen. We might as well forcefully close Phonet pipe endpoints then. The cellular modem supports only a few existing pipes at a time. So we really should not leak them. This change instructs the modem to destroy the pipe if either of the pipe's endpoint (Linux socket) is closed too early. Signed-off-by: Rémi Denis-Courmont <remi.denis-courmont@nokia.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 7fedd7e commit 6482f55

2 files changed

Lines changed: 31 additions & 1 deletion

File tree

include/net/phonet/pep.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,11 @@ static inline struct pnpipehdr *pnp_hdr(struct sk_buff *skb)
7777
#define MAX_PNPIPE_HEADER (MAX_PHONET_HEADER + 4)
7878

7979
enum {
80+
PNS_PIPE_CREATE_REQ = 0x00,
81+
PNS_PIPE_CREATE_RESP,
82+
PNS_PIPE_REMOVE_REQ,
83+
PNS_PIPE_REMOVE_RESP,
84+
8085
PNS_PIPE_DATA = 0x20,
8186
PNS_PIPE_ALIGNED_DATA,
8287

net/phonet/pep.c

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -620,6 +620,28 @@ static int pep_do_rcv(struct sock *sk, struct sk_buff *skb)
620620
return err;
621621
}
622622

623+
static int pipe_do_remove(struct sock *sk)
624+
{
625+
struct pep_sock *pn = pep_sk(sk);
626+
struct pnpipehdr *ph;
627+
struct sk_buff *skb;
628+
629+
skb = alloc_skb(MAX_PNPIPE_HEADER, GFP_KERNEL);
630+
if (!skb)
631+
return -ENOMEM;
632+
633+
skb_reserve(skb, MAX_PNPIPE_HEADER);
634+
__skb_push(skb, sizeof(*ph));
635+
skb_reset_transport_header(skb);
636+
ph = pnp_hdr(skb);
637+
ph->utid = 0;
638+
ph->message_id = PNS_PIPE_REMOVE_REQ;
639+
ph->pipe_handle = pn->pipe_handle;
640+
ph->data[0] = PAD;
641+
642+
return pn_skb_send(sk, skb, &pipe_srv);
643+
}
644+
623645
/* associated socket ceases to exist */
624646
static void pep_sock_close(struct sock *sk, long timeout)
625647
{
@@ -638,7 +660,10 @@ static void pep_sock_close(struct sock *sk, long timeout)
638660
sk_for_each_safe(sknode, p, n, &pn->ackq)
639661
sk_del_node_init(sknode);
640662
sk->sk_state = TCP_CLOSE;
641-
}
663+
} else if ((1 << sk->sk_state) & (TCPF_SYN_RECV|TCPF_ESTABLISHED))
664+
/* Forcefully remove dangling Phonet pipe */
665+
pipe_do_remove(sk);
666+
642667
ifindex = pn->ifindex;
643668
pn->ifindex = 0;
644669
release_sock(sk);

0 commit comments

Comments
 (0)