Does anyone get strncpy right?
I decided to have a quick look at OpenBIOS. 5 seconds in, it's clear that strncpy is used incorrectly in a number of places. OpenBSD realised many years ago how prone to bugs strncpy was and replaced it with the non standard strlcpy.
static void create_free_part( char *ptr, int size ) { nvpart_t *nvp = (nvpart_t*)ptr; memset( nvp, 0, size ); strncpy( nvp->name, "777777777777", sizeof(nvp->name) ); nvp->signature = NV_SIG_FREE; nvp->len_hi = (size /16) >> 8; nvp->len_lo = size /16; nvp->checksum = nvpart_checksum(nvp); }And more..
static int create_nv_part( int signature, const char *name, int size ) { nvpart_t *p = NULL; int fs; while( next_nvpart(&p) > 0 ) { if( p->signature != NV_SIG_FREE ) continue; fs = nvpart_size( p ); if( fs < size ) size = fs; p->signature = signature; memset( p->name, 0, sizeof(p->name) ); strncpy( p->name, name, sizeof(p->name) ); p->len_hi = (size>>8)/16; p->len_lo = size/16; p->checksum = nvpart_checksum(p); if( fs > size ) { char *fp = (char*)p + size; create_free_part( fp, fs-size ); } return size; } printk("create-failed\n"); return -1; }And more..
intprop = get_int_property(chosen, "stdout", &proplen); PUSH(intprop); fword("get-instance-path"); ((struct linux_romvec *)romvec)->pv_stdout = pop_fstr_copy(); /* Get the name of the selected boot device, along with the device and u nit number */ prop = get_property(chosen, "bootpath", &proplen); strncpy(bootpathbuf, prop, proplen); prop = get_property(chosen, "bootargs", &proplen); strncpy(bootargsbuf, prop, proplen); /* Set bootpath pointer used in romvec table to the bootpath */ push_str(bootpathbuf); fword("pathres-resolve-aliases"); bootpath = pop_fstr_copy(); printk("bootpath: %s\n", bootpath);There are a number of more cases of this simple bug, but I think the readers get the point..