avoid-buffer-overflow-on-rx-fixed-size-array-return-20090402

LICENSE IPL10
FIXES 124579

avoid potentially writing beyond allocated memory if a return is larger than expected
This commit is contained in:
Simon Wilkinson 2009-04-06 23:52:52 +00:00 committed by Derrick Brashear
parent 160619505d
commit 62bca1123f
2 changed files with 24 additions and 14 deletions

View File

@ -636,8 +636,6 @@ afs_DoBulkStat(struct vcache *adp, long dirCookie, struct vrequest *areqp)
int nskip; /* # of slots in the LRU queue to skip */ int nskip; /* # of slots in the LRU queue to skip */
struct vcache *lruvcp; /* vcache ptr of our goal pos in LRU queue */ struct vcache *lruvcp; /* vcache ptr of our goal pos in LRU queue */
struct dcache *dcp; /* chunk containing the dir block */ 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. */ afs_size_t temp; /* temp for holding chunk length, &c. */
struct AFSFid *fidsp; /* file IDs were collecting */ struct AFSFid *fidsp; /* file IDs were collecting */
struct AFSCallBack *cbsp; /* call back pointers */ struct AFSCallBack *cbsp; /* call back pointers */
@ -698,13 +696,11 @@ afs_DoBulkStat(struct vcache *adp, long dirCookie, struct vrequest *areqp)
* one for fids and callbacks, and one for stat info. Well set * one for fids and callbacks, and one for stat info. Well set
* up our pointers to the memory from there, too. * up our pointers to the memory from there, too.
*/ */
statMemp = osi_AllocLargeSpace(nentries * sizeof(AFSFetchStatus)); statsp = (AFSFetchStatus *)
statsp = (struct AFSFetchStatus *)statMemp; osi_Alloc(AFSCBMAX * sizeof(AFSFetchStatus));
cbfMemp = fidsp = (AFSFid *) osi_AllocLargeSpace(nentries * sizeof(AFSFid));
osi_AllocLargeSpace(nentries * cbsp = (AFSCallBack *)
(sizeof(AFSCallBack) + sizeof(AFSFid))); osi_Alloc(AFSCBMAX * sizeof(AFSCallBack));
fidsp = (AFSFid *) cbfMemp;
cbsp = (AFSCallBack *) (cbfMemp + nentries * sizeof(AFSFid));
/* next, we must iterate over the directory, starting from the specified /* next, we must iterate over the directory, starting from the specified
* cookie offset (dirCookie), and counting out nentries file entries. * cookie offset (dirCookie), and counting out nentries file entries.
@ -1192,8 +1188,9 @@ afs_DoBulkStat(struct vcache *adp, long dirCookie, struct vrequest *areqp)
code = 0; code = 0;
} }
done2: done2:
osi_FreeLargeSpace(statMemp); osi_FreeLargeSpace((char *)fidsp);
osi_FreeLargeSpace(cbfMemp); osi_Free((char *)statsp, AFSCBMAX * sizeof(AFSFetchStatus));
osi_Free((char *)cbsp, AFSCBMAX * sizeof(AFSCallBack));
return code; return code;
} }

View File

@ -239,8 +239,14 @@ pioctl(char *path, afs_int32 cmd, struct ViceIoctl *data, afs_int32 follow)
InData.rmtbulk_len = data->in_size; InData.rmtbulk_len = data->in_size;
InData.rmtbulk_val = inbuffer; InData.rmtbulk_val = inbuffer;
inparam_conversion(cmd, InData.rmtbulk_val, 0); 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 /* 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 * lose the current directory value when doing an rpc call. Below we
* prepend the current absolute path directory, if the name is relative */ * prepend the current absolute path directory, if the name is relative */
@ -277,8 +283,15 @@ pioctl(char *path, afs_int32 cmd, struct ViceIoctl *data, afs_int32 follow)
if (!errorcode) { if (!errorcode) {
/* Do the conversions back to the host order; store the results back /* Do the conversions back to the host order; store the results back
* on the same buffer */ * 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); free(inbuffer);
return errorcode; return errorcode;
} }