Unverified Commit 0e1bb98e authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!11516 fix CVE-2024-44988

Merge Pull Request from: @ci-robot 
 
PR sync from: Zhang Changzhong <zhangchangzhong@huawei.com>
https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/LPCNFQTHHXY253RN4SJV5ZB6R2HMJZ72/ 
fix CVE-2024-44988

Hans J. Schultz (1):
  net: dsa: mv88e6xxx: read FID when handling ATU violations

Joseph Huang (1):
  net: dsa: mv88e6xxx: Fix out-of-bound access

Vladimir Oltean (1):
  net: dsa: mv88e6xxx: replace ATU violation prints with trace points


-- 
2.9.5
 
https://gitee.com/src-openeuler/kernel/issues/IAOXZQ 
 
Link:https://gitee.com/openeuler/kernel/pulls/11516

 

Reviewed-by: default avatarYue Haibing <yuehaibing@huawei.com>
Signed-off-by: default avatarYang Yingliang <yangyingliang@huawei.com>
parents baf46725 de10b31a
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -15,3 +15,7 @@ mv88e6xxx-objs += port_hidden.o
mv88e6xxx-$(CONFIG_NET_DSA_MV88E6XXX_PTP) += ptp.o
mv88e6xxx-objs += serdes.o
mv88e6xxx-objs += smi.o
mv88e6xxx-objs += trace.o

# for tracing framework to find trace.h
CFLAGS_trace.o := -I$(src)
+67 −15
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@

#include "chip.h"
#include "global1.h"
#include "trace.h"

/* Offset 0x01: ATU FID Register */

@@ -114,6 +115,19 @@ static int mv88e6xxx_g1_atu_op_wait(struct mv88e6xxx_chip *chip)
	return mv88e6xxx_g1_wait_bit(chip, MV88E6XXX_G1_ATU_OP, bit, 0);
}

static int mv88e6xxx_g1_read_atu_violation(struct mv88e6xxx_chip *chip)
{
	int err;

	err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_ATU_OP,
				 MV88E6XXX_G1_ATU_OP_BUSY |
				 MV88E6XXX_G1_ATU_OP_GET_CLR_VIOLATION);
	if (err)
		return err;

	return mv88e6xxx_g1_atu_op_wait(chip);
}

static int mv88e6xxx_g1_atu_op(struct mv88e6xxx_chip *chip, u16 fid, u16 op)
{
	u16 val;
@@ -159,6 +173,41 @@ int mv88e6xxx_g1_atu_get_next(struct mv88e6xxx_chip *chip, u16 fid)
	return mv88e6xxx_g1_atu_op(chip, fid, MV88E6XXX_G1_ATU_OP_GET_NEXT_DB);
}

static int mv88e6xxx_g1_atu_fid_read(struct mv88e6xxx_chip *chip, u16 *fid)
{
	u16 val = 0, upper = 0, op = 0;
	int err = -EOPNOTSUPP;

	if (mv88e6xxx_num_databases(chip) > 256) {
		err = mv88e6xxx_g1_read(chip, MV88E6352_G1_ATU_FID, &val);
		val &= 0xfff;
		if (err)
			return err;
	} else {
		err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_ATU_OP, &op);
		if (err)
			return err;
		if (mv88e6xxx_num_databases(chip) > 64) {
			/* ATU DBNum[7:4] are located in ATU Control 15:12 */
			err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_ATU_CTL,
						&upper);
			if (err)
				return err;

			upper = (upper >> 8) & 0x00f0;
		} else if (mv88e6xxx_num_databases(chip) > 16) {
			/* ATU DBNum[5:4] are located in ATU Operation 9:8 */
			upper = (op >> 4) & 0x30;
		}

		/* ATU DBNum[3:0] are located in ATU Operation 3:0 */
		val = (op & 0xf) | upper;
	}
	*fid = val;

	return err;
}

/* Offset 0x0C: ATU Data Register */

