-/* radare - LGPL - Copyright 2016-2023 - Oscar Salvador */
+/* radare - LGPL - Copyright 2016-2025 - Oscar Salvador */
#include <r_debug.h>
#include <r_util.h>
/* /proc/[pid]/stat */
/* we only need few fields which are process-wide */
+ /* fields: pid(1) comm(2) state(3) ppid(4) pgrp(5) sid(6) tty(7) tpgid(8) flags(9) ... nice(19) num_threads(20) */
{
- if (r_str_scanf (buff, "%d %*s %c %d %d %*d %*d %lu %ld",
+ int res = r_str_scanf (buff, "%d (%*[^)]) %c %d %d %d %*d %*d %d %*d %*d %*d %*d %*d %*d %*d %*d %*d %d %d",
&p->pid, &p->s_name, &p->ppid, &p->pgrp,
&p->sid, &p->flag,
- &p->nice, &p->num_threads) < 6) {
- free (buff);
- return NULL;
- }
+ &p->nice, &p->num_threads);
+ if (res < 8) {
+ free (buff);
+ return NULL;
+ }
free (buff);
}
if (!p->num_threads || p->num_threads < 1) {
static elf_shdr_t *get_extra_sectionhdr(elf_hdr_t *elf_hdr, st64 offset, int n_segments) {
elf_shdr_t *shdr = R_NEW0 (elf_shdr_t);
- if (!shdr) {
- return NULL;
- }
elf_hdr->e_shoff = offset;
elf_hdr->e_shentsize = sizeof (elf_shdr_t);
elf_hdr->e_shnum = 1;
write_note_hdr (type, ¬e_data);
memcpy (note_data, note_info[type].name, note_info[type].size_name);
note_data += note_info[type].size_name;
- memcpy (note_data, elf_proc_note->thread_note->fp_regset, note_info[type].size);
+ memcpy (note_data, elf_proc_note->thread_note->siginfo, note_info[type].size);
note_data += note_info[type].size_roundedup;
#if __arm__ || __arm64
}
proc_data->per_process = get_proc_process_content (dbg);
if (!proc_data->per_process) {
+ R_LOG_ERROR ("linux_generate_corefile: get_proc_process_content failed");
free (elf_proc_note);
free (proc_data);
return false;
/* NT_PRPSINFO */
elf_proc_note->prpsinfo = linux_get_prpsinfo (dbg, proc_data->per_process);
if (!elf_proc_note->prpsinfo) {
+ R_LOG_ERROR ("linux_generate_corefile: linux_get_prpsinfo failed");
error = true;
goto cleanup;
}
/* NT_AUXV */
elf_proc_note->auxv = linux_get_auxv (dbg);
if (!elf_proc_note->auxv) {
+ R_LOG_ERROR ("linux_generate_corefile: linux_get_auxv failed");
error = true;
goto cleanup;
}
/* NT_FILE */
elf_proc_note->maps = linux_get_mapped_files (dbg, proc_data->per_process->coredump_filter);
if (!elf_proc_note->maps) {
+ R_LOG_ERROR ("linux_generate_corefile: linux_get_mapped_files failed");
error = true;
goto cleanup;
}
init_note_info_structure(dbg, dbg->pid, elf_proc_note->auxv->size);
note_data = build_note_section (dbg, elf_proc_note, proc_data, ¬e_section_size);
if (!note_data) {
+ R_LOG_ERROR ("linux_generate_corefile: build_note_section failed");
error = true;
goto cleanup;
}
elf_hdr = build_elf_hdr (n_segments);
if (!elf_hdr) {
+ R_LOG_ERROR ("linux_generate_corefile: build_elf_hdr failed");
error = true;
goto cleanup;
}
goto beach;
}
// process scanset and fill the string
- /* String conversion requires a width. */
- _BSCANF_CHECK_STRING ();
/* '[' conversion specifiers DO NOT consume whitespace. */
- char_ptr = va_arg (args, char*);
- _BSCANF_CHECK_NULL (char_ptr);
- *char_ptr = 0; // null byte the first char before failing
- if (max_width < 1) {
- R_LOG_DEBUG ("Missing length specifier for string");
- } else {
- for (; *buf_ptr && max_width > 0; max_width--) {
- if (!scanset_check (scanset, *buf_ptr)) {
- break;
- }
- *char_ptr = *buf_ptr;
- char_ptr++;
+ if (is_suppressed) {
+ /* Consume matching characters and ignore them */
+ while (*buf_ptr && scanset_check (scanset, *buf_ptr)) {
buf_ptr++;
}
- if (max_width == 0) {
- R_LOG_DEBUG ("Truncated string in scanf");
+ } else {
+ /* String conversion requires a width. */
+ _BSCANF_CHECK_STRING ();
+ char_ptr = va_arg (args, char*);
+ _BSCANF_CHECK_NULL (char_ptr);
+ *char_ptr = 0; // null byte the first char before failing
+ if (max_width < 1) {
+ R_LOG_DEBUG ("Missing length specifier for string");
+ } else {
+ for (; *buf_ptr && max_width > 0; max_width--) {
+ if (!scanset_check (scanset, *buf_ptr)) {
+ break;
+ }
+ *char_ptr = *buf_ptr;
+ char_ptr++;
+ buf_ptr++;
+ }
+ if (max_width == 0) {
+ R_LOG_DEBUG ("Truncated string in scanf");
+ }
+ /* Strings must be null-terminated. */
+ *char_ptr = '\0';
+ num_args_set++;
}
- /* Strings must be null-terminated. */
- *char_ptr = '\0';
- num_args_set++;
}
// reset max width value
max_width = 0;
- if (*fmt_ptr == 0) {
- // end of string not expecting anything after that
- break;
- }
+ // scanset_parse already advanced fmt_ptr past ']', skip the extra fmt_ptr++ at end of loop
+ continue;
} else if ('i' == *fmt_ptr || 'd' == *fmt_ptr) {
/* 'i'/'d': match a integer/decimal integer. */
_BSCANF_CONSUME_WSPACE ();
beach:
va_end (args);
+ /* According to scanf family semantics, return EOF (-1) if no conversions were performed
+ * and an input failure occurred (e.g., buffer ended). Otherwise return number of
+ * successfully assigned inputs. */
+ if (num_args_set == 0 && *buf_ptr == '\0') {
+ return EOF;
+ }
return num_args_set;
}