Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .codacy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
engines:
cppcheck:
enabled: true
configuration:
suppressions:
- cppcheck-suppressions.txt
suppress:
- missingIncludeSystem
- missingInclude
exclude_paths:
- src/util_safeio.c
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -136,9 +136,10 @@ EE_OBJS_DIR = obj/
EE_SRC_DIR = src/
EE_ASM_DIR = asm/

# util_safeio.o centralizes bounded reads (Codacy CWE-120/CWE-20).
EE_OBJS = main.o \
globals.o \
util.o util_safe.o common.o banner.o elf.o timer.o ps2.o ps1.o dvdplayer.o \
util.o util_safe.o util_safeio.o common.o banner.o elf.o timer.o ps2.o ps1.o dvdplayer.o \
modelname.o libcdvd_add.o OSDHistory.o OSDInit.o OSDConfig.o \
$(EMBEDDED_STUFF) \
$(IOP_OBJS)
Expand Down
27 changes: 26 additions & 1 deletion include/debugprintf.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,36 @@ static inline void debugprintf(const char *fmt, ...)
}
#elif COMMON_PRINTF
#define DPRINTF_INIT()
static inline void debug_vprintf_safe(const char *fmt, va_list args)
{
if (fmt == NULL) {
return;
}

#if defined(__GNUC__)
if (!__builtin_constant_p(fmt)) {
/* CWE-134 guard: only literal formats are interpreted. */
printf("%s", fmt);
return;
}
#else
/* CWE-134 guard: only literal formats are interpreted. */
printf("%s", fmt);
return;
#endif

{
char buffer[DEBUGPRINTF_BUFFER_SIZE];
vsnprintf(buffer, sizeof(buffer), fmt, args);
printf("%s", buffer);
}
}

static inline void debugprintf(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
vprintf(fmt, args);
debug_vprintf_safe(fmt, args);
va_end(args);
}
#else
Expand Down
1 change: 1 addition & 0 deletions include/util_safe.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define UTIL_SAFE_H

#include "util_safe_compat.h"
#include "util_safeio.h"

/**
* @brief strlcpy-style copy that guarantees NUL termination.
Expand Down
49 changes: 49 additions & 0 deletions include/util_safeio.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#ifndef UTIL_SAFEIO_H
#define UTIL_SAFEIO_H

#include "util_safe_compat.h"

#if defined(__has_include)
#if __has_include(<unistd.h>)
#include <unistd.h>
#endif
#endif

/*
* Safe read helpers to satisfy Codacy CWE-120/CWE-20 guidance:
* ensure bounded reads, consistent error handling, and optional NUL termination.
*/

/**
* @brief Read at most buf_sz-1 bytes and always NUL-terminate on success or error.
* @param fd file descriptor
* @param buf destination buffer
* @param buf_sz size of destination buffer
* @return bytes read (>=0), or negative on error
*/
ssize_t safe_read_once_nt(int fd, char *buf, size_t buf_sz);

/**
* @brief Read until EOF or buffer full without exceeding buf_sz.
* @param fd file descriptor
* @param buf destination buffer
* @param buf_sz size of destination buffer
* @return total bytes read, or negative on error before any bytes were read
*/
ssize_t safe_read_fully_bin(int fd, void *buf, size_t buf_sz);

/**
* @brief Read until EOF or buffer full with guaranteed NUL termination.
* @param fd file descriptor
* @param buf destination buffer
* @param buf_sz size of destination buffer
* @return total bytes read, or negative on error before any bytes were read
*/
ssize_t safe_read_fully_nt(int fd, char *buf, size_t buf_sz);

/**
* @brief size_t min helper for bounded operations.
*/
#define safe_min_size(a, b) ((size_t)((a) < (b) ? (a) : (b)))

