Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

ptp: ocp: Limit signal/freq counts in summary output functions

The debugfs summary output could access uninitialized elements in
the freq_in[] and signal_out[] arrays, causing NULL pointer
dereferences and triggering a kernel Oops (page_fault_oops).
This patch adds u8 fields (nr_freq_in, nr_signal_out) to track the
number of initialized elements, with a maximum of 4 per array.
The summary output functions are updated to respect these limits,
preventing out-of-bounds access and ensuring safe array handling.

Widen the label variables because the change confuses GCC about
max length of the strings.

Fixes: ef61f5528fca ("ptp: ocp: add Adva timecard support")
Signed-off-by: Sagi Maimon <maimon.sagi@gmail.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
Link: https://patch.msgid.link/20250514073541.35817-1-maimon.sagi@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Sagi Maimon and committed by
Jakub Kicinski
c9e45558 c39b1bb5

+17 -7
+17 -7
drivers/ptp/ptp_ocp.c
··· 315 315 #define OCP_BOARD_ID_LEN 13 316 316 #define OCP_SERIAL_LEN 6 317 317 #define OCP_SMA_NUM 4 318 + #define OCP_SIGNAL_NUM 4 319 + #define OCP_FREQ_NUM 4 318 320 319 321 enum { 320 322 PORT_GNSS, ··· 344 342 struct dcf_master_reg __iomem *dcf_out; 345 343 struct dcf_slave_reg __iomem *dcf_in; 346 344 struct tod_reg __iomem *nmea_out; 347 - struct frequency_reg __iomem *freq_in[4]; 348 - struct ptp_ocp_ext_src *signal_out[4]; 345 + struct frequency_reg __iomem *freq_in[OCP_FREQ_NUM]; 346 + struct ptp_ocp_ext_src *signal_out[OCP_SIGNAL_NUM]; 349 347 struct ptp_ocp_ext_src *pps; 350 348 struct ptp_ocp_ext_src *ts0; 351 349 struct ptp_ocp_ext_src *ts1; ··· 380 378 u32 utc_tai_offset; 381 379 u32 ts_window_adjust; 382 380 u64 fw_cap; 383 - struct ptp_ocp_signal signal[4]; 381 + struct ptp_ocp_signal signal[OCP_SIGNAL_NUM]; 384 382 struct ptp_ocp_sma_connector sma[OCP_SMA_NUM]; 385 383 const struct ocp_sma_op *sma_op; 386 384 struct dpll_device *dpll; 385 + int signals_nr; 386 + int freq_in_nr; 387 387 }; 388 388 389 389 #define OCP_REQ_TIMESTAMP BIT(0) ··· 2701 2697 bp->eeprom_map = fb_eeprom_map; 2702 2698 bp->fw_version = ioread32(&bp->image->version); 2703 2699 bp->sma_op = &ocp_fb_sma_op; 2700 + bp->signals_nr = 4; 2701 + bp->freq_in_nr = 4; 2704 2702 2705 2703 ptp_ocp_fb_set_version(bp); 2706 2704 ··· 2868 2862 bp->fw_version = ioread32(&bp->reg->version); 2869 2863 bp->fw_tag = 2; 2870 2864 bp->sma_op = &ocp_art_sma_op; 2865 + bp->signals_nr = 4; 2866 + bp->freq_in_nr = 4; 2871 2867 2872 2868 /* Enable MAC serial port during initialisation */ 2873 2869 iowrite32(1, &bp->board_config->mro50_serial_activate); ··· 2896 2888 bp->flash_start = 0xA00000; 2897 2889 bp->eeprom_map = fb_eeprom_map; 2898 2890 bp->sma_op = &ocp_adva_sma_op; 2891 + bp->signals_nr = 2; 2892 + bp->freq_in_nr = 2; 2899 2893 2900 2894 version = ioread32(&bp->image->version); 2901 2895 /* if lower 16 bits are empty, this is the fw loader. */ ··· 4018 4008 { 4019 4009 struct signal_reg __iomem *reg = bp->signal_out[nr]->mem; 4020 4010 struct ptp_ocp_signal *signal = &bp->signal[nr]; 4021 - char label[8]; 4011 + char label[16]; 4022 4012 bool on; 4023 4013 u32 val; 4024 4014 ··· 4041 4031 _frequency_summary_show(struct seq_file *s, int nr, 4042 4032 struct frequency_reg __iomem *reg) 4043 4033 { 4044 - char label[8]; 4034 + char label[16]; 4045 4035 bool on; 4046 4036 u32 val; 4047 4037 ··· 4185 4175 } 4186 4176 4187 4177 if (bp->fw_cap & OCP_CAP_SIGNAL) 4188 - for (i = 0; i < 4; i++) 4178 + for (i = 0; i < bp->signals_nr; i++) 4189 4179 _signal_summary_show(s, bp, i); 4190 4180 4191 4181 if (bp->fw_cap & OCP_CAP_FREQ) 4192 - for (i = 0; i < 4; i++) 4182 + for (i = 0; i < bp->freq_in_nr; i++) 4193 4183 _frequency_summary_show(s, i, bp->freq_in[i]); 4194 4184 4195 4185 if (bp->irig_out) {