afs: Replace strcpy &co by safer alternatives 43/14743/11
authorMarcio Barbosa <mbarbosa@sinenomine.net>
Wed, 6 Apr 2022 20:59:56 +0000 (20:59 +0000)
committerBenjamin Kaduk <kaduk@mit.edu>
Fri, 13 May 2022 05:50:08 +0000 (01:50 -0400)
In addition to being unsafe, these functions (strcpy, strncpy, strcat,
and sprintf) are deprecated on macOS. Replace these functions by safer
alternatives (strlcpy, strlcat, snprintf, and afs_strdup).

Notice that, in order to use afs_strdup(), this commit adds the afs_util
library to the AFSPAGOBJS list. Given that afs_strcasecmp() is also
implemented in afs_util.c, src/crypto/hcrypto/kernel/strcasecmp.c can be
removed from the tree.

No functional change should be incurred by this commit.

This commit is a continuation of a patch initially developed by
cwills@sinenomine.net.

Change-Id: Id11d8bca133e44f96913f7959d87bc82dbebce29
Reviewed-on: https://gerrit.openafs.org/14743
Reviewed-by: Andrew Deason <adeason@sinenomine.net>
Reviewed-by: Cheyenne Wills <cwills@sinenomine.net>
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>
Tested-by: BuildBot <buildbot@rampaginggeek.com>

23 files changed:
src/afs/DARWIN/osi_inode.c
src/afs/DARWIN/osi_vfsops.c
src/afs/UKERNEL/afsincludes.h
src/afs/VNOPS/afs_vnop_lookup.c
src/afs/VNOPS/afs_vnop_symlink.c
src/afs/afs_callback.c
src/afs/afs_cell.c
src/afs/afs_daemons.c
src/afs/afs_dynroot.c
src/afs/afs_icl.c
src/afs/afs_init.c
src/afs/afs_mariner.c
src/afs/afs_pag_call.c
src/afs/afs_pag_cred.c
src/afs/afs_pioctl.c
src/afs/afs_volume.c
src/crypto/hcrypto/kernel/libafsdep
src/crypto/hcrypto/kernel/strcasecmp.c [deleted file]
src/dir/dir.c
src/dir/test/Makefile.in
src/libafs/Makefile.common.in
src/rx/rx_kcommon.c
src/rx/rx_packet.c

index 1ee2ef2..1a7ca31 100644 (file)
@@ -38,10 +38,14 @@ getinode(fs, dev, inode, vpp, perror)
     int code;
     vfs_context_t ctx;
     char volfspath[64];
+    size_t len = sizeof(volfspath);
     
     *vpp = 0;
     *perror = 0;