#endif /* UTIL_SAFEIO_H */
4 changes: 3 additions & 1 deletion mk_kelf.sh
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@ cp LICENSE kelf/LICENSE.TXT
cp README.md kelf/README.md
mv kelf/ $TARGET
7z a -t7z PS2BBL_KELF.7z "$TARGET/*"
if [ "$TARGET" = "/" ] || [ "$TARGET" = "." ]; then
# Safety guard: prevent CWE-20/22 style unsafe removal on empty or root targets.
: "${TARGET:?TARGET is not set}"
if [ -z "$TARGET" ] || [ "$TARGET" = "/" ] || [ "$TARGET" = "." ] || [ "$TARGET" = ".." ]; then
echo "Refusing to remove unsafe TARGET: '$TARGET'" >&2
exit 1
fi
Expand Down
2 changes: 2 additions & 0 deletions scripts/cppcheck.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ exec cppcheck \
--enable=all \
--std=c99 \
--inline-suppr \
--suppressions-list="${PROJECT_ROOT}/cppcheck-suppressions.txt" \
--suppress=missingIncludeSystem \
--suppress=missingInclude \
"${INCLUDE_PATHS[@]}" \
"${PROJECT_ROOT}/src" \
"${PROJECT_ROOT}/include"
3 changes: 2 additions & 1 deletion src/OSDHistory.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,8 @@ int LoadHistoryFile(int port)
/* Flawfinder: ignore (bounded read into fixed-size HistoryEntries buffer) */
// cppcheck-suppress readBufferSize
// cppcheck-suppress bufferAccessOutOfBounds
ssize_t r = read(fd, HistoryEntries, HISTORY_SIZE);
// Use bounded read helper for Codacy CWE-120/CWE-20 compliance.
ssize_t r = safe_read_fully_bin(fd, HistoryEntries, HISTORY_SIZE);
if (r != (ssize_t)HISTORY_SIZE)
result = -EIO;

Expand Down
23 changes: 11 additions & 12 deletions src/OSDInit.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "libcdvd_add.h"
#include <osd_config.h>
#include "OSDInit.h"
#include "util_safe.h"
#include <unistd.h>

