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..