Language: C
Label: safe
CWE: CWE-787 \u2014 Out-of-bounds Write
The product writes data past the end, or before the beginning, of the intended buffer.

Code:
static void process_constructors(RKernelCacheObj *obj, struct MACH0_(obj_t) *mach0, RList *ret, ut64 paddr, bool is_first, int mode, const char *prefix) {
	const RVector *sections = MACH0_(load_sections) (mach0);
	if (!sections) {
		return;
	}
	int type;
	struct section_t *section;
	r_vector_foreach (sections, section) {
		if (section->size == 0) {
			continue;
		}

		if (strstr (section->name, "_mod_fini_func") || strstr (section->name, "_mod_term_func")) {
			type  = R_BIN_ENTRY_TYPE_FINI;
		} else if (strstr (section->name, "_mod_init_func")) {
			type  = is_first ? 0 : R_BIN_ENTRY_TYPE_INIT;
			is_first = false;
		} else {
			continue;
		}

		ut8 *buf = calloc (section->size, 1);
		if (!buf) {
			break;
		}
		if (r_buf_read_at (obj->cache_buf, section->paddr + paddr, buf, section->size) < section->size) {
			free (buf);
			break;
		}
		int j;
		int count = 0;
		for (j = 0; j + 7 < section->size; j += 8) {
			ut64 addr64 = K_RPTR (buf + j);
			ut64 paddr64 = section->paddr + paddr + j;
			if (mode == R_K_CONSTRUCTOR_TO_ENTRY) {
				RBinAddr *ba = newEntry (paddr64, addr64, type);
				r_list_append (ret, ba);
			} else if (mode == R_K_CONSTRUCTOR_TO_SYMBOL) {
				RBinSymbol *sym = R_NEW0 (RBinSymbol);
				if (!sym) {
					break;
				}

				sym->name = r_str_newf ("%s.%s.%d", prefix, (type == R_BIN_ENTRY_TYPE_INIT) ? "init" : "fini", count++);
				sym->vaddr = addr64;
				sym->paddr = paddr64;
				sym->size = 0;
				sym->forwarder = "NONE";
				sym->bind = "GLOBAL";
				sym->type = "FUNC";

				r_list_append (ret, sym);
			}
		}
		free (buf);
	}
}