From 890f4784c1483bbf9d4fbc83d9dd210b5b93d43e Mon Sep 17 00:00:00 2001 From: jpeeler Date: Fri, 15 Feb 2008 23:33:44 +0000 Subject: Fixes bug 11471. Replaced all instances of strncpy with zap_copy_string (added to zaptel.h) to fix any off by one errors and ensure destination string is NULL terminated. git-svn-id: http://svn.digium.com/svn/zaptel/branches/1.2@3833 5390a7c7-147a-4af0-8ec9-7488f05a26cb --- fxotune.c | 2 +- jpah.h | 2 +- ppp/zaptel.c | 2 +- sethdlc-new.c | 2 +- sethdlc.c | 2 +- tonezone.c | 2 +- tor2ee.c | 4 ++-- wct4xxp/wct4xxp-diag.c | 2 +- zaptel-base.c | 12 ++++++------ zaptel.h | 26 ++++++++++++++++++++++++++ ztcfg-dude.c | 8 ++++---- ztcfg.c | 10 +++++----- ztd-eth.c | 4 ++-- ztdynamic.c | 4 ++-- ztmonitor.c | 4 ++-- zttranscode.c | 2 +- 16 files changed, 57 insertions(+), 31 deletions(-) diff --git a/fxotune.c b/fxotune.c index ea4467e..a5e64d3 100644 --- a/fxotune.c +++ b/fxotune.c @@ -167,7 +167,7 @@ static int ensure_silence(struct silence_info *info) memset(&dop, 0, sizeof(dop)); dop.op = ZT_DIAL_OP_REPLACE; dop.dialstr[0] = 'T'; - strncpy(dop.dialstr + 1, info->dialstr, sizeof(dop.dialstr) - 1); + zap_copy_string(dop.dialstr + 1, info->dialstr, sizeof(dop.dialstr)); if (ioctl(info->device, ZT_DIAL, &dop)) { fprintf(stderr, "Unable to dial!\n"); diff --git a/jpah.h b/jpah.h index f72c5fa..fb661ed 100644 --- a/jpah.h +++ b/jpah.h @@ -49,7 +49,7 @@ static void echo_can_init(void) static void echo_can_identify(char *buf, size_t len) { - strncpy(buf, "JP1", len); + zap_copy_string(buf, "JP1", len); } static void echo_can_shutdown(void) diff --git a/ppp/zaptel.c b/ppp/zaptel.c index d231794..121bfec 100644 --- a/ppp/zaptel.c +++ b/ppp/zaptel.c @@ -223,7 +223,7 @@ int setdevname_zaptel(const char *cp) } } - strncpy(devnam, cp, sizeof(devnam) - 1); + zap_copy_string(devnam, cp, sizeof(devnam)); info("Using zaptel device '%s'\n", devnam); diff --git a/sethdlc-new.c b/sethdlc-new.c index 1765c32..376a3f4 100644 --- a/sethdlc-new.c +++ b/sethdlc-new.c @@ -673,7 +673,7 @@ int main(int arg_c, char *arg_v[]) if (sock < 0) error("Unable to create socket: %s\n", strerror(errno)); - strncpy(req.ifr_name, argv[1], sizeof(req.ifr_name) - 1); /* Device name */ + zap_copy_string(req.ifr_name, argv[1], sizeof(req.ifr_name)); /* Device name */ if (argc == 2) show_port(); diff --git a/sethdlc.c b/sethdlc.c index afbcb20..bf1238d 100644 --- a/sethdlc.c +++ b/sethdlc.c @@ -293,7 +293,7 @@ int main(int argc, char *argv[]) if (sock<0) error("Unable to create socket: %s\n", strerror(errno)); - strncpy(req.ifr_name, argv[1], sizeof(req.ifr_name) - 1); /* Device name */ + zap_copy_string(req.ifr_name, argv[1], sizeof(req.ifr_name)); /* Device name */ if (argc == 2) { show_port(sock); diff --git a/tonezone.c b/tonezone.c index deb1ac1..d38221b 100644 --- a/tonezone.c +++ b/tonezone.c @@ -274,7 +274,7 @@ int tone_zone_register_zone(int fd, struct tone_zone *z) } h->count = count; h->zone = z->zone; - strncpy(h->name, z->description, sizeof(h->name)); + zap_copy_string(h->name, z->description, sizeof(h->name)); x = z->zone; ioctl(fd, ZT_FREEZONE, &x); res = ioctl(fd, ZT_LOADZONE, h); diff --git a/tor2ee.c b/tor2ee.c index dc671cb..575e0ef 100644 --- a/tor2ee.c +++ b/tor2ee.c @@ -779,7 +779,7 @@ static int write_eeprom_file(char *filename, char *revision, struct pci_eeprom * /* Store revision number */ memset(ee->revision, 0, sizeof(ee->revision)); - strncpy(ee->revision, revision, sizeof(ee->revision)); + zap_copy_string(ee->revision, revision, sizeof(ee->revision)); /* Calculate FCS on revision and data */ ee->crc16 = htons(calc_crc16((char *)ee, sizeof(*ee) - 2)); @@ -1051,7 +1051,7 @@ int main(int argc, char *argv[]) exit(1); } modify(&ee, reg, val); - strncpy(tmp, ee.revision, sizeof(tmp)); + zap_copy_string(tmp, ee.revision, sizeof(tmp)); if (write_eeprom_file(writefile, tmp, &ee)) { fprintf(stderr, "Unable to write EEPROM file\n"); closemem(); diff --git a/wct4xxp/wct4xxp-diag.c b/wct4xxp/wct4xxp-diag.c index 50a328d..8c14611 100644 --- a/wct4xxp/wct4xxp-diag.c +++ b/wct4xxp/wct4xxp-diag.c @@ -378,7 +378,7 @@ int main(int argc, char *argv[]) exit(1); } if (*(argv[1]) == '/') - strncpy(fn, argv[1], sizeof(fn) - 1); + zap_copy_string(fn, argv[1], sizeof(fn)); else snprintf(fn, sizeof(fn), "/dev/zap/%d", atoi(argv[1])); fd = open(fn, O_RDWR); diff --git a/zaptel-base.c b/zaptel-base.c index 94843b9..1d44752 100644 --- a/zaptel-base.c +++ b/zaptel-base.c @@ -1212,7 +1212,7 @@ static devfs_handle_t register_devfs_channel(struct zt_chan *chan, devfs_handle_ /* Set up the path of the file/link itself */ tmp_offset = devfs_generate_path(zaptel_devfs_dir, tmp, sizeof(tmp) - 1); sprintf(buf, "/%d", chan->channo); - strncpy(path, tmp+tmp_offset, sizeof(path) - 1); + zap_copy_string(path, tmp+tmp_offset, sizeof(path)); strncat(path, buf, sizeof(path) - 1); err = devfs_mk_symlink(NULL, path, DEVFS_FL_DEFAULT, link+link_offset, &chan->fhandle_symlink, NULL); @@ -2514,7 +2514,7 @@ ioctl_load_zone(unsigned long data) memset(slab, 0, size); /* Grab the zone */ z = (struct zt_zone *)slab; - strncpy(z->name, th.name, sizeof(z->name) - 1); + zap_copy_string(z->name, th.name, sizeof(z->name)); for (x=0;xringcadence[x] = th.ringcadence[x]; data += sizeof(struct zt_tone_def_header); @@ -2928,7 +2928,7 @@ static int zt_common_ioctl(struct inode *node, struct file *file, unsigned int c stack.param.pulseaftertime = chan->pulseaftertime; if (chan->span) stack.param.spanno = chan->span->spanno; else stack.param.spanno = 0; - strncpy(stack.param.name, chan->name, sizeof(stack.param.name) - 1); + zap_copy_string(stack.param.name, chan->name, sizeof(stack.param.name)); stack.param.chanpos = chan->chanpos; /* Return current law */ if (chan->xlaw == __zt_alaw) @@ -3037,8 +3037,8 @@ static int zt_common_ioctl(struct inode *node, struct file *file, unsigned int c stack.span.spanno = i; /* put the span # in here */ stack.span.totalspans = 0; if (maxspans) stack.span.totalspans = maxspans - 1; /* put total number of spans here */ - strncpy(stack.span.desc, spans[i]->desc, sizeof(stack.span.desc) - 1); - strncpy(stack.span.name, spans[i]->name, sizeof(stack.span.name) - 1); + zap_copy_string(stack.span.desc, spans[i]->desc, sizeof(stack.span.desc)); + zap_copy_string(stack.span.name, spans[i]->name, sizeof(stack.span.name)); stack.span.alarms = spans[i]->alarms; /* get alarm status */ stack.span.bpvcount = spans[i]->bpvcount; /* get BPV count */ stack.span.rxlevel = spans[i]->rxlevel; /* get rx level */ @@ -3577,7 +3577,7 @@ static int zt_chanandpseudo_ioctl(struct inode *inode, struct file *file, unsign rv = -EBUSY; break; } - strncpy(chan->txdialbuf + strlen(chan->txdialbuf), stack.tdo.dialstr, ZT_MAX_DTMF_BUF - strlen(chan->txdialbuf)); + zap_copy_string(chan->txdialbuf + strlen(chan->txdialbuf), stack.tdo.dialstr, ZT_MAX_DTMF_BUF - strlen(chan->txdialbuf)); if (!chan->dialing) { chan->dialing = 1; diff --git a/zaptel.h b/zaptel.h index da5f481..c27685e 100644 --- a/zaptel.h +++ b/zaptel.h @@ -1733,4 +1733,30 @@ struct zt_radio_param { /*! Maximum audio mask */ #define ZT_FORMAT_AUDIO_MASK ((1 << 16) - 1) +/*! + \brief Size-limited null-terminating string copy. + \param dst The destination buffer + \param src The source string + \param size The size of the destination buffer + \return Nothing. + + This is similar to \a strncpy, with two important differences: + - the destination buffer will \b always be null-terminated + - the destination buffer is not filled with zeros past the copied string length + These differences make it slightly more efficient, and safer to use since it will + not leave the destination buffer unterminated. There is no need to pass an artificially + reduced buffer size to this function (unlike \a strncpy), and the buffer does not need + to be initialized to zeroes prior to calling this function. +*/ +static inline void zap_copy_string(char *dst, const char *src, unsigned int size) +{ + while (*src && size) { + *dst++ = *src++; + size--; + } + if (__builtin_expect(!size, 0)) + dst--; + *dst = '\0'; +} + #endif /* _LINUX_ZAPTEL_H */ diff --git a/ztcfg-dude.c b/ztcfg-dude.c index 50e18d7..4764f65 100644 --- a/ztcfg-dude.c +++ b/ztcfg-dude.c @@ -182,8 +182,8 @@ int dspanconfig(char *keyword, char *args) } - strncpy(zds[numdynamic].driver, realargs[0], sizeof(zds[numdynamic].driver)); - strncpy(zds[numdynamic].addr, realargs[1], sizeof(zds[numdynamic].addr)); + zap_copy_string(zds[numdynamic].driver, realargs[0], sizeof(zds[numdynamic].driver)); + zap_copy_string(zds[numdynamic].addr, realargs[1], sizeof(zds[numdynamic].addr)); zds[numdynamic].numchans = chans; zds[numdynamic].timing = timing; @@ -291,7 +291,7 @@ int apply_channels(int chans[], char *argstr) for (x=0;x-.\n", args[x]); @@ -566,7 +566,7 @@ static int registerzone(char *keyword, char *args) error("Too many tone zones specified\n"); return 0; } - strncpy(zonestoload[numzones++], args, sizeof(zonestoload[0])); + zap_copy_string(zonestoload[numzones++], args, sizeof(zonestoload[0])); return 0; } diff --git a/ztcfg.c b/ztcfg.c index e251f2a..d27162c 100644 --- a/ztcfg.c +++ b/ztcfg.c @@ -256,8 +256,8 @@ int dspanconfig(char *keyword, char *args) } - strncpy(zds[numdynamic].driver, realargs[0], sizeof(zds[numdynamic].driver)); - strncpy(zds[numdynamic].addr, realargs[1], sizeof(zds[numdynamic].addr)); + zap_copy_string(zds[numdynamic].driver, realargs[0], sizeof(zds[numdynamic].driver)); + zap_copy_string(zds[numdynamic].addr, realargs[1], sizeof(zds[numdynamic].addr)); zds[numdynamic].numchans = chans; zds[numdynamic].timing = timing; @@ -365,7 +365,7 @@ int apply_channels(int chans[], char *argstr) for (x=0;x-.\n", args[x]); @@ -612,7 +612,7 @@ static int registerzone(char *keyword, char *args) error("Too many tone zones specified\n"); return 0; } - strncpy(zonestoload[numzones++], args, sizeof(zonestoload[0])); + zap_copy_string(zonestoload[numzones++], args, sizeof(zonestoload[0])); return 0; } @@ -868,7 +868,7 @@ int rad_apply_channels(int chans[], char *argstr) for (x=0;x-.\n", args[x]); diff --git a/ztd-eth.c b/ztd-eth.c index a5d8f83..72aab86 100644 --- a/ztd-eth.c +++ b/ztd-eth.c @@ -297,12 +297,12 @@ static void *ztdeth_create(struct zt_span *span, char *addr) memset(z, 0, sizeof(struct ztdeth)); /* Address should be /[/subaddr] */ - strncpy(tmp, addr, sizeof(tmp) - 1); + zap_copy_string(tmp, addr, sizeof(tmp)); tmp2 = strchr(tmp, '/'); if (tmp2) { *tmp2 = '\0'; tmp2++; - strncpy(z->ethdev, tmp, sizeof(z->ethdev) - 1); + zap_copy_string(z->ethdev, tmp, sizeof(z->ethdev)); } else { printk("Invalid TDMoE address (no device) '%s'\n", addr); kfree(z); diff --git a/ztdynamic.c b/ztdynamic.c index e8623cc..8341af5 100644 --- a/ztdynamic.c +++ b/ztdynamic.c @@ -579,8 +579,8 @@ static int create_dynamic(ZT_DYNAMIC_SPAN *zds) memset(z->msgbuf, 0, bufsize); /* Setup parameters properly assuming we're going to be okay. */ - strncpy(z->dname, zds->driver, sizeof(z->dname) - 1); - strncpy(z->addr, zds->addr, sizeof(z->addr) - 1); + zap_copy_string(z->dname, zds->driver, sizeof(z->dname)); + zap_copy_string(z->addr, zds->addr, sizeof(z->addr)); z->timing = zds->timing; sprintf(z->span.name, "ZTD/%s/%s", zds->driver, zds->addr); sprintf(z->span.desc, "Dynamic '%s' span at '%s'", zds->driver, zds->addr); diff --git a/ztmonitor.c b/ztmonitor.c index f3f2a87..adfd6bb 100644 --- a/ztmonitor.c +++ b/ztmonitor.c @@ -155,10 +155,10 @@ void draw_barheader() memset(bar+barlen+2, '>', 1); memset(bar+barlen+3, '\0', 1); - strncpy(bar+(barlen/2), "(RX)", 4); + zap_copy_string(bar+(barlen/2), "(RX)", 4); printf("%s", bar); - strncpy(bar+(barlen/2), "(TX)", 4); + zap_copy_string(bar+(barlen/2), "(TX)", 4); printf(" %s\n", bar); } diff --git a/zttranscode.c b/zttranscode.c index a550969..427c2f9 100644 --- a/zttranscode.c +++ b/zttranscode.c @@ -311,7 +311,7 @@ static int zt_tc_getinfo(unsigned long data) if (!tc) return -ENOSYS; - strncpy(info.name, tc->name, sizeof(info.name) - 1); + zap_copy_string(info.name, tc->name, sizeof(info.name)); info.numchannels = tc->numchannels; info.srcfmts = tc->srcfmts; info.dstfmts = tc->dstfmts; -- cgit v1.2.3