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

Comments

Popular posts from this blog

Linux Kernel Infoleaks

Memory Bugs in Multiple Linux Kernel Drivers using DebugFS

ESP8266 Firmware Buffer Overflows