-    sprintf(volfspath, "/.vol/%d/%d", dev, inode);
+    if (snprintf(volfspath, len, "/.vol/%d/%d", dev, inode) >= len) {
+       *perror = BAD_IGET;
+       return ENAMETOOLONG;
+    }
     code = vnode_open(volfspath, O_RDWR, 0, 0, &vp, afs_osi_ctxtp);
     if (code) {
        *perror = BAD_IGET;
index e9b4383..8224892 100644 (file)
@@ -113,7 +113,10 @@ afs_mount(struct mount *mp, char *path, caddr_t data, struct nameidata *ndp, CTX
     memset(mnt_stat->f_mntfromname, 0, MNAMELEN);
 
     if (data == 0) {
-       strcpy(mnt_stat->f_mntfromname, "AFS");
+       if (strlcpy(mnt_stat->f_mntfromname, "AFS", MNAMELEN) >= MNAMELEN) {
+           AFS_GUNLOCK();
+           return ENAMETOOLONG;
+       }
        /* null terminated string "AFS" will fit, just leave it be. */
        vfs_setfsprivate(mp, NULL);
     } else {
@@ -125,7 +128,10 @@ afs_mount(struct mount *mp, char *path, caddr_t data, struct nameidata *ndp, CTX
        memset(volName + size, 0, MNAMELEN - size);
 
        if (volName[0] == 0) {
-           strcpy(mnt_stat->f_mntfromname, "AFS");
+           if (strlcpy(mnt_stat->f_mntfromname, "AFS", MNAMELEN) >= MNAMELEN) {
+               AFS_GUNLOCK();
+               return ENAMETOOLONG;
+           }
            vfs_setfsprivate(mp, &afs_rootFid);
        } else {
            struct cell *localcell = afs_GetPrimaryCell(READ_LOCK);
index 8e9f619..3b8d0ff 100644 (file)
@@ -27,3 +27,4 @@
 #include "afs/afs_stats.h"
 #include "afs/afs_prototypes.h"
 #include "afs/discon.h"
+#include "roken.h"
index 2a84a5d..db9de71 100644 (file)
@@ -484,33 +484,43 @@ afs_ENameOK(char *aname)
 
 static int
 afs_getsysname(struct vrequest *areq, struct vcache *adp,
-              char *bufp, int *num, char **sysnamelist[])
+              char *bufp, size_t bufsize, int *num, char **sysnamelist[])
 {
-    struct unixuser *au;
-    afs_int32 error;
+    struct unixuser *au = NULL;
+    afs_int32 error, code = -1;
+    size_t rlen;
 
     AFS_STATCNT(getsysname);
 
     *sysnamelist = afs_sysnamelist;
 
-    if (!afs_nfsexporter)
-       strcpy(bufp, (*sysnamelist)[0]);
-    else {
+    if (!afs_nfsexporter) {
+       rlen = strlcpy(bufp, (*sysnamelist)[0], bufsize);
+       if (rlen >= bufsize)
+           goto done;
+    } else {
        au = afs_GetUser(areq->uid, adp->f.fid.Cell, READ_LOCK);
        if (au->exporter) {
            error = EXP_SYSNAME(au->exporter, (char *)0, sysnamelist, num, 0);
            if (error) {
-               strcpy(bufp, "@sys");
-               afs_PutUser(au, READ_LOCK);
-               return -1;
+               strlcpy(bufp, "@sys", bufsize);
+               goto done;
            } else {
-               strcpy(bufp, (*sysnamelist)[0]);
+               rlen = strlcpy(bufp, (*sysnamelist)[0], bufsize);
+               if (rlen >= bufsize)
+                   goto done;
            }
-       } else
-           strcpy(bufp, afs_sysname);
-       afs_PutUser(au, READ_LOCK);
+       } else {
+           rlen = strlcpy(bufp, afs_sysname, bufsize);
+           if (rlen >= bufsize)
+               goto done;
+       }
     }
-    return 0;
+    code = 0;
+ done:
+    if (au != NULL)
+       afs_PutUser(au, READ_LOCK);
+    return code;
 }
 
 void
@@ -525,7 +535,8 @@ Check_AtSys(struct vcache *avc, const char *aname,
        state->name_size = MAXSYSNAME;
        state->name = osi_AllocLargeSpace(state->name_size);
        state->index =
-           afs_getsysname(areq, avc, state->name, &num, sysnamelist);
+           afs_getsysname(areq, avc, state->name, state->name_size, &num,
+                          sysnamelist);
     } else {
        state->offset = -1;
        state->name_size = 0;
@@ -539,7 +550,8 @@ Next_AtSys(struct vcache *avc, struct vrequest *areq,
           struct sysname_info *state)
 {
     int num = afs_sysnamecount;
-    char **sysnamelist[MAXNUMSYSNAMES];
+    char **sysnamelist[MAXNUMSYSNAMES], *buf;
+    size_t bsz;
 
     if (state->index == -1)
        return 0;               /* No list */
@@ -553,15 +565,35 @@ Next_AtSys(struct vcache *avc, struct vrequest *areq,
            /*Move to the end of the string */ ;
 
        if ((tname > state->name + 4) && (AFS_EQ_ATSYS(tname - 4))) {
-           state->offset = (tname - 4) - state->name;
-           tname = osi_AllocLargeSpace(AFS_LRALLOCSIZ);
-           strncpy(tname, state->name, state->offset);
-           state->name = tname;
-           state->name_size = AFS_LRALLOCSIZ;
+           int idx;
+           size_t len, bufsize = AFS_LRALLOCSIZ;
+
+           len = (tname - 4) - state->name;
+           if (len >= bufsize) {
+               return 0;
+           }
+
+           tname = osi_AllocLargeSpace(bufsize);
+           /* intentionally truncating state->name */
+           strlcpy(tname, state->name, len + 1);
+
+           buf = tname + len;
+           bsz = bufsize - len;
            num = 0;
-           state->index =
-               afs_getsysname(areq, avc, state->name + state->offset, &num,
-                              sysnamelist);
+           idx = afs_getsysname(areq, avc, buf, bsz, &num, sysnamelist);
+           if (idx == -1) {
+               osi_FreeLargeSpace(tname);
+               return 0;
+           }
+           /*
+            * If we got here, state->name isn't pointing to any dynamically
+            * allocated memory. In other words, state->name_size must be 0.
+            */
+           state->name = tname;
+           state->offset = len;
+           state->name_size = bufsize;
+           state->index = idx;
+
            return 1;
        } else
            return 0;           /* .*@sys doesn't match either */
@@ -586,7 +618,16 @@ Next_AtSys(struct vcache *avc, struct vrequest *areq,
        if (++(state->index) >= num || !(*sysnamelist)[(unsigned int)state->index])
            return 0;           /* end of list */
     }
-    strcpy(state->name + state->offset, (*sysnamelist)[(unsigned int)state->index]);
+    /*
+     * If we got here, state->name was allocated by the AtSys iterator. In other
+     * words, state->name_size must be greater than 0.
+     */
+    buf = state->name + state->offset;
+    bsz = state->name_size - state->offset;
+    if (strlcpy(buf, (*sysnamelist)[(unsigned int)state->index], bsz) >= bsz) {
+       state->index = -1;
+       return 0;
+    }
     return 1;
 }
 
index 6c991fe..a47f18f 100644 (file)
@@ -282,7 +282,7 @@ afs_symlink(OSI_VC_DECL(adp), char *aname, struct vattr *attrs,
     if (!tvc->linkData) {
        tvc->linkData = afs_osi_Alloc(alen);
        osi_Assert(tvc->linkData != NULL);
-       strncpy(tvc->linkData, atargetName, alen - 1);
+       memcpy(tvc->linkData, atargetName, alen - 1);
        tvc->linkData[alen - 1] = 0;
     }
     ReleaseWriteLock(&tvc->lock);
index f94bc02..f87e4eb 100644 (file)
@@ -298,7 +298,7 @@ SRXAFSCB_GetLock(struct rx_call *a_call, afs_int32 a_index,
        code = 1;
     } else if (a_index >= nentries) {
        struct cell *tc = afs_GetCellByIndex(a_index-nentries, 0);
-       strcpy(a_result->name, tc->cellName);
+       strlcpy(a_result->name, tc->cellName, sizeof(a_result->name));
        a_result->lock.waitStates =
            ((struct afs_lock *)&(tc->lock))->wait_states;
        a_result->lock.exclLocked =
@@ -319,7 +319,7 @@ SRXAFSCB_GetLock(struct rx_call *a_call, afs_int32 a_index,
         * Found it - copy out its contents.
         */
        tl = &ltable[a_index];
-       strcpy(a_result->name, tl->name);
+       strlcpy(a_result->name, tl->name, sizeof(a_result->name));
        a_result->lock.waitStates =
            ((struct afs_lock *)(tl->addr))->wait_states;
        a_result->lock.exclLocked =
index f0bdcf6..d7bbcf1 100644 (file)
@@ -143,7 +143,7 @@ afs_AFSDBHandler(char *acellName, int acellNameLen, afs_int32 * kernelMsg)
     }
 
     /* Return the lookup request to userspace */
-    strncpy(acellName, afsdb_req.cellname, acellNameLen);
+    strlcpy(acellName, afsdb_req.cellname, acellNameLen);
     ReleaseReadLock(&afsdb_req_lock);
     return 0;
 }
index 3c22323..f965f45 100644 (file)
@@ -290,12 +290,17 @@ afs_CheckRootVolume(void)
     struct volume *tvp = NULL;
     int usingDynroot = afs_GetDynrootEnable();
     int localcell;
+    size_t bufsize, len;
 
     AFS_STATCNT(afs_CheckRootVolume);
+    bufsize = sizeof(rootVolName);
     if (*afs_rootVolumeName == 0) {
-       strcpy(rootVolName, "root.afs");
+       len = strlcpy(rootVolName, "root.afs", bufsize);
     } else {
-       strcpy(rootVolName, afs_rootVolumeName);
+       len = strlcpy(rootVolName, afs_rootVolumeName, bufsize);
+    }
+    if (len >= bufsize) {
+       return ENAMETOOLONG;
     }
 
     if (usingDynroot) {
@@ -311,11 +316,13 @@ afs_CheckRootVolume(void)
        tvp = afs_GetVolumeByName(rootVolName, localcell, 1, NULL, READ_LOCK);
        if (!tvp) {
            char buf[128];
-           int len = strlen(rootVolName);
 
            if ((len < 9) || strcmp(&rootVolName[len - 9], ".readonly")) {
-               strcpy(buf, rootVolName);
-               afs_strcat(buf, ".readonly");
+               bufsize = sizeof(buf);
+               len = snprintf(buf, bufsize, "%s.readonly", rootVolName);
+               if (len >= bufsize) {
+                   return ENAMETOOLONG;
+               }
                tvp = afs_GetVolumeByName(buf, localcell, 1, NULL, READ_LOCK);
            }
        }
index 0acb448..3ebba4f 100644 (file)
@@ -354,8 +354,7 @@ afs_RebuildDynroot(void)
        dotLen = strlen(c->cellName) + 2;
        dotCell = afs_osi_Alloc(dotLen);
        osi_Assert(dotCell != NULL);
-       strcpy(dotCell, ".");
-       afs_strcat(dotCell, c->cellName);
+       osi_Assert(snprintf(dotCell, dotLen, ".%s", c->cellName) < dotLen);
 
        afs_dynroot_computeDirEnt(c->cellName, &curPage, &curChunk);
        afs_dynroot_computeDirEnt(dotCell, &curPage, &curChunk);
@@ -373,8 +372,7 @@ afs_RebuildDynroot(void)
        dotLen = strlen(ca->alias) + 2;
        dotCell = afs_osi_Alloc(dotLen);
        osi_Assert(dotCell != NULL);
-       strcpy(dotCell, ".");
-       afs_strcat(dotCell, ca->alias);
+       osi_Assert(snprintf(dotCell, dotLen, ".%s", ca->alias) < dotLen);
 
        afs_dynroot_computeDirEnt(ca->alias, &curPage, &curChunk);
        afs_dynroot_computeDirEnt(dotCell, &curPage, &curChunk);
@@ -434,8 +432,7 @@ afs_RebuildDynroot(void)
        dotLen = strlen(c->cellName) + 2;
        dotCell = afs_osi_Alloc(dotLen);
        osi_Assert(dotCell != NULL);
-       strcpy(dotCell, ".");
-       afs_strcat(dotCell, c->cellName);
+       osi_Assert(snprintf(dotCell, dotLen, ".%s", c->cellName) < dotLen);
        afs_dynroot_addDirEnt(dirHeader, &curPage, &curChunk, c->cellName,
                              VNUM_FROM_CIDX_RW(cellidx, 0));
        afs_dynroot_addDirEnt(dirHeader, &curPage, &curChunk, dotCell,
@@ -454,8 +451,7 @@ afs_RebuildDynroot(void)
        dotLen = strlen(ca->alias) + 2;
        dotCell = afs_osi_Alloc(dotLen);
        osi_Assert(dotCell != NULL);
-       strcpy(dotCell, ".");
-       afs_strcat(dotCell, ca->alias);
+       osi_Assert(snprintf(dotCell, dotLen, ".%s", ca->alias) < dotLen);
        afs_dynroot_addDirEnt(dirHeader, &curPage, &curChunk, ca->alias,
                              VNUM_FROM_CAIDX_RW(aliasidx, 0));
        afs_dynroot_addDirEnt(dirHeader, &curPage, &curChunk, dotCell,
@@ -661,7 +657,8 @@ afs_DynrootNewVnode(struct vcache *avc, struct AFSFetchStatus *status)
                linklen = strlen(ts->target);
                avc->linkData = afs_osi_Alloc(linklen + 1);
                osi_Assert(avc->linkData != NULL);
-               strcpy(avc->linkData, ts->target);
+               osi_Assert(strlcpy(avc->linkData, ts->target, linklen + 1) <
+                                  linklen + 1);
 
                status->Length = linklen;
                status->UnixModeBits = 0755;
@@ -707,11 +704,12 @@ afs_DynrootNewVnode(struct vcache *avc, struct AFSFetchStatus *status)
                linklen = 7;
            } else {
                int namelen = strlen(realName);
+               char *prefix = rw ? "." : "";
                linklen = rw + namelen;
                avc->linkData = afs_osi_Alloc(linklen + 1);
                osi_Assert(avc->linkData != NULL);
-               strcpy(avc->linkData, rw ? "." : "");
-               afs_strcat(avc->linkData, realName);
+               osi_Assert(snprintf(avc->linkData, linklen + 1, "%s%s", prefix,
+                          realName) < linklen + 1);
            }
 
            status->UnixModeBits = 0755;
@@ -733,16 +731,16 @@ afs_DynrootNewVnode(struct vcache *avc, struct AFSFetchStatus *status)
            linklen = 2 + namelen + strlen(bp);
            avc->linkData = afs_osi_Alloc(linklen + 1);
            osi_Assert(avc->linkData != NULL);
-           strcpy(avc->linkData, "%");
-           afs_strcat(avc->linkData, c->cellName);
-           afs_strcat(avc->linkData, ":");
-           afs_strcat(avc->linkData, bp);
+           osi_Assert(snprintf(avc->linkData, linklen + 1, "%%%s:%s",
+                      c->cellName, bp) < linklen + 1);
 
            status->UnixModeBits = 0644;
            status->ParentVnode = AFS_DYNROOT_MOUNT_VNODE;
            afs_PutCell(c, READ_LOCK);
 
        } else {
+           char *prefix = rw ? "%" : "#";
+
            c = afs_GetCellByIndex(cellidx, READ_LOCK);
            if (!c) {
                afs_warn("dynroot vnode inconsistency, can't find cell %d\n",
@@ -757,9 +755,8 @@ afs_DynrootNewVnode(struct vcache *avc, struct AFSFetchStatus *status)
            linklen = 1 + namelen + 10;
            avc->linkData = afs_osi_Alloc(linklen + 1);
            osi_Assert(avc->linkData != NULL);
-           strcpy(avc->linkData, rw ? "%" : "#");
-           afs_strcat(avc->linkData, c->cellName);
-           afs_strcat(avc->linkData, ":root.cell");
+           osi_Assert(snprintf(avc->linkData, linklen + 1, "%s%s:root.cell",
+                      prefix, c->cellName) < linklen + 1);
 
            status->UnixModeBits = 0644;
            afs_PutCell(c, READ_LOCK);
@@ -878,6 +875,7 @@ afs_DynrootVOPSymlink(struct vcache *avc, afs_ucred_t *acred,
                      char *aname, char *atargetName)
 {
     struct afs_dynSymlink *tps;
+    size_t len;
 
     if (afs_cr_uid(acred))
        return EPERM;
@@ -900,12 +898,14 @@ afs_DynrootVOPSymlink(struct vcache *avc, afs_ucred_t *acred,
     osi_Assert(tps != NULL);
     tps->index = afs_dynSymlinkIndex++;
     tps->next = afs_dynSymlinkBase;
-    tps->name = afs_osi_Alloc(strlen(aname) + 1);
+    len = strlen(aname) + 1;
+    tps->name = afs_osi_Alloc(len);
     osi_Assert(tps->name != NULL);
-    strcpy(tps->name, aname);
-    tps->target = afs_osi_Alloc(strlen(atargetName) + 1);
+    osi_Assert(strlcpy(tps->name, aname, len) < len);
+    len = strlen(atargetName) + 1;
+    tps->target = afs_osi_Alloc(len);
     osi_Assert(tps->target != NULL);
-    strcpy(tps->target, atargetName);
+    osi_Assert(strlcpy(tps->target, atargetName, len) < len);
     afs_dynSymlinkBase = tps;
     ReleaseWriteLock(&afs_dynSymlinkLock);
 
index 2cf15e2..42b4a0c 100644 (file)
@@ -706,6 +706,7 @@ afs_icl_CreateLogWithFlags(char *name, afs_int32 logSize, afs_uint32 flags,
                           struct afs_icl_log **outLogpp)
 {
     struct afs_icl_log *logp;
+    size_t namelen;
 
     /* add into global list under lock */
     ObtainWriteLock(&afs_icl_lock, 183);
@@ -731,8 +732,9 @@ afs_icl_CreateLogWithFlags(char *name, afs_int32 logSize, afs_uint32 flags,
     memset((caddr_t) logp, 0, sizeof(*logp));
 
     logp->refCount = 1;
-    logp->name = osi_AllocSmallSpace(strlen(name) + 1);
-    strcpy(logp->name, name);
+    namelen = strlen(name) + 1;
+    logp->name = osi_AllocSmallSpace(namelen);
+    osi_Assert(strlcpy(logp->name, name, namelen) < namelen);
     LOCK_INIT(&logp->lock, "logp lock");
     logp->logSize = logSize;
     logp->datap = NULL;                /* don't allocate it until we need it */
@@ -1060,6 +1062,7 @@ afs_icl_CreateSetWithFlags(char *name, struct afs_icl_log *baseLogp,
     struct afs_icl_set *setp;
     int i;
     afs_int32 states = ICL_DEFAULT_SET_STATES;
+    size_t namelen;
 
     ObtainWriteLock(&afs_icl_lock, 197);
     if (!afs_icl_inited)
@@ -1100,8 +1103,9 @@ afs_icl_CreateSetWithFlags(char *name, struct afs_icl_log *baseLogp,
      * the afs_icl_lock is still held, and thus the obtain can't block.
      */
     ObtainWriteLock(&setp->lock, 199);
-    setp->name = osi_AllocSmallSpace(strlen(name) + 1);
-    strcpy(setp->name, name);
+    namelen = strlen(name) + 1;
+    setp->name = osi_AllocSmallSpace(namelen);
+    osi_Assert(strlcpy(setp->name, name, namelen) < namelen);
     setp->nevents = ICL_DEFAULTEVENTS;
     setp->eventFlags = afs_osi_Alloc(ICL_DEFAULTEVENTS);
     osi_Assert(setp->eventFlags != NULL);
index a9d6379..63d24cf 100644 (file)
@@ -543,7 +543,7 @@ afs_ResourceInit(int preallocs)
            osi_Assert(afs_sysnamelist[i] != NULL);
        }
        afs_sysname = afs_sysnamelist[0];
-       strcpy(afs_sysname, SYS_NAME);
+       osi_Assert(strlcpy(afs_sysname, SYS_NAME, MAXSYSNAME) < MAXSYSNAME);
        afs_sysnamecount = 1;
        afs_sysnamegen++;
     }
index 0ae4d3c..e027490 100644 (file)
@@ -48,8 +48,7 @@ afs_AddMarinerName(char *aname, struct vcache *avc)
        marinerPtr = 1;
     }
     tp = marinerNames[i];
-    strncpy(tp, aname, SMAR);
-    tp[SMAR - 1] = 0;
+    strlcpy(tp, aname, SMAR);
     marinerVCs[i] = avc;
     return 0;
 }
@@ -78,7 +77,8 @@ void
 afs_MarinerLog(char *astring, struct vcache *avc)
 {
     struct sockaddr_in taddr;
-    char *tp, *tp1, *buf;
+    char *buf;
+    size_t bufsize, buflen;
     struct iovec dvec;
 
     AFS_STATCNT(afs_MarinerLog);
@@ -88,24 +88,32 @@ afs_MarinerLog(char *astring, struct vcache *avc)
 #ifdef  STRUCT_SOCKADDR_HAS_SA_LEN
     taddr.sin_len = sizeof(taddr);
 #endif
-    tp = buf = osi_AllocSmallSpace(AFS_SMALLOCSIZ);
+    bufsize = AFS_SMALLOCSIZ;
+    buf = osi_AllocSmallSpace(bufsize);
+
+    if (strlcpy(buf, astring, bufsize) >= bufsize)
+       goto done;
 
-    strcpy(tp, astring);
-    tp += strlen(astring);
     if (avc) {
-       *tp++ = ' ';
-       tp1 = afs_GetMariner(avc);
-       strcpy(tp, tp1);
-       tp += strlen(tp1);
+       char *tp1 = afs_GetMariner(avc);
+
+       if (strlcat(buf, " ", bufsize) >= bufsize)
+           goto done;
+       if (strlcat(buf, tp1, bufsize) >= bufsize)
+           goto done;
     }
-    *tp++ = '\n';
+    if (strlcat(buf, "\n", bufsize) >= bufsize)
+       goto done;
+
     /* note, console doesn't want a terminating null */
     /* I don't care if mariner packets fail to be sent */
+    buflen = strlen(buf);
     dvec.iov_base = buf;
-    dvec.iov_len = tp - buf;
+    dvec.iov_len = buflen;
     AFS_GUNLOCK();
-    (void)rxi_NetSend(afs_server->socket, &taddr, &dvec, 1, tp - buf, 0);
+    (void)rxi_NetSend(afs_server->socket, &taddr, &dvec, 1, buflen, 0);
     AFS_GLOCK();
+ done:
     osi_FreeSmallSpace(buf);
 }                              /*afs_MarinerLog */
 
index e434881..637d60a 100644 (file)
@@ -111,7 +111,7 @@ afspag_Init(afs_int32 nfs_server_addr)
         osi_Assert(afs_sysnamelist[i] != NULL);
     }
     afs_sysname = afs_sysnamelist[0];
-    strcpy(afs_sysname, SYS_NAME);
+    osi_Assert(strlcpy(afs_sysname, SYS_NAME, MAXSYSNAME) < MAXSYSNAME);
     afs_sysnamecount = 1;
     afs_sysnamegen++;
 
index 651bb3a..3dce854 100644 (file)
@@ -48,13 +48,12 @@ afspag_GetCell(char *acell)
        tcell = afs_osi_Alloc(sizeof(struct afspag_cell));
        if (!tcell)
            goto out;
-       tcell->cellname = afs_osi_Alloc(strlen(acell) + 1);
+       tcell->cellname = afs_strdup(acell);
        if (!tcell->cellname) {
            afs_osi_Free(tcell, sizeof(struct afspag_cell));
            tcell = 0;
            goto out;
        }
-       strcpy(tcell->cellname, acell);
        tcell->cellnum = ++lastcell;
        tcell->next = cells;
        cells = tcell;
@@ -388,11 +387,9 @@ SPAGCB_GetSysName(struct rx_call *a_call, afs_int32 a_uid,
        goto out;
 
     for (i = 0; i < afs_sysnamecount; i++) {
-       a_sysnames->SysNameList_val[i].sysname =
-           afs_osi_Alloc(strlen(afs_sysnamelist[i]) + 1);
+       a_sysnames->SysNameList_val[i].sysname = afs_strdup(afs_sysnamelist[i]);
        if (!a_sysnames->SysNameList_val[i].sysname)
            goto out;
-       strcpy(a_sysnames->SysNameList_val[i].sysname, afs_sysnamelist[i]);
     }
 
     ReleaseReadLock(&afs_xpagsys);
index 1ee1a66..94ee107 100644 (file)
@@ -3840,6 +3840,7 @@ DECL_PIOCTL(PSetSysName)
     int t, count, num = 0, allpags = 0;
     char **sysnamelist;
     struct afs_pdata validate;
+    size_t len;
 
     AFS_STATCNT(PSetSysName);
     if (!afs_globalVFS) {
@@ -3906,7 +3907,11 @@ DECL_PIOCTL(PSetSysName)
            }
        } else {
            foundname = num;
-           strcpy(outname, sysnamelist[0]);
+           len = sizeof(outname);
+           if (strlcpy(outname, sysnamelist[0], len) >= len) {
+               afs_PutUser(au, READ_LOCK);
+               return E2BIG;
+           }
        }
        afs_PutUser(au, READ_LOCK);
        if (setsysname)
@@ -3916,7 +3921,9 @@ DECL_PIOCTL(PSetSysName)
        if (!afs_sysname)
            osi_Panic("PSetSysName: !afs_sysname\n");
        if (!setsysname) {      /* user just wants the info */
-           strcpy(outname, afs_sysname);
+           len = sizeof(outname);
+           if (strlcpy(outname, afs_sysname, len) >= len)
+               return E2BIG;
            foundname = afs_sysnamecount;
            sysnamelist = afs_sysnamelist;
        } else {                /* Local guy; only root can change sysname */
@@ -3933,7 +3940,8 @@ DECL_PIOCTL(PSetSysName)
 
            if (strlen(inname) >= MAXSYSNAME-1)
                return EINVAL;
-           strcpy(afs_sysname, inname);
+           if (strlcpy(afs_sysname, inname, MAXSYSNAME) >= MAXSYSNAME)
+               return E2BIG;
 
            if (setsysname > 1) {       /* ... or list */
                for (count = 1; count < setsysname; ++count) {
@@ -5129,7 +5137,7 @@ DECL_PIOCTL(PFsCmd)
        if (vType(tvc) == VLNK) {
            ObtainWriteLock(&tvc->lock, 555);
            if (afs_HandleLink(tvc, areq) == 0)
-               strncpy((char *)&Outputs->chars, tvc->linkData, MAXCMDCHARS);
+               strlcpy((char *)&Outputs->chars, tvc->linkData, MAXCMDCHARS);
            ReleaseWriteLock(&tvc->lock);
        }
     }
index 1faeef1..d3d4d00 100644 (file)
@@ -732,9 +732,8 @@ afs_SetupVolume(afs_int32 volid, char *aname, void *ve, struct cell *tcell,
        LockAndInstallVolumeEntry(tv, ove, tcell->cellNum);
     if (agood) {
        if (!tv->name) {
-           tv->name = afs_osi_Alloc(strlen(aname) + 1);
+           tv->name = afs_strdup(aname);
            osi_Assert(tv->name != NULL);
-           strcpy(tv->name, aname);
        }
     }
     for (i = 0; i < NMAXNSERVERS; i++) {
@@ -796,6 +795,7 @@ afs_NewDynrootVolume(struct VenusFid *fid)
     struct volume *tv;
     struct vldbentry *tve;
     char *bp, tbuf[CVBS];
+    size_t len;
 
     tcell = afs_GetCell(fid->Cell, READ_LOCK);
     if (!tcell)
@@ -807,7 +807,8 @@ afs_NewDynrootVolume(struct VenusFid *fid)
 
     bp = afs_cv2string(&tbuf[CVBS], fid->Fid.Volume);
     memset(tve, 0, sizeof(*tve));
-    strcpy(tve->name, "local-dynroot");
+    len = sizeof(tve->name);
+    osi_Assert(strlcpy(tve->name, "local-dynroot", len) < len);
     tve->volumeId[ROVOL] = fid->Fid.Volume;
     tve->flags = VLF_ROEXISTS;
 
index 8e6bbc1..613f687 100644 (file)
@@ -10,5 +10,4 @@ evp-algs.c
 rand.c
 rand-timer.c
 evp-hcrypto.h
-strcasecmp.c
 heim_threads.h
diff --git a/src/crypto/hcrypto/kernel/strcasecmp.c b/src/crypto/hcrypto/kernel/strcasecmp.c
deleted file mode 100644 (file)
index 4a5acf2..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright 2000, International Business Machines Corporation and others.
- * All Rights Reserved.
- *
- * This software has been released under the terms of the IBM Public
- * License.  For details, see the LICENSE file in the top-level source
- * directory or online at http://www.openafs.org/dl/license10.html
- */
-
-const char hckernel_strcasecmp_placeholder[] =
-               "This is not an empty compilation unit.";
-
-#ifndef afs_strcasecmp
-int
-afs_strcasecmp(const char *s1, const char *s2)
-{
-    while (*s1 && *s2) {
-       char c1, c2;
-
-       c1 = *s1++;
-       c2 = *s2++;
-       if (c1 >= 'A' && c1 <= 'Z')
-           c1 += 0x20;
-       if (c2 >= 'A' && c2 <= 'Z')
-           c2 += 0x20;
-       if (c1 != c2)
-           return c1 - c2;
-    }
-
-    return *s1 - *s2;
-}
-#endif
index 51c200a..84a5e2c 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <afsconfig.h>
 #include <afs/param.h>
+#include <afs/afsint.h>
 
 #ifdef KERNEL
 # if !defined(UKERNEL)
@@ -47,6 +48,7 @@
 # else /* !defined(UKERNEL) */
 #  include "afs/stds.h"
 #  include "afs/sysincludes.h"
+#  include "afsincludes.h"
 # endif /* !defined(UKERNEL) */
 
 /* afs_buffer.c */
@@ -98,6 +100,7 @@ afs_dir_Create(dir_file_t dir, char *entry, void *voidfid)
     struct DirEntry *ep;
     struct DirHeader *dhp;
     int code;
+    size_t rlen;
 
     /* check name quality */
     if (*entry == 0)
@@ -127,7 +130,16 @@ afs_dir_Create(dir_file_t dir, char *entry, void *voidfid)
     ep->flag = FFIRST;
     ep->fid.vnode = htonl(vfid[1]);
     ep->fid.vunique = htonl(vfid[2]);
-    strcpy(ep->name, entry);
+
+    /*
+     * Note, the size of ep->name does not represent the maximum size of the
+     * name. FindBlobs has already ensured that the name can fit.
+     */
+    rlen = strlcpy(ep->name, entry, AFSNAMEMAX + 1);
+    if (rlen >= AFSNAMEMAX + 1) {
+       DRelease(&entrybuf, 1);
+       return ENAMETOOLONG;
+    }
 
     /* Now we just have to thread it on the hash table list. */
     if (DRead(dir, 0, &headerbuf) != 0) {
@@ -799,6 +811,7 @@ afs_dir_InverseLookup(void *dir, afs_uint32 vnode, afs_uint32 unique,
     struct DirBuffer entrybuf;
     struct DirEntry *entry;
     int code = 0;
+    size_t rlen;
 
     code = FindFid(dir, vnode, unique, &entrybuf);
     if (code) {
@@ -806,10 +819,10 @@ afs_dir_InverseLookup(void *dir, afs_uint32 vnode, afs_uint32 unique,
     }
     entry = (struct DirEntry *)entrybuf.data;
 
-    if (strlen(entry->name) >= length)
+    rlen = strlcpy(name, entry->name, length);
+    if (rlen >= length) {
        code = E2BIG;
-    else
-       strcpy(name, entry->name);
+    }
     DRelease(&entrybuf, 0);
     return code;
 }
index 29824ea..e129104 100644 (file)
@@ -21,5 +21,5 @@ clean:
        $(RM) -f *.o *.a test dtest core
 
 dtest:         dtest.o
-       $(AFS_LDRULE) dtest.o $(LIBS)
+       $(AFS_LDRULE) dtest.o $(LIBS) $(LIB_roken) $(XLIBS)
 
index f6dc450..2e77531 100644 (file)
@@ -265,7 +265,7 @@ AFSPAGOBJS = \
        rx_pag_packet.o \
        rx_multi.o      \
        rx_stats.o      \
-       strcasecmp_pag.o        \
+       afs_util.o      \
        opr_rbtree.o    \
        xdr_rx.o        \
        xdr_mem.o       \
@@ -552,8 +552,6 @@ rx_pag_packet.o: $(TOP_SRC_RX)/rx_packet.c
        $(CRULE_NOOPT) $(TOP_SRC_RX)/rx_packet.c
 rx_pag_knet.o: $(TOP_SRC_RX)/${MKAFS_OSTYPE}/rx_knet.c
        $(CRULE_NOOPT) $(TOP_SRC_RX)/${MKAFS_OSTYPE}/rx_knet.c
-strcasecmp_pag.o: $(TOP_SRCDIR)/crypto/hcrypto/kernel/strcasecmp.c
-       $(CRULE_NOOPT) $(TOP_SRCDIR)/crypto/hcrypto/kernel/strcasecmp.c
 
 # Crypto
 md5.o: $(TOP_SRCDIR)/external/heimdal/hcrypto/md5.c
index d26975d..98f1b45 100644 (file)
@@ -234,7 +234,7 @@ osi_AssertFailK(const char *expr, const char *file, int line)
 
 # define ADDBUF(BUF, STR)                                      \
        if (strlen(BUF) + strlen((char *)(STR)) + 1 <= sizeof BUF) {    \
-               strcat(BUF, (char *)(STR));                             \
+               strlcat(BUF, (char *)(STR), sizeof(BUF));               \
        }
 
     buf[0] = '\0';
index 8e4eb98..edf37ca 100644 (file)
@@ -2108,7 +2108,7 @@ rxi_ReceiveVersionPacket(struct rx_packet *ap, osi_socket asocket,
        ap->header.flags = ap->header.flags & ~RX_CLIENT_INITIATED;
        rxi_EncodePacketHeader(ap);
        memset(buf, 0, sizeof(buf));
-       strncpy(buf, cml_version_number + 4, sizeof(buf) - 1);
+       strlcpy(buf, cml_version_number + 4, sizeof(buf));
        rx_packetwrite(ap, 0, 65, buf);
        tl = ap->length;
        ap->length = 65;