From: Russ Allbery Date: Fri, 3 Apr 2009 03:55:08 +0000 (-0700) Subject: Apply upstream security patches from 1.4.9 X-Git-Tag: debian/1.4.7.dfsg1-6+lenny1~3 X-Git-Url: https://git.michaelhowe.org/gitweb/?a=commitdiff_plain;h=fc686cc8619ee17faacc4da45f6c690923cb2ce5;p=packages%2Fo%2Fopenafs.git Apply upstream security patches from 1.4.9 * Apply upstream security patches from 1.4.9: - Avoid a potential kernel memory overrun if more items than requested are returned from an InlineBulk or BulkStatus message. - Avoid converting negative errors into invalid kernel memory pointers. --- diff --git a/debian/changelog b/debian/changelog index 87777a4d3..681392329 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,13 @@ +openafs (1.4.7.dfsg1-6+lenny1) UNRELEASED; urgency=high + + * Apply upstream security patches from 1.4.9: + - Avoid a potential kernel memory overrun if more items than requested + are returned from an InlineBulk or BulkStatus message. + - Avoid converting negative errors into invalid kernel memory + pointers. + + -- Russ Allbery Thu, 02 Apr 2009 20:54:27 -0700 + openafs (1.4.7.dfsg1-6) unstable; urgency=low * Apply upstream patch to free /proc entries in the correct order. diff --git a/src/afs/LINUX/osi_vnodeops.c b/src/afs/LINUX/osi_vnodeops.c index 8cc52cdd5..4e10eec2b 100644 --- a/src/afs/LINUX/osi_vnodeops.c +++ b/src/afs/LINUX/osi_vnodeops.c @@ -1051,8 +1051,10 @@ afs_linux_lookup(struct inode *dip, struct dentry *dp) #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,10) if (code == ENOENT) return ERR_PTR(0); - else + else if ((code >= 0) && (code <= MAX_ERRNO)) return ERR_PTR(-code); + else + return ERR_PTR(-EIO); #else if (code == ENOENT) code = 0; @@ -1396,7 +1398,10 @@ afs_linux_follow_link(struct dentry *dp, struct dentry *basep, if (code < 0) { dput(basep); - res = ERR_PTR(code); + if (code < -MAX_ERRNO) + res = ERR_PTR(-EIO); + else + res = ERR_PTR(code); } else { name[code] = '\0'; res = lookup_dentry(name, basep, follow); diff --git a/src/afs/VNOPS/afs_vnop_lookup.c b/src/afs/VNOPS/afs_vnop_lookup.c index f1cfa1a50..094191a6d 100644 --- a/src/afs/VNOPS/afs_vnop_lookup.c +++ b/src/afs/VNOPS/afs_vnop_lookup.c @@ -538,8 +538,6 @@ afs_DoBulkStat(struct vcache *adp, long dirCookie, struct vrequest *areqp) int nskip; /* # of slots in the LRU queue to skip */ struct vcache *lruvcp; /* vcache ptr of our goal pos in LRU queue */ struct dcache *dcp; /* chunk containing the dir block */ - char *statMemp; /* status memory block */ - char *cbfMemp; /* callback and fid memory block */ afs_size_t temp; /* temp for holding chunk length, &c. */ struct AFSFid *fidsp; /* file IDs were collecting */ struct AFSCallBack *cbsp; /* call back pointers */ @@ -597,13 +595,11 @@ afs_DoBulkStat(struct vcache *adp, long dirCookie, struct vrequest *areqp) * one for fids and callbacks, and one for stat info. Well set * up our pointers to the memory from there, too. */ - statMemp = osi_AllocLargeSpace(nentries * sizeof(AFSFetchStatus)); - statsp = (struct AFSFetchStatus *)statMemp; - cbfMemp = - osi_AllocLargeSpace(nentries * - (sizeof(AFSCallBack) + sizeof(AFSFid))); - fidsp = (AFSFid *) cbfMemp; - cbsp = (AFSCallBack *) (cbfMemp + nentries * sizeof(AFSFid)); + statsp = (AFSFetchStatus *) + osi_Alloc(AFSCBMAX * sizeof(AFSFetchStatus)); + fidsp = (AFSFid *) osi_AllocLargeSpace(nentries * sizeof(AFSFid)); + cbsp = (AFSCallBack *) + osi_Alloc(AFSCBMAX * sizeof(AFSCallBack)); /* next, we must iterate over the directory, starting from the specified * cookie offset (dirCookie), and counting out nentries file entries. @@ -1081,7 +1077,7 @@ afs_DoBulkStat(struct vcache *adp, long dirCookie, struct vrequest *areqp) afs_PutVolume(volp, READ_LOCK); /* If we did the InlineBulk RPC pull out the return code */ - if (inlinebulk) { + if (inlinebulk && code == 0) { if ((&statsp[0])->errorCode) { afs_Analyze(tcp, (&statsp[0])->errorCode, &adp->fid, areqp, AFS_STATS_FS_RPCIDX_BULKSTATUS, SHARED_LOCK, NULL); @@ -1091,8 +1087,9 @@ afs_DoBulkStat(struct vcache *adp, long dirCookie, struct vrequest *areqp) code = 0; } done2: - osi_FreeLargeSpace(statMemp); - osi_FreeLargeSpace(cbfMemp); + osi_FreeLargeSpace((char *)fidsp); + osi_Free((char *)statsp, AFSCBMAX * sizeof(AFSFetchStatus)); + osi_Free((char *)cbsp, AFSCBMAX * sizeof(AFSCallBack)); return code; } diff --git a/src/sys/rmtsysc.c b/src/sys/rmtsysc.c index c9eeed8ec..c43cf9120 100644 --- a/src/sys/rmtsysc.c +++ b/src/sys/rmtsysc.c @@ -241,8 +241,14 @@ pioctl(char *path, afs_int32 cmd, struct ViceIoctl *data, afs_int32 follow) InData.rmtbulk_len = data->in_size; InData.rmtbulk_val = inbuffer; inparam_conversion(cmd, InData.rmtbulk_val, 0); - OutData.rmtbulk_len = data->out_size; - OutData.rmtbulk_val = data->out; + + OutData.rmtbulk_len = MAXBUFFERLEN * sizeof(*OutData.rmtbulk_val); + OutData.rmtbulk_val = malloc(OutData.rmtbulk_len); + if (!OutData.rmtbulk_val) { + free(inbuffer); + return -1; + } + /* We always need to pass absolute pathnames to the remote pioctl since we * lose the current directory value when doing an rpc call. Below we * prepend the current absolute path directory, if the name is relative */ @@ -279,8 +285,15 @@ pioctl(char *path, afs_int32 cmd, struct ViceIoctl *data, afs_int32 follow) if (!errorcode) { /* Do the conversions back to the host order; store the results back * on the same buffer */ - outparam_conversion(cmd, OutData.rmtbulk_val, 1); + if (data->out_size < OutData.rmtbulk_len) { + errno = EINVAL; + errorcode = -1; + } else { + memcpy(data->out, OutData.rmtbulk_val, data->out_size); + outparam_conversion(cmd, data->out, 1); + } } + free(OutData.rmtbulk_val); free(inbuffer); return errorcode; }