static int mv88e6xxx_g1_atu_data_read(struct mv88e6xxx_chip *chip,
@@ -353,14 +402,12 @@ static irqreturn_t mv88e6xxx_g1_atu_prob_irq_thread_fn(int irq, void *dev_id)
{
	struct mv88e6xxx_chip *chip = dev_id;
	struct mv88e6xxx_atu_entry entry;
	int spid;
	int err;
	u16 val;
	int err, spid;
	u16 val, fid;

	mv88e6xxx_reg_lock(chip);

	err = mv88e6xxx_g1_atu_op(chip, 0,
				  MV88E6XXX_G1_ATU_OP_GET_CLR_VIOLATION);
	err = mv88e6xxx_g1_read_atu_violation(chip);
	if (err)
		goto out;

@@ -368,6 +415,10 @@ static irqreturn_t mv88e6xxx_g1_atu_prob_irq_thread_fn(int irq, void *dev_id)
	if (err)
		goto out;

	err = mv88e6xxx_g1_atu_fid_read(chip, &fid);
	if (err)
		goto out;

	err = mv88e6xxx_g1_atu_data_read(chip, &entry);
	if (err)
		goto out;
@@ -385,23 +436,24 @@ static irqreturn_t mv88e6xxx_g1_atu_prob_irq_thread_fn(int irq, void *dev_id)
	}

	if (val & MV88E6XXX_G1_ATU_OP_MEMBER_VIOLATION) {
		dev_err_ratelimited(chip->dev,
				    "ATU member violation for %pM portvec %x spid %d\n",
				    entry.mac, entry.portvec, spid);
		trace_mv88e6xxx_atu_member_violation(chip->dev, spid,
						     entry.portvec, entry.mac,
						     fid);
		chip->ports[spid].atu_member_violation++;
	}

	if (val & MV88E6XXX_G1_ATU_OP_MISS_VIOLATION) {
		dev_err_ratelimited(chip->dev,
				    "ATU miss violation for %pM portvec %x spid %d\n",
				    entry.mac, entry.portvec, spid);
		trace_mv88e6xxx_atu_miss_violation(chip->dev, spid,
						   entry.portvec, entry.mac,
						   fid);
		chip->ports[spid].atu_miss_violation++;
	}

	if (val & MV88E6XXX_G1_ATU_OP_FULL_VIOLATION) {
		dev_err_ratelimited(chip->dev,
				    "ATU full violation for %pM portvec %x spid %d\n",
				    entry.mac, entry.portvec, spid);
		trace_mv88e6xxx_atu_full_violation(chip->dev, spid,
						   entry.portvec, entry.mac,
						   fid);
		if (spid < ARRAY_SIZE(chip->ports))
			chip->ports[spid].atu_full_violation++;
	}
	mv88e6xxx_reg_unlock(chip);
+6 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-or-later
/* Copyright 2022 NXP
 */

#define CREATE_TRACE_POINTS
#include "trace.h"
+66 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* Copyright 2022 NXP
 */

#undef TRACE_SYSTEM
#define TRACE_SYSTEM	mv88e6xxx

#if !defined(_MV88E6XXX_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
#define _MV88E6XXX_TRACE_H

#include <linux/device.h>
#include <linux/if_ether.h>
#include <linux/tracepoint.h>

DECLARE_EVENT_CLASS(mv88e6xxx_atu_violation,

	TP_PROTO(const struct device *dev, int spid, u16 portvec,
		 const unsigned char *addr, u16 fid),

	TP_ARGS(dev, spid, portvec, addr, fid),

	TP_STRUCT__entry(
		__string(name, dev_name(dev))
		__field(int, spid)
		__field(u16, portvec)
		__array(unsigned char, addr, ETH_ALEN)
		__field(u16, fid)
	),

	TP_fast_assign(
		__assign_str(name, dev_name(dev));
		__entry->spid = spid;
		__entry->portvec = portvec;
		memcpy(__entry->addr, addr, ETH_ALEN);
		__entry->fid = fid;
	),

	TP_printk("dev %s spid %d portvec 0x%x addr %pM fid %u",
		  __get_str(name), __entry->spid, __entry->portvec,
		  __entry->addr, __entry->fid)
);

DEFINE_EVENT(mv88e6xxx_atu_violation, mv88e6xxx_atu_member_violation,
	     TP_PROTO(const struct device *dev, int spid, u16 portvec,
		      const unsigned char *addr, u16 fid),
	     TP_ARGS(dev, spid, portvec, addr, fid));

DEFINE_EVENT(mv88e6xxx_atu_violation, mv88e6xxx_atu_miss_violation,
	     TP_PROTO(const struct device *dev, int spid, u16 portvec,
		      const unsigned char *addr, u16 fid),
	     TP_ARGS(dev, spid, portvec, addr, fid));

DEFINE_EVENT(mv88e6xxx_atu_violation, mv88e6xxx_atu_full_violation,
	     TP_PROTO(const struct device *dev, int spid, u16 portvec,
		      const unsigned char *addr, u16 fid),
	     TP_ARGS(dev, spid, portvec, addr, fid));

#endif /* _MV88E6XXX_TRACE_H */

/* We don't want to use include/trace/events */
#undef TRACE_INCLUDE_PATH
#define TRACE_INCLUDE_PATH .
#undef TRACE_INCLUDE_FILE
#define TRACE_INCLUDE_FILE	trace
/* This part must be outside protection */
#include <trace/define_trace.h>