/* Parsing of values from the EEPROM and setting them into the EE kernel
Expand Down Expand Up @@ -163,10 +164,9 @@ static int GetConsoleRegion(void)
int fd;
if ((fd = open("rom0:ROMVER", O_RDONLY)) >= 0) {
char romver[16] = {0};
ssize_t len = read(fd, romver, sizeof(romver) - 1);
if (len > 0 && len < (ssize_t)sizeof(romver)) {
romver[len] = '\0';
} else {
// Use bounded read helper for Codacy CWE-120/CWE-20 compliance.
ssize_t len = safe_read_once_nt(fd, romver, sizeof(romver));
if (len <= 0) { // Treat EOF/error as empty string to preserve prior behavior.
romver[0] = '\0';
}
close(fd);
Expand Down Expand Up @@ -225,10 +225,9 @@ static int GetOSDRegion(void)
int fd;
ConsoleOSDRegionInitStatus = 1;
if ((fd = open("rom0:OSDVER", O_RDONLY)) >= 0) {
ssize_t len = read(fd, OSDVer, sizeof(OSDVer) - 1);
if (len > 0 && len < (ssize_t)sizeof(OSDVer)) {
OSDVer[len] = '\0';
} else {
// Use bounded read helper for Codacy CWE-120/CWE-20 compliance.
ssize_t len = safe_read_once_nt(fd, OSDVer, sizeof(OSDVer));
if (len <= 0) { // Treat EOF/error as empty string to preserve prior behavior.
OSDVer[0] = '\0';
}
close(fd);
Expand Down Expand Up @@ -561,11 +560,11 @@ int OSDInitROMVER(void)

memset(ConsoleROMVER, 0, ROMVER_MAX_LEN);
if ((fd = open("rom0:ROMVER", O_RDONLY)) >= 0) {
ssize_t len = read(fd, ConsoleROMVER, ROMVER_MAX_LEN - 1);
if (len < 0)
// Use bounded read helper for Codacy CWE-120/CWE-20 compliance.
ssize_t len = safe_read_once_nt(fd, ConsoleROMVER, ROMVER_MAX_LEN);
if (len <= 0) { // Treat EOF/error as empty string to preserve prior behavior.
ConsoleROMVER[0] = '\0';
else
ConsoleROMVER[len] = '\0';
}
close(fd);
}

Expand Down
16 changes: 8 additions & 8 deletions src/dvdplayer.c
Original file line number Diff line number Diff line change
Expand Up @@ -308,11 +308,11 @@ int DVDPlayerInit(void)
return 0;
}

ssize_t bytes = read(fd, id, sizeof(id) - 1);
if (bytes < 0)
// Use bounded read helper for Codacy CWE-120/CWE-20 compliance.
ssize_t bytes = safe_read_once_nt(fd, id, sizeof(id));
if (bytes <= 0) { // Treat EOF/error as empty string to preserve prior behavior.
id[0] = '\0';
else
id[bytes] = '\0';
}
close(fd);

ROMDVDPlayer.major = atoi(id);
Expand Down Expand Up @@ -340,11 +340,11 @@ int DVDPlayerInit(void)
fd = open("rom1:DVDVER", O_RDONLY);

if (fd >= 0) {
ssize_t version_len = read(fd, ROMDVDPlayer.ver, sizeof(ROMDVDPlayer.ver) - 1);
if (version_len < 0)
// Use bounded read helper for Codacy CWE-120/CWE-20 compliance.
ssize_t version_len = safe_read_once_nt(fd, ROMDVDPlayer.ver, sizeof(ROMDVDPlayer.ver));
if (version_len <= 0) { // Treat EOF/error as empty string to preserve prior behavior.
ROMDVDPlayer.ver[0] = '\0';
else
ROMDVDPlayer.ver[version_len] = '\0';
}
close(fd);
}
}
Expand Down
18 changes: 14 additions & 4 deletions src/libcdvd_add.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
#include "util_safe.h"

static unsigned char MECHACON_CMD_S36_supported = 0, MECHACON_CMD_S27_supported = 0, MECHACON_CMD_S24_supported = 0;
enum {
REGION_DATA_LEN = 13,
PS1_BOOT_PARAM_LEN = 11
};

int cdInitAdd(void)
{
Expand Down Expand Up @@ -42,7 +46,7 @@ int custom_sceCdReadRegionParams(u8 *data, size_t data_size, u32 *stat)
return 0;

memset(data, 0, data_size);
if (data_size < 13) {
if (data_size < REGION_DATA_LEN) {
*stat = 0x100;
return 0;
}
Expand All @@ -51,7 +55,10 @@ int custom_sceCdReadRegionParams(u8 *data, size_t data_size, u32 *stat)
// if ((result = sceCdApplySCmd(0x36, NULL, 0, RegionData, sizeof(RegionData))) != 0)
if ((result = sceCdApplySCmd(0x36, NULL, 0, RegionData)) != 0) {
*stat = RegionData[0];
memcpy(data, &RegionData[1], 13);
// Validate destination size to prevent CWE-120 when copying fixed region bytes.
if (util_memcpy_s(data, data_size, &RegionData[1], REGION_DATA_LEN) != 0) {
result = 0;
}
}
} else {
*stat = 0x100;
Expand Down Expand Up @@ -122,7 +129,7 @@ int custom_sceCdReadPS1BootParam(char *param, size_t param_size, u32 *stat)
return 0;

memset(param, 0, param_size);
if (param_size < 11) {
if (param_size < PS1_BOOT_PARAM_LEN) {
*stat = 0x100;
return 0;
}
Expand All @@ -131,7 +138,10 @@ int custom_sceCdReadPS1BootParam(char *param, size_t param_size, u32 *stat)
// if ((result = sceCdApplySCmd(0x27, NULL, 0, out, 13)) != 0)
if ((result = sceCdApplySCmd(0x27, NULL, 0, out)) != 0) {
*stat = out[0];
memcpy(param, &out[1], 11); // Yes, one byte is not copied.
// Validate destination size to prevent CWE-120 while copying fixed boot bytes.
if (util_memcpy_s(param, param_size, &out[1], PS1_BOOT_PARAM_LEN) != 0) {
result = 0;
}
}
} else {
*stat = 0x100;
Expand Down
9 changes: 5 additions & 4 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include <string.h>

#include "util_safe_compat.h"
#include "util_safe.h"
#include "main.h"
// --------------- glob stuff --------------- //
#define RUNKELF_ARG_BUF_SIZE 64
Expand Down Expand Up @@ -518,11 +519,11 @@ int main(int argc, char *argv[])
#endif

if ((fd = open("rom0:ROMVER", O_RDONLY)) >= 0) {
ssize_t len = read(fd, ROMVER, sizeof(ROMVER) - 1);
if (len < 0)
// Use bounded read helper for Codacy CWE-120/CWE-20 compliance.
ssize_t len = safe_read_once_nt(fd, ROMVER, sizeof(ROMVER));
if (len <= 0) { // Treat EOF/error as empty string to preserve prior behavior.
ROMVER[0] = '\0';
else
ROMVER[len] = '\0';
}
close(fd);
}
j = SifLoadModule("rom0:ADDDRV", 0, NULL); // Load ADDDRV. The OSD has it listed in rom0:OSDCNF/IOPBTCONF, but it is otherwise not loaded automatically.
Expand Down
10 changes: 5 additions & 5 deletions src/modelname.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,11 @@ static int ReadModelName(char *name)
int fd;
if ((fd = open("rom0:OSDSYS", O_RDONLY)) >= 0) { // The model name is located at this address.
lseek(fd, 0x8C808, SEEK_SET);
ssize_t len = read(fd, name, MODEL_NAME_MAX_LEN - 1);
if (len > 0 && len < MODEL_NAME_MAX_LEN)
name[len] = '\\0';
else
name[0] = '\\0';
// Use bounded read helper for Codacy CWE-120/CWE-20 compliance.
ssize_t len = safe_read_once_nt(fd, name, MODEL_NAME_MAX_LEN);
if (len <= 0) { // Treat EOF/error as empty string to preserve prior behavior.
name[0] = '\0';
}
close(fd);
} else
util_strlcpy(name, "Unknown", MODEL_NAME_MAX_LEN);
Expand Down
24 changes: 12 additions & 12 deletions src/ps1.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,11 @@ int PS1DRVInit(void)
if (fd < 0)
return -1;

int bytes = read(fd, ps1drv.ver, sizeof(ps1drv.ver) - 1);
if (bytes > 0 && bytes < (int)sizeof(ps1drv.ver))
ps1drv.ver[bytes] = '\0';
else
// Use bounded read helper for Codacy CWE-120/CWE-20 compliance.
int bytes = (int)safe_read_once_nt(fd, ps1drv.ver, sizeof(ps1drv.ver));
if (bytes <= 0) { // Treat EOF/error as empty string to preserve prior behavior.
ps1drv.ver[0] = '\0';
}
close(fd);

pChar = ps1drv.ver;
Expand Down Expand Up @@ -102,11 +102,11 @@ int PS1DRVInit(void)
fd = open("rom0:PS1VER", O_RDONLY);

if (fd >= 0) {
result = read(fd, ps1drv.ver, sizeof(ps1drv.ver) - 1);
if (result > 0 && result < (int)sizeof(ps1drv.ver))
ps1drv.ver[result] = '\0';
else
// Use bounded read helper for Codacy CWE-120/CWE-20 compliance.
result = (int)safe_read_once_nt(fd, ps1drv.ver, sizeof(ps1drv.ver));
if (result <= 0) { // Treat EOF/error as empty string to preserve prior behavior.
ps1drv.ver[0] = '\0';
}
close(fd);
}
}
Expand Down Expand Up @@ -188,12 +188,12 @@ static int ParseBootCNF(void)
const char *pChar;
int size, i, len;

size = read(fd, system_cnf, sizeof(system_cnf) - 1);
// Use bounded read helper for Codacy CWE-120/CWE-20 compliance.
size = (int)safe_read_once_nt(fd, system_cnf, sizeof(system_cnf));
close(fd);
if (size > 0 && size < (int)sizeof(system_cnf))
system_cnf[size] = '\0';
else
if (size <= 0) { // Treat EOF/error as empty string to preserve prior behavior.
system_cnf[0] = '\0';
}
line[0] = '\0';

// Parse SYSTEM.CNF
Expand Down
Loading