Skip to content

Commit 3a50cf1

Browse files
vvfedorenkoSaeed Mahameed
authored andcommitted
mlx5: fix possible ptp queue fifo use-after-free
Fifo indexes are not checked during pop operations and it leads to potential use-after-free when poping from empty queue. Such case was possible during re-sync action. WARN_ON_ONCE covers future cases. There were out-of-order cqe spotted which lead to drain of the queue and use-after-free because of lack of fifo pointers check. Special check and counter are added to avoid resync operation if SKB could not exist in the fifo because of OOO cqe (skb_id must be between consumer and producer index). Fixes: 58a5189 ("net/mlx5e: Add resiliency for PTP TX port timestamp") Signed-off-by: Vadim Fedorenko <[email protected]> Signed-off-by: Saeed Mahameed <[email protected]>
1 parent e435941 commit 3a50cf1

File tree

4 files changed

+22
-1
lines changed

4 files changed

+22
-1
lines changed

drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,17 @@ static bool mlx5e_ptp_ts_cqe_drop(struct mlx5e_ptpsq *ptpsq, u16 skb_cc, u16 skb
8686
return (ptpsq->ts_cqe_ctr_mask && (skb_cc != skb_id));
8787
}
8888

89+
static bool mlx5e_ptp_ts_cqe_ooo(struct mlx5e_ptpsq *ptpsq, u16 skb_id)
90+
{
91+
u16 skb_cc = PTP_WQE_CTR2IDX(ptpsq->skb_fifo_cc);
92+
u16 skb_pc = PTP_WQE_CTR2IDX(ptpsq->skb_fifo_pc);
93+
94+
if (PTP_WQE_CTR2IDX(skb_id - skb_cc) >= PTP_WQE_CTR2IDX(skb_pc - skb_cc))
95+
return true;
96+
97+
return false;
98+
}
99+
89100
static void mlx5e_ptp_skb_fifo_ts_cqe_resync(struct mlx5e_ptpsq *ptpsq, u16 skb_cc,
90101
u16 skb_id, int budget)
91102
{
@@ -120,8 +131,14 @@ static void mlx5e_ptp_handle_ts_cqe(struct mlx5e_ptpsq *ptpsq,
120131
goto out;
121132
}
122133

123-
if (mlx5e_ptp_ts_cqe_drop(ptpsq, skb_cc, skb_id))
134+
if (mlx5e_ptp_ts_cqe_drop(ptpsq, skb_cc, skb_id)) {
135+
if (mlx5e_ptp_ts_cqe_ooo(ptpsq, skb_id)) {
136+
/* already handled by a previous resync */
137+
ptpsq->cq_stats->ooo_cqe_drop++;
138+
return;
139+
}
124140
mlx5e_ptp_skb_fifo_ts_cqe_resync(ptpsq, skb_cc, skb_id, budget);
141+
}
125142

126143
skb = mlx5e_skb_fifo_pop(&ptpsq->skb_fifo);
127144
hwtstamp = mlx5e_cqe_ts_to_ns(sq->ptp_cyc2time, sq->clock, get_cqe_ts(cqe));

drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,8 @@ void mlx5e_skb_fifo_push(struct mlx5e_skb_fifo *fifo, struct sk_buff *skb)
302302
static inline
303303
struct sk_buff *mlx5e_skb_fifo_pop(struct mlx5e_skb_fifo *fifo)
304304
{
305+
WARN_ON_ONCE(*fifo->pc == *fifo->cc);
306+
305307
return *mlx5e_skb_fifo_get(fifo, (*fifo->cc)++);
306308
}
307309

drivers/net/ethernet/mellanox/mlx5/core/en_stats.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2138,6 +2138,7 @@ static const struct counter_desc ptp_cq_stats_desc[] = {
21382138
{ MLX5E_DECLARE_PTP_CQ_STAT(struct mlx5e_ptp_cq_stats, abort_abs_diff_ns) },
21392139
{ MLX5E_DECLARE_PTP_CQ_STAT(struct mlx5e_ptp_cq_stats, resync_cqe) },
21402140
{ MLX5E_DECLARE_PTP_CQ_STAT(struct mlx5e_ptp_cq_stats, resync_event) },
2141+
{ MLX5E_DECLARE_PTP_CQ_STAT(struct mlx5e_ptp_cq_stats, ooo_cqe_drop) },
21412142
};
21422143

21432144
static const struct counter_desc ptp_rq_stats_desc[] = {

drivers/net/ethernet/mellanox/mlx5/core/en_stats.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,7 @@ struct mlx5e_ptp_cq_stats {
461461
u64 abort_abs_diff_ns;
462462
u64 resync_cqe;
463463
u64 resync_event;
464+
u64 ooo_cqe_drop;
464465
};
465466

466467
struct mlx5e_rep_stats {

0 commit comments

Comments
 (0)