Replace most uses of strncpy with strlcpy.
authorDan Cross <dcross@google.com>
Fri, 16 Oct 2015 16:24:55 +0000 (12:24 -0400)
committerBarret Rhoden <brho@cs.berkeley.edu>
Wed, 28 Oct 2015 16:40:41 +0000 (12:40 -0400)
Strncpy has strange and subtle semantics; it was being used
incorrectly in many places. Replace almost everywhere with
strlcpy or memmove.

Note that spatch will in some cases introduce simply incorrect
code when it replaces calls to strcpy; it will take sizeof()
the destination argument, but if that's a pointer, then one
ends up with the size of the pointer type (for our platforms,
8 bytes) instead of the proper size of the destination. When
I saw things like that, I fixed them.

Signed-off-by: Dan Cross <dcross@google.com>
[Minor checkpatch touchups]
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
26 files changed:
kern/arch/x86/devarch.c
kern/drivers/dev/acpi.c
kern/drivers/dev/mnt.c
kern/drivers/dev/pci.c
kern/drivers/dev/pipe.c
kern/drivers/dev/proc.c
kern/drivers/dev/root.c
kern/drivers/dev/srv.c
kern/include/ip.h
kern/include/ns.h
kern/src/blockdev.c
kern/src/ext2fs.c
kern/src/kdebug.c
kern/src/kfs.c
kern/src/monitor.c
kern/src/net/arp.c
kern/src/net/devip.c
kern/src/net/dial.c
kern/src/net/ipifc.c
kern/src/net/kernel.h
kern/src/net/netif.c
kern/src/ns/chan.c
kern/src/ns/parse.c
kern/src/ns/qio.c
kern/src/process.c
kern/src/vfs.c

index 777133c..8f0f541 100644 (file)
@@ -107,7 +107,7 @@ struct dirtab *addarchfile(char *name, int perm, Rdwrfn * rdfn, Rdwrfn * wrfn)
        }
 
        for (i = 0; i < narchdir; i++)
-               if (strcmp(archdir[i].name, name) == 0) {
+               if (strncmp(archdir[i].name, name, KNAMELEN) == 0) {
                        spin_unlock(&archwlock);
                        return NULL;
                }
@@ -193,8 +193,7 @@ int ioreserve(int unused_int, int size, int align, char *tag)
        map->start = port;
        map->end = port + size;
        map->reserved = 1;
-       strncpy(map->tag, tag, sizeof(map->tag));
-       map->tag[sizeof(map->tag) - 1] = 0;
+       strlcpy(map->tag, tag, sizeof(map->tag));
        *l = map;
 
        archdir[0].qid.vers++;
@@ -264,8 +263,7 @@ int ioalloc(int port, int size, int align, char *tag)
        map->next = *l;
        map->start = port;
        map->end = port + size;
-       strncpy(map->tag, tag, sizeof(map->tag));
-       map->tag[sizeof(map->tag) - 1] = 0;
+       strlcpy(map->tag, tag, sizeof(map->tag));
        *l = map;
 
        archdir[0].qid.vers++;
index 7d15582..9497051 100644 (file)
@@ -1570,7 +1570,7 @@ static long acpiread(struct chan *c, void *a, long n, int64_t off)
                case Qtbl:
                        s = ttext;
                        e = ttext + tlen;
-                       strncpy(s, "no tables\n", sizeof(s));
+                       strlcpy(s, "no tables\n", tlen);
                        for (t = tfirst; t != NULL; t = t->next) {
                                ns = seprinttable(s, e, t);
                                while (ns == e - 1) {
index b77f5da..350f522 100644 (file)
@@ -179,7 +179,7 @@ long mntversion(struct chan *c, char *version, int msize, int returnlen)
                qunlock(&c->umqlock);
                poperror();
 
-               strncpy(buf, m->version, sizeof buf);
+               strlcpy(buf, m->version, sizeof(buf));
                k = strlen(buf);
                if (strncmp(buf, v, k) != 0) {
                        snprintf(buf, sizeof buf, "incompatible 9P versions %s %s",
index c28c8ce..5556931 100644 (file)
@@ -35,6 +35,8 @@ enum {
        Qpcidir,
        Qpcictl,
        Qpciraw,
+
+       PCI_CONFIG_SZ = 256,
 };
 
 #define TYPE(q)                ((uint32_t)(q).path & 0x0F)
@@ -144,7 +146,7 @@ static void pciclose(struct chan *)
 
 static long pciread(struct chan *c, void *va, long n, int64_t offset)
 {
-       char buf[256], *ebuf, *w, *a;
+       char buf[PCI_CONFIG_SZ], *ebuf, *w, *a;
        int i, tbdf, r;
        uint32_t x;
        Pcidev *p;
@@ -206,17 +208,14 @@ static long pciread(struct chan *c, void *va, long n, int64_t offset)
 
 static long pciwrite(struct chan *c, void *va, long n, int64_t offset)
 {
-       char buf[256];
        uint8_t *a;
        int i, r, tbdf;
        uint32_t x;
        Pcidev *p;
 
-       if (n >= sizeof(buf))
-               n = sizeof(buf) - 1;
+       if (n > PCI_CONFIG_SZ)
+               n = PCI_CONFIG_SZ;
        a = va;
-       strncpy(buf, (char *unused_char_p_t)a, n);
-       buf[n] = 0;
 
        switch (TYPE(c->qid)) {
                case Qpciraw:
@@ -224,10 +223,10 @@ static long pciwrite(struct chan *c, void *va, long n, int64_t offset)
                        p = pcimatchtbdf(tbdf);
                        if (p == NULL)
                                error(EINVAL, NULL);
-                       if (offset > 256)
+                       if (offset > PCI_CONFIG_SZ)
                                return 0;
-                       if (n + offset > 256)
-                               n = 256 - offset;
+                       if (n + offset > PCI_CONFIG_SZ)
+                               n = PCI_CONFIG_SZ - offset;
                        r = offset;
                        if (!(r & 3) && n == 4) {
                                x = GBIT32(a);
index e4ba83d..f59c62f 100644 (file)
@@ -442,7 +442,7 @@ static long pipebwrite(struct chan *c, struct block *bp, uint32_t junk)
        return n;
 }
 
-static int pipewstat(struct chan *c, uint8_t * dp, int n)
+static int pipewstat(struct chan *c, uint8_t *dp, int n)
 {
        ERRSTACK(2);
        struct dir *d;
@@ -467,10 +467,9 @@ static int pipewstat(struct chan *c, uint8_t * dp, int n)
                validwstatname(d->name);
                if (strlen(d->name) >= KNAMELEN)
                        error(ENAMETOOLONG, NULL);
-               if (strcmp(p->pipedir[1 + !d1].name, d->name) == 0)
+               if (strncmp(p->pipedir[1 + !d1].name, d->name, KNAMELEN) == 0)
                        error(EEXIST, NULL);
-               strncpy(p->pipedir[1 + d1].name, d->name,
-                               MIN(KNAMELEN, sizeof(p->pipedir[1 + d1].name, d->name)));
+               strncpy(p->pipedir[1 + d1].name, d->name, KNAMELEN);
        }
        if (d->mode != ~0UL)
                p->pipedir[d1 + 1].perm = d->mode & 0777;
index 2266137..319904f 100644 (file)
@@ -216,13 +216,13 @@ procgen(struct chan *c, char *name, struct dirtab *tab, int unused, int s,
 
        if (c->qid.path == Qdir) {
                if (s == 0) {
-                       strncpy(get_cur_genbuf(), "trace", GENBUF_SZ);
+                       strlcpy(get_cur_genbuf(), "trace", GENBUF_SZ);
                        mkqid(&qid, Qtrace, -1, QTFILE);
                        devdir(c, qid, get_cur_genbuf(), 0, eve, 0444, dp);
                        return 1;
                }
                if (s == 1) {
-                       strncpy(get_cur_genbuf(), "tracepids", GENBUF_SZ);
+                       strlcpy(get_cur_genbuf(), "tracepids", GENBUF_SZ);
                        mkqid(&qid, Qtracepids, -1, QTFILE);
                        devdir(c, qid, get_cur_genbuf(), 0, eve, 0444, dp);
                        return 1;
@@ -264,13 +264,13 @@ procgen(struct chan *c, char *name, struct dirtab *tab, int unused, int s,
                return 1;
        }
        if (c->qid.path == Qtrace) {
-               strncpy(get_cur_genbuf(), "trace", GENBUF_SZ);
+               strlcpy(get_cur_genbuf(), "trace", GENBUF_SZ);
                mkqid(&qid, Qtrace, -1, QTFILE);
                devdir(c, qid, get_cur_genbuf(), 0, eve, 0444, dp);
                return 1;
        }
        if (c->qid.path == Qtracepids) {
-               strncpy(get_cur_genbuf(), "tracepids", GENBUF_SZ);
+               strlcpy(get_cur_genbuf(), "tracepids", GENBUF_SZ);
                mkqid(&qid, Qtracepids, -1, QTFILE);
                devdir(c, qid, get_cur_genbuf(), 0, eve, 0444, dp);
                return 1;
index b8054d3..a39045a 100644 (file)
@@ -285,7 +285,7 @@ rootgen(struct chan *c, char *name,
                tab = &roottab[rootdata[path].child];
                /* we're starting at a directory. It might be '.' */
                for (iter = 0, i = rootdata[path].child; /* break */; iter++) {
-                       if(strcmp(tab->name, name) == 0){
+                       if (strncmp(tab->name, name, KNAMELEN) == 0) {
                                printd("Rootgen returns 1 for %s\n", name);
                                devdir(c, tab->qid, tab->name, tab->length, eve, tab->perm, dp);
                                printd("return 1 with [%d, %d, %d]\n", dp->qid.path,
index 704b6a1..db09385 100644 (file)
@@ -118,7 +118,7 @@ static int srvgen(struct chan *c, char *name, struct dirtab *tab,
        c->aux = next;  /* uncounted ref */
        mkqid(&q, Qsrvfile, 0, QTFILE);
        /* once we release the lock, next could disappear, including next->name */
-       strncpy(get_cur_genbuf(), next->name, GENBUF_SZ);
+       strlcpy(get_cur_genbuf(), next->name, GENBUF_SZ);
        devdir(c, q, get_cur_genbuf(), 1 /* length */ , next->user, next->perm, dp);
        spin_unlock(&srvlock);
        return 1;
@@ -312,8 +312,7 @@ static long srvwrite(struct chan *c, void *va, long count, int64_t offset)
                nexterror();
        }
        kbuf = kmalloc(count + 1, KMALLOC_WAIT);
-       strncpy(kbuf, va, count);
-       kbuf[count] = 0;
+       strlcpy(kbuf, va, count + 1);
        fd = strtoul(kbuf, 0, 10);
        /* the magic of srv: srv stores the chan corresponding to the fd.  -1 for
         * mode, so we just get the chan with no checks (RDWR would work too). */
index 3f760e1..7744c51 100644 (file)
@@ -540,7 +540,7 @@ struct arpent {
 
 extern void arpinit(struct Fs *);
 extern int arpread(struct arp *, char *unused_char_p_t, uint32_t, int);
-extern int arpwrite(struct Fs *, char *unused_char_p_t, int);
+extern int arpwrite(struct Fs *, char *unused_char_p_t, long);
 extern struct arpent *arpget(struct arp *, struct block *bp, int version,
                                                         struct Ipifc *ifc, uint8_t * ip, uint8_t * h);
 extern void arprelease(struct arp *, struct arpent *a);
index dc5edbe..77ea8ee 100644 (file)
@@ -768,7 +768,6 @@ void kproc(char *unused_char_p_t, void (*)(void *), void *, int);
 void kprocchild(struct proc *, void (*)(void *), void *);
 void (*kproftick) (uint32_t);
 void ksetenv(char *unused_char_p_t, char *, int);
-//void      kstrncpy( char *unused_char_p_t, char*, int unused_int, sizeof(char*, char*));
 void kstrdup(char **unused_char_pp_t, char *unused_char_p_t);
 
 struct block *mem2bl(uint8_t * unused_uint8_p_t, int);
index 90b90de..94f2fac 100644 (file)
@@ -38,8 +38,7 @@ void block_init(void)
        kref_init(&ram_bd->b_kref, fake_release, 1);
        pm_init(&ram_bd->b_pm, &block_pm_op, ram_bd);
        ram_bd->b_data = _binary_mnt_ext2fs_img_start;
-       strncpy(ram_bd->b_name, "RAMDISK", BDEV_INLINE_NAME);
-       ram_bd->b_name[BDEV_INLINE_NAME - 1] = '\0';
+       strlcpy(ram_bd->b_name, "RAMDISK", BDEV_INLINE_NAME);
        /* Connect it to the file system */
        struct file *ram_bf = make_device("/dev/ramdisk", S_IRUSR | S_IWUSR,
                                          __S_IFBLK, &block_f_op);
index ae7050b..18c4ad9 100644 (file)
@@ -1013,10 +1013,12 @@ static unsigned int ext2_dirent_len(struct ext2_dirent *e2dir)
                return 0;
 }
 
-/* Helper for writing the contents of a dentry to a disk dirent */
+/* Helper for writing the contents of a dentry to a disk dirent. Zeroes the
+ * contents of the dirent so that we don't write random data to disk. */
 static void ext2_write_dirent(struct ext2_dirent *e2dir, struct dentry *dentry,
                               unsigned int rec_len)
 {
+       memset(e2dir, 0, sizeof(*e2dir));
        e2dir->dir_inode = cpu_to_le32(dentry->d_inode->i_ino);
        e2dir->dir_reclen = cpu_to_le16(rec_len);
        e2dir->dir_namelen = dentry->d_name.len;
@@ -1044,7 +1046,8 @@ static void ext2_write_dirent(struct ext2_dirent *e2dir, struct dentry *dentry,
                        e2dir->dir_filetype = EXT2_FT_UNKNOWN;
        }
        assert(dentry->d_name.len <= 255);
-       strncpy((char*)e2dir->dir_name, dentry->d_name.name, dentry->d_name.len);
+       strlcpy((char*)e2dir->dir_name, dentry->d_name.name,
+               sizeof(e2dir->dir_name));
 }
 
 /* Helper for ext2_create().  This tries to squeeze a dirent in the slack space
@@ -1187,8 +1190,7 @@ I_AM_HERE;
        struct inode *inode = dentry->d_inode;
        SET_FTYPE(inode->i_mode, __S_IFLNK);
        inode->i_fop = &ext2_f_op_sym;
-       strncpy(string, symname, len);
-       string[len] = '\0';             /* symname should be \0d anyway, but just in case */
+       strlcpy(string, symname, len + 1);
        #endif
        return 0;
 }
@@ -1344,9 +1346,8 @@ int ext2_readdir(struct file *dir, struct dirent *dirent)
                panic("Something is jacked with the dirent going beyond the dir/file");
        /* note, dir_namelen doesn't include the \0 */
        dirent->d_reclen = e2dir->dir_namelen;
-       strncpy(dirent->d_name, (char*)e2dir->dir_name, e2dir->dir_namelen);
        assert(e2dir->dir_namelen <= MAX_FILENAME_SZ);
-       dirent->d_name[e2dir->dir_namelen] = '\0';
+       strlcpy(dirent->d_name, (char*)e2dir->dir_name, e2dir->dir_namelen + 1);
        ext2_put_metablock(dir->f_dentry->d_sb, blk_buf);
        
        /* At the end of the directory, sort of.  ext2 often preallocates blocks, so
index 982fca5..83233ad 100644 (file)
@@ -36,8 +36,7 @@ char *get_fn_name(uintptr_t pc)
        buf = kmalloc(name_len, 0);
        if (!buf)
                return 0;
-       strncpy(buf, found->name, name_len);
-       buf[name_len] = 0;
+       strlcpy(buf, found->name, name_len);
        return buf;
 }
 
index 9dbd66a..2bee781 100644 (file)
@@ -392,8 +392,7 @@ int kfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
        kfs_init_inode(dir, dentry);
        SET_FTYPE(inode->i_mode, __S_IFLNK);
        inode->i_fop = &kfs_f_op_sym;
-       strncpy(string, symname, len);
-       string[len] = '\0';             /* symname should be \0d anyway, but just in case */
+       strlcpy(string, symname, len + 1);
        k_i_info->filestart = string;   /* reusing this void* to hold the char* */
        return 0;
 }
@@ -584,9 +583,14 @@ int kfs_readdir(struct file *dir, struct dirent *dirent)
                        dirent->d_ino = subent->d_inode->i_ino;
                        dirent->d_off = count;
                        dirent->d_reclen = subent->d_name.len;
-                       /* d_name.name is null terminated, the byte after d_name.len */
-                       assert(subent->d_name.len <= MAX_FILENAME_SZ);
-                       strncpy(dirent->d_name, subent->d_name.name, subent->d_name.len +1);
+                       /* d_name.name is null terminated, the byte after d_name.len.
+                        * Regardless, exercise caution as we copy into d_name, should
+                        * the size of the quickstring buffer and the size of d_name
+                        * fall out of sync with one another. */
+                       assert(subent->d_name.len < sizeof(dirent->d_name));
+                       strncpy(dirent->d_name, subent->d_name.name,
+                               sizeof(dirent->d_name) - 1);
+                       dirent->d_name[sizeof(dirent->d_name) - 1] = '\0';
                        found = TRUE;
                }
        }
@@ -596,13 +600,13 @@ int kfs_readdir(struct file *dir, struct dirent *dirent)
                dirent->d_ino = dir_d->d_inode->i_ino;
                dirent->d_off = 1;
                dirent->d_reclen = 1;
-               strncpy(dirent->d_name, ".", 2);        /* the extra is for the null term */
+               strlcpy(dirent->d_name, ".", sizeof(dirent->d_name));
                found = TRUE;
        } else if (desired_file == 1) {
                dirent->d_ino = dir_d->d_parent->d_inode->i_ino;
                dirent->d_off = 2;
                dirent->d_reclen = 2;
-               strncpy(dirent->d_name, "..", 3);       /* the extra is for the null term */
+               strlcpy(dirent->d_name, "..", sizeof(dirent->d_name));
                found = TRUE;
        }
        /* need to check the sub-dirs as well as the sub-"files".  The main
@@ -813,7 +817,7 @@ static int __add_kfs_entry(struct dentry *parent, char *path,
                 * anything like that. */
                dirname_sz = first_slash - path;
                assert(dirname_sz <= MAX_FILENAME_SZ);
-               strncpy(dir, path, dirname_sz);
+               memmove(dir, path, dirname_sz);
                dir[dirname_sz] = '\0';
                printd("Finding DIR %s in dentry %s (start: %p, size %d)\n", dir,
                       parent->d_name.name, c_bhdr->c_filestart, c_bhdr->c_filesize);
index 3283d8b..6932b1a 100644 (file)
@@ -304,8 +304,13 @@ int mon_bin_run(int argc, char **argv, struct hw_trapframe *hw_tf)
        }
        struct file *program;
        int retval = 0;
-       char buf[6 + MAX_FILENAME_SZ] = "/bin/";        /* /bin/ + max + \0 */
-       strncpy(buf + 5, argv[1], MAX_FILENAME_SZ);
+       char buf[5 + MAX_FILENAME_SZ + 1] = "/bin/";    /* /bin/ + max + \0 */
+
+       strlcpy(buf, "/bin/", sizeof(buf));
+       if (strlcat(buf, argv[1], sizeof(buf)) > sizeof(buf)) {
+               printk("Filename '%s' too long!\n", argv[1]);
+               return 1;
+       }
        program = do_file_open(buf, O_READ, 0);
        if (!program) {
                printk("No such program!\n");
index 4c1072b..384e7f4 100644 (file)
@@ -435,7 +435,7 @@ arpenter(struct Fs *fs, int version, uint8_t * ip, uint8_t * mac, int n,
        qunlock(&arp->qlock);
 }
 
-int arpwrite(struct Fs *fs, char *s, int len)
+int arpwrite(struct Fs *fs, char *s, long len)
 {
        int n;
        struct route *r;
@@ -448,14 +448,13 @@ int arpwrite(struct Fs *fs, char *s, int len)
 
        arp = fs->arp;
 
-       if (len == 0)
+       if (len <= 0)
                error(EINVAL, NULL);
-       if (len >= sizeof(buf))
-               len = sizeof(buf) - 1;
-       strncpy(buf, s, len);
-       buf[len] = 0;
-       if (len > 0 && buf[len - 1] == '\n')
-               buf[len - 1] = 0;
+       if (len > sizeof(buf))
+               len = sizeof(buf);
+       strlcpy(buf, s, sizeof(buf));
+       if (len > 0 && buf[len - 2] == '\n')
+               buf[len - 2] = 0;
 
        n = getfields(buf, f, 4, 1, " ");
        if (strcmp(f[0], "flush") == 0) {
@@ -473,7 +472,7 @@ int arpwrite(struct Fs *fs, char *s, int len)
                        }
                }
                memset(arp->hash, 0, sizeof(arp->hash));
-// clear all pkts on these lists (rxmt, dropf/l)
+               // clear all pkts on these lists (rxmt, dropf/l)
                arp->rxmt = NULL;
                arp->dropf = NULL;
                arp->dropl = NULL;
index 3a73943..b95c0ba 100644 (file)
@@ -1573,10 +1573,9 @@ retry:
 int Fsconnected(struct conv *c, char *msg)
 {
        if (msg != NULL && *msg != '\0')
-               strncpy(c->cerr, msg, sizeof(c->cerr));
+               strlcpy(c->cerr, msg, sizeof(c->cerr));
 
        switch (c->state) {
-
                case Announcing:
                        c->state = Announced;
                        break;
index 4c6be09..b7da019 100644 (file)
@@ -64,7 +64,7 @@ struct DS {
 /* only used here for now. */
 static void kerrstr(void *err, int len)
 {
-       strncpy(err, current_errstr(), len);
+       strlcpy(err, current_errstr(), len);
 }
 
 /*
@@ -95,7 +95,7 @@ int kdial(char *dest, char *local, char *dir, int *cfdp)
                goto out;
 
        err[0] = 0;
-       strncpy(err, current_errstr(), ERRMAX);
+       strlcpy(err, current_errstr(), ERRMAX);
        if (strstr(err, "refused") != 0) {
                goto out;
        }
@@ -155,7 +155,7 @@ static int csdial(DS * ds)
         *  we get one that works.
         */
        *besterr = 0;
-       strncpy(err, errno_to_string(ECONNRESET), ERRMAX);
+       strlcpy(err, errno_to_string(ECONNRESET), ERRMAX);
        sysseek(fd, 0, 0);
        while ((n = sysread(fd, buf, Maxstring - 1)) > 0) {
                buf[n] = 0;
@@ -264,8 +264,7 @@ static void _dial_string_parse(char *str, DS * ds)
 {
        char *p, *p2;
 
-       strncpy(ds->buf, str, Maxstring);
-       ds->buf[Maxstring - 1] = 0;
+       strlcpy(ds->buf, str, Maxstring);
 
        p = strchr(ds->buf, '!');
        if (p == 0) {
@@ -290,7 +289,7 @@ static void _dial_string_parse(char *str, DS * ds)
 /*
  *  announce a network service.
  */
-int kannounce(char *addr, char *dir)
+int kannounce(char *addr, char *dir, size_t dirlen)
 {
        int ctl, n, m;
        char buf[NETPATHLEN];
@@ -338,17 +337,17 @@ int kannounce(char *addr, char *dir)
         *  return directory etc.
         */
        if (dir)
-               strncpy(dir, buf, sizeof(dir));
+               strlcpy(dir, buf, dirlen);
        return ctl;
 }
 
 /*
  *  listen for an incoming call
  */
-int klisten(char *dir, char *newdir)
+int klisten(char *dir, char *newdir, size_t newdirlen)
 {
        int ctl, n, m;
-       char buf[NETPATHLEN];
+       char buf[NETPATHLEN + 1];
        char *cp;
 
        /*
@@ -362,7 +361,7 @@ int klisten(char *dir, char *newdir)
        /*
         *  find out which line we have
         */
-       strncpy(buf, dir, sizeof(buf));
+       strlcpy(buf, dir, sizeof(buf));
        cp = strrchr(buf, '/');
        *++cp = 0;
        n = cp - buf;
@@ -377,7 +376,7 @@ int klisten(char *dir, char *newdir)
         *  return directory etc.
         */
        if (newdir)
-               strncpy(newdir, buf, sizeof(newdir));
+               strlcpy(newdir, buf, newdirlen);
        return ctl;
 
 }
@@ -392,15 +391,13 @@ identtrans(char *netdir, char *addr, char *naddr, int na, char *file, int nf)
        char *p;
 
        /* parse the protocol */
-       strncpy(proto, addr, sizeof(proto));
-       proto[sizeof(proto) - 1] = 0;
+       strlcpy(proto, addr, sizeof(proto));
        p = strchr(proto, '!');
        if (p)
                *p++ = 0;
 
        snprintf(file, nf, "%s/%s/clone", netdir, proto);
-       strncpy(naddr, p, na);
-       naddr[na - 1] = 0;
+       strlcpy(naddr, p, na);
 
        return 1;
 }
@@ -425,7 +422,7 @@ static int nettrans(char *addr, char *naddr, int na, char *file, int nf)
                return -1;
        }
        if (*addr != '/') {
-               strncpy(netdir, "/net", sizeof(netdir));
+               strlcpy(netdir, "/net", sizeof(netdir));
        } else {
                for (p2 = p; *p2 != '/'; p2--) ;
                i = p2 - addr;
@@ -433,8 +430,7 @@ static int nettrans(char *addr, char *naddr, int na, char *file, int nf)
                        set_errstr("bad dial string: %s", addr);
                        return -1;
                }
-               strncpy(netdir, addr, i);
-               netdir[i] = 0;
+               strlcpy(netdir, addr, i + 1);
                addr = p2 + 1;
        }
 
@@ -463,9 +459,7 @@ static int nettrans(char *addr, char *naddr, int na, char *file, int nf)
        if (p == 0)
                return -1;
        *p++ = 0;
-       strncpy(naddr, p, na);
-       naddr[na - 1] = 0;
-       strncpy(file, buf, nf);
-       file[nf - 1] = 0;
+       strlcpy(naddr, p, na);
+       strlcpy(file, buf, nf);
        return 0;
 }
index 8f69ee3..4a13e2c 100644 (file)
@@ -162,10 +162,9 @@ static char *ipifcbind(struct conv *c, char **argv, int argc)
 
        /* set the bound device name */
        if (argc > 2)
-               strncpy(ifc->dev, argv[2], sizeof(ifc->dev));
+               strlcpy(ifc->dev, argv[2], sizeof(ifc->dev));
        else
-               snprintf(ifc->dev, sizeof ifc->dev, "%s%d", m->name, c->x);
-       ifc->dev[sizeof(ifc->dev) - 1] = 0;
+               snprintf(ifc->dev, sizeof(ifc->dev), "%s%d", m->name, c->x);
 
        /* set up parameters */
        ifc->m = m;
index 253ad0f..a30191d 100644 (file)
@@ -1,6 +1,6 @@
 extern int kclose(int);
 extern int kdial(char *, char *, char *, int *);
-extern int kannounce(char *, char *);
+extern int kannounce(char *, char *, size_t);
 extern void kerrstr(char *);
 extern void kgerrstr(char *);
 extern int kopen(char *, int);
index 4557884..9d71dad 100644 (file)
@@ -53,8 +53,7 @@ static int parseaddr(uint8_t * unused_uint8_p_t, char *unused_char_p_t, int);
 void netifinit(struct ether *nif, char *name, int nfile, uint32_t limit)
 {
        qlock_init(&nif->qlock);
-       strncpy(nif->name, name, KNAMELEN - 1);
-       nif->name[KNAMELEN - 1] = 0;
+       strlcpy(nif->name, name, KNAMELEN);
        nif->nfile = nfile;
        nif->f = kzmalloc(nfile * sizeof(struct netfile *), 0);
        if (nif->f)
@@ -91,7 +90,7 @@ netifgen(struct chan *c, char *unused_char_p_t, struct dirtab *vp,
                        case 0:
                                q.path = N2ndqid;
                                q.type = QTDIR;
-                               strncpy(get_cur_genbuf(), nif->name, GENBUF_SZ);
+                               strlcpy(get_cur_genbuf(), nif->name, GENBUF_SZ);
                                devdir(c, q, get_cur_genbuf(), 0, eve, 0555, dp);
                                break;
                        default:
@@ -188,7 +187,7 @@ netifgen(struct chan *c, char *unused_char_p_t, struct dirtab *vp,
                case DEVDOTDOT:
                        q.type = QTDIR;
                        q.path = N2ndqid;
-                       strncpy(get_cur_genbuf(), nif->name, GENBUF_SZ);
+                       strlcpy(get_cur_genbuf(), nif->name, GENBUF_SZ);
                        devdir(c, q, get_cur_genbuf(), 0, eve, DMDIR | 0555, dp);
                        break;
                case 0:
@@ -465,7 +464,7 @@ int netifwstat(struct ether *nif, struct chan *c, uint8_t * db, int n)
                error(ENODATA, NULL);
        }
        if (!emptystr(dir[0].uid))
-               strncpy(f->owner, dir[0].uid, KNAMELEN);
+               strlcpy(f->owner, dir[0].uid, KNAMELEN);
        if (dir[0].mode != ~0UL)
                f->mode = dir[0].mode;
        kfree(dir);
@@ -558,7 +557,7 @@ static int netown(struct netfile *p, char *o, int omode)
                        return -1;
                }
        }
-       strncpy(p->owner, o, KNAMELEN);
+       strlcpy(p->owner, o, KNAMELEN);
        p->mode = 0660;
        spin_unlock(&netlock);
        return 0;
index 0f86846..918f289 100644 (file)
@@ -1011,7 +1011,7 @@ static struct chan *__namec_from(struct chan *c, char *aname, int amode,
                kfree(e.name);
                kfree(e.elems);
                kfree(e.off);
-//dumpmount();
+               //dumpmount();
                nexterror();
        }
 
@@ -1027,7 +1027,7 @@ static struct chan *__namec_from(struct chan *c, char *aname, int amode,
                /* perm must have DMDIR if last element is / or /. */
                if (e.mustbedir && !(perm & DMDIR)) {
                        npath = e.ARRAY_SIZEs;
-                       strncpy(tmperrbuf, "create without DMDIR", sizeof(tmperrbuf));
+                       strlcpy(tmperrbuf, "create without DMDIR", sizeof(tmperrbuf));
                        goto NameError;
                }
 
@@ -1052,7 +1052,7 @@ NameError:
                /* brho: skipping the namec custom error string business, since it hides
                 * the underlying failure.  implement this if you want the old stuff. */
 #if 0
-               strncpy(tmperrbuf, current->errstr, sizeof(tmperrbuf));
+               strlcpy(tmperrbuf, current->errstr, sizeof(tmperrbuf));
                len = prefix + e.off[npath]; // prefix was name - aname, the start pt
                if (len < ERRMAX / 3 || (name = memrchr(aname, '/', len)) == NULL
                        || name == aname)
@@ -1068,7 +1068,7 @@ NameError:
 
        if (e.mustbedir && !(c->qid.type & QTDIR)) {
                npath = e.ARRAY_SIZEs;
-               strncpy(tmperrbuf, "not a directory", sizeof(tmperrbuf));
+               strlcpy(tmperrbuf, "not a directory", sizeof(tmperrbuf));
                goto NameError;
        }
 
@@ -1272,7 +1272,7 @@ Open:
                        poperror();     /* matching the if(!waserror) */
 
                        /* save error, so walk doesn't clobber our existing errstr */
-                       strncpy(tmperrbuf, current_errstr(), MAX_ERRSTR_LEN);
+                       strlcpy(tmperrbuf, current_errstr(), sizeof(tmperrbuf));
                        saved_errno = get_errno();
                        /* note: we depend that walk does not error */
                        if (walk(&c, e.elems + e.ARRAY_SIZEs - 1, 1, can_mount, NULL) < 0) {
@@ -1280,7 +1280,7 @@ Open:
                                /* Report the error we had originally */
                                error(EFAIL, tmperrbuf);
                        }
-                       strncpy(current_errstr(), tmperrbuf, MAX_ERRSTR_LEN);
+                       strlcpy(current_errstr(), tmperrbuf, MAX_ERRSTR_LEN);
                        omode |= O_TRUNC;
                        goto Open;
 
@@ -1291,9 +1291,9 @@ Open:
        poperror();
 
        if (e.ARRAY_SIZEs > 0)
-               strncpy(get_cur_genbuf(), e.elems[e.ARRAY_SIZEs - 1], GENBUF_SZ);
+               strlcpy(get_cur_genbuf(), e.elems[e.ARRAY_SIZEs - 1], GENBUF_SZ);
        else
-               strncpy(get_cur_genbuf(), ".", GENBUF_SZ);
+               strlcpy(get_cur_genbuf(), ".", GENBUF_SZ);
 
        kfree(e.name);
        kfree(e.elems);
index ecf51ed..2fa9880 100644 (file)
@@ -117,7 +117,7 @@ void cmderror(struct cmdbuf *cb, char *s)
                        p = seprintf(p, e, " ");
                p = seprintf(p, e, "%s", cb->f[i]);
        }
-       strncpy(p, "\"", sizeof(p));
+       seprintf(p, e, "\"");
        error(EFAIL, get_cur_genbuf());
 }
 
index 05e6751..88f7b2d 100644 (file)
@@ -1890,7 +1890,7 @@ void qclose(struct queue *q)
        spin_lock_irqsave(&q->lock);
        q->state |= Qclosed;
        q->state &= ~(Qflow | Qstarve | Qdropoverflow | Qnonblock);
-       strncpy(q->err, errno_to_string(ECONNABORTED), sizeof(q->err));
+       strlcpy(q->err, errno_to_string(ECONNABORTED), sizeof(q->err));
        bfirst = q->bfirst;
        q->bfirst = 0;
        q->len = 0;
@@ -1916,9 +1916,9 @@ void qhangup(struct queue *q, char *msg)
        spin_lock_irqsave(&q->lock);
        q->state |= Qclosed;
        if (msg == 0 || *msg == 0)
-               strncpy(q->err, errno_to_string(ECONNABORTED), sizeof(q->err));
+               strlcpy(q->err, errno_to_string(ECONNABORTED), sizeof(q->err));
        else
-               strncpy(q->err, msg, ERRMAX - 1);
+               strlcpy(q->err, msg, ERRMAX);
        spin_unlock_irqsave(&q->lock);
 
        /* wake up readers/writers */
index 7640941..317968a 100644 (file)
@@ -257,9 +257,8 @@ void proc_set_progname(struct proc *p, char *name)
                name = DEFAULT_PROGNAME;
 
        /* might have an issue if a dentry name isn't null terminated, and we'd get
-        * extra junk up to progname_sz. */
-       strncpy(p->progname, name, PROC_PROGNAME_SZ);
-       p->progname[PROC_PROGNAME_SZ - 1] = '\0';
+        * extra junk up to progname_sz. Or crash. */
+       strlcpy(p->progname, name, PROC_PROGNAME_SZ);
 }
 
 /* Be sure you init'd the vcore lists before calling this. */
index bcab6a4..feb2f2f 100644 (file)
@@ -631,14 +631,12 @@ static void dentry_set_name(struct dentry *dentry, char *name)
        size_t name_len = strnlen(name, MAX_FILENAME_SZ);       /* not including \0! */
        char *l_name = 0;
        if (name_len < DNAME_INLINE_LEN) {
-               strncpy(dentry->d_iname, name, name_len);
-               dentry->d_iname[name_len] = '\0';
+               strlcpy(dentry->d_iname, name, name_len + 1);
                qstr_builder(dentry, 0);
        } else {
                l_name = kmalloc(name_len + 1, 0);
                assert(l_name);
-               strncpy(l_name, name, name_len);
-               l_name[name_len] = '\0';
+               strlcpy(l_name, name, name_len + 1);
                qstr_builder(dentry, l_name);
        }
 }
@@ -2740,7 +2738,7 @@ char *do_getcwd(struct fs_struct *fs_env, char **kfree_this, size_t cwd_l)
                        return 0;
                }
                path_start -= link_len;
-               strncpy(path_start, dentry->d_name.name, link_len);
+               memmove(path_start, dentry->d_name.name, link_len);
                path_start--;
                *path_start = '/';
                dentry = dentry->d_parent;