From: Vadim Fedorenko <vadim.fedorenko@linux.dev>
To: Sagi Maimon <maimon.sagi@gmail.com>,
jonathan.lemon@gmail.com, richardcochran@gmail.com,
andrew+netdev@lunn.ch, davem@davemloft.net, edumazet@google.com,
kuba@kernel.org, pabeni@redhat.com
Cc: linux-kernel@vger.kernel.org, netdev@vger.kernel.org
Subject: Re: [PATCH v4] ptp: ocp: Limit signal/freq counts in show/store functions
Date: Tue, 13 May 2025 20:53:37 +0100 [thread overview]
Message-ID: <4ef4472b-62a5-43f6-bd16-d6e0ace2335a@linux.dev> (raw)
In-Reply-To: <20250511154235.101780-1-maimon.sagi@gmail.com>
On 11.05.2025 16:42, Sagi Maimon wrote:
> The sysfs show/store operations could access uninitialized elements
> in the freq_in[] and signal_out[] arrays, leading to NULL pointer
> dereferences. This patch introduces u8 fields (nr_freq_in,
> nr_signal_out) to track the number of initialized elements, capping
> the maximum at 4 for each array. The show/store functions are updated
> to respect these limits, preventing out-of-bounds access and ensuring
> safe array handling.
>
> Signed-off-by: Sagi Maimon <maimon.sagi@gmail.com>
> ---
> Addressed comments from Vadim Fedorenko:
> - https://www.spinics.net/lists/netdev/msg1090730.html
> Changes since v3:
> - in signal/freq show routine put constant string "UNSUPPORTED" in
> output instead of returning error.
> ---
> ---
> drivers/ptp/ptp_ocp.c | 40 +++++++++++++++++++++++++++++++++-------
> 1 file changed, 33 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/ptp/ptp_ocp.c b/drivers/ptp/ptp_ocp.c
> index 2ccdca4f6960..14b4b3bebccd 100644
> --- a/drivers/ptp/ptp_ocp.c
> +++ b/drivers/ptp/ptp_ocp.c
> @@ -315,6 +315,8 @@ struct ptp_ocp_serial_port {
> #define OCP_BOARD_ID_LEN 13
> #define OCP_SERIAL_LEN 6
> #define OCP_SMA_NUM 4
> +#define OCP_SIGNAL_NUM 4
> +#define OCP_FREQ_NUM 4
>
> enum {
> PORT_GNSS,
> @@ -342,8 +344,8 @@ struct ptp_ocp {
> struct dcf_master_reg __iomem *dcf_out;
> struct dcf_slave_reg __iomem *dcf_in;
> struct tod_reg __iomem *nmea_out;
> - struct frequency_reg __iomem *freq_in[4];
> - struct ptp_ocp_ext_src *signal_out[4];
> + struct frequency_reg __iomem *freq_in[OCP_FREQ_NUM];
> + struct ptp_ocp_ext_src *signal_out[OCP_SIGNAL_NUM];
> struct ptp_ocp_ext_src *pps;
> struct ptp_ocp_ext_src *ts0;
> struct ptp_ocp_ext_src *ts1;
> @@ -378,10 +380,12 @@ struct ptp_ocp {
> u32 utc_tai_offset;
> u32 ts_window_adjust;
> u64 fw_cap;
> - struct ptp_ocp_signal signal[4];
> + struct ptp_ocp_signal signal[OCP_SIGNAL_NUM];
> struct ptp_ocp_sma_connector sma[OCP_SMA_NUM];
> const struct ocp_sma_op *sma_op;
> struct dpll_device *dpll;
> + int signals_nr;
> + int freq_in_nr;
> };
>
> #define OCP_REQ_TIMESTAMP BIT(0)
> @@ -2697,6 +2701,8 @@ ptp_ocp_fb_board_init(struct ptp_ocp *bp, struct ocp_resource *r)
> bp->eeprom_map = fb_eeprom_map;
> bp->fw_version = ioread32(&bp->image->version);
> bp->sma_op = &ocp_fb_sma_op;
> + bp->signals_nr = 4;
> + bp->freq_in_nr = 4;
>
> ptp_ocp_fb_set_version(bp);
>
> @@ -2862,6 +2868,8 @@ ptp_ocp_art_board_init(struct ptp_ocp *bp, struct ocp_resource *r)
> bp->fw_version = ioread32(&bp->reg->version);
> bp->fw_tag = 2;
> bp->sma_op = &ocp_art_sma_op;
> + bp->signals_nr = 4;
> + bp->freq_in_nr = 4;
>
> /* Enable MAC serial port during initialisation */
> iowrite32(1, &bp->board_config->mro50_serial_activate);
> @@ -2888,6 +2896,8 @@ ptp_ocp_adva_board_init(struct ptp_ocp *bp, struct ocp_resource *r)
> bp->flash_start = 0xA00000;
> bp->eeprom_map = fb_eeprom_map;
> bp->sma_op = &ocp_adva_sma_op;
> + bp->signals_nr = 2;
> + bp->freq_in_nr = 2;
>
> version = ioread32(&bp->image->version);
> /* if lower 16 bits are empty, this is the fw loader. */
> @@ -3190,6 +3200,9 @@ signal_store(struct device *dev, struct device_attribute *attr,
> if (!argv)
> return -ENOMEM;
>
> + if (gen >= bp->signals_nr)
> + return -EINVAL;
> +
> err = -EINVAL;
> s.duty = bp->signal[gen].duty;
> s.phase = bp->signal[gen].phase;
> @@ -3247,6 +3260,10 @@ signal_show(struct device *dev, struct device_attribute *attr, char *buf)
> int i;
>
> i = (uintptr_t)ea->var;
> +
> + if (i >= bp->signals_nr)
> + return sysfs_emit(buf, "UNSUPPORTED\n");
> +
> signal = &bp->signal[i];
I've checked the code again. Jakub is right, there is no need to modify
singal/seconds/frequency show/set functions. Now I'm not quite sure how is it
possible to reach this functions with unsupported input? You export a specific
set of attributes for your card:
static const struct ocp_attr_group adva_timecard_groups[] = {
{ .cap = OCP_CAP_BASIC, .group = &adva_timecard_group },
{ .cap = OCP_CAP_BASIC, .group = &ptp_ocp_timecard_tty_group },
{ .cap = OCP_CAP_SIGNAL, .group = &fb_timecard_signal0_group },
{ .cap = OCP_CAP_SIGNAL, .group = &fb_timecard_signal1_group },
{ .cap = OCP_CAP_FREQ, .group = &fb_timecard_freq0_group },
{ .cap = OCP_CAP_FREQ, .group = &fb_timecard_freq1_group },
{ },
};
It has only freq1, freq2, gen1, gen2 attributes exported to sysfs. How can it
happen that you can change freq3 or gen3?
The only problem I see is in the summary output - that should be addressed with
this patch (well, you've done it already).
>
> count = sysfs_emit(buf, "%llu %d %llu %d", signal->period,
> @@ -3359,6 +3376,9 @@ seconds_store(struct device *dev, struct device_attribute *attr,
> u32 val;
> int err;
>
> + if (idx >= bp->freq_in_nr)
> + return -EINVAL;
> +
> err = kstrtou32(buf, 0, &val);
> if (err)
> return err;
> @@ -3381,6 +3401,9 @@ seconds_show(struct device *dev, struct device_attribute *attr, char *buf)
> int idx = (uintptr_t)ea->var;
> u32 val;
>
> + if (idx >= bp->freq_in_nr)
> + return sysfs_emit(buf, "UNSUPPORTED\n");
> +
> val = ioread32(&bp->freq_in[idx]->ctrl);
> if (val & 1)
> val = (val >> 8) & 0xff;
> @@ -3402,6 +3425,9 @@ frequency_show(struct device *dev, struct device_attribute *attr, char *buf)
> int idx = (uintptr_t)ea->var;
> u32 val;
>
> + if (idx >= bp->freq_in_nr)
> + return -EINVAL;
> +
> val = ioread32(&bp->freq_in[idx]->status);
> if (val & FREQ_STATUS_ERROR)
> return sysfs_emit(buf, "error\n");
> @@ -4008,7 +4034,7 @@ _signal_summary_show(struct seq_file *s, struct ptp_ocp *bp, int nr)
> {
> struct signal_reg __iomem *reg = bp->signal_out[nr]->mem;
> struct ptp_ocp_signal *signal = &bp->signal[nr];
> - char label[8];
> + char label[16];
> bool on;
> u32 val;
>
> @@ -4031,7 +4057,7 @@ static void
> _frequency_summary_show(struct seq_file *s, int nr,
> struct frequency_reg __iomem *reg)
> {
> - char label[8];
> + char label[16];
> bool on;
> u32 val;
>
> @@ -4175,11 +4201,11 @@ ptp_ocp_summary_show(struct seq_file *s, void *data)
> }
>
> if (bp->fw_cap & OCP_CAP_SIGNAL)
> - for (i = 0; i < 4; i++)
> + for (i = 0; i < bp->signals_nr; i++)
> _signal_summary_show(s, bp, i);
>
> if (bp->fw_cap & OCP_CAP_FREQ)
> - for (i = 0; i < 4; i++)
> + for (i = 0; i < bp->freq_in_nr; i++)
> _frequency_summary_show(s, i, bp->freq_in[i]);
>
> if (bp->irig_out) {
---
pw-bot:cr
next prev parent reply other threads:[~2025-05-13 19:53 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-05-11 15:42 [PATCH v4] ptp: ocp: Limit signal/freq counts in show/store functions Sagi Maimon
2025-05-11 21:16 ` Vadim Fedorenko
2025-05-13 19:53 ` Vadim Fedorenko [this message]
2025-05-14 6:01 ` Sagi Maimon
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4ef4472b-62a5-43f6-bd16-d6e0ace2335a@linux.dev \
--to=vadim.fedorenko@linux.dev \
--cc=andrew+netdev@lunn.ch \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=jonathan.lemon@gmail.com \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=maimon.sagi@gmail.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=richardcochran@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.