mirror of
https://git.openafs.org/openafs.git
synced 2025-01-18 06:50:12 +00:00
DEVEL15-linux-vnop-return-value-cleanup-20090703
LICENSE IPL10
rework all linux vnode ops so the vulnerability we previously had can't
recur later just because someone makes a change that would leak a negative
error
(cherry picked from commit ebc4f737ae
)
This commit is contained in:
parent
3866da1c89
commit
61aabcf11f
@ -80,6 +80,22 @@ extern struct afs_cacheOps afs_UfsCacheOps;
|
||||
} while(0);
|
||||
#endif /* AFS_LINUX24_ENV */
|
||||
|
||||
|
||||
/* This function converts a positive error code from AFS into a negative
|
||||
* code suitable for passing into the Linux VFS layer. It checks that the
|
||||
* error code is within the permissable bounds for the ERR_PTR mechanism.
|
||||
*
|
||||
* _All_ error codes which come from the AFS layer should be passed through
|
||||
* this function before being returned to the kernel.
|
||||
*/
|
||||
|
||||
static inline int afs_convert_code(int code) {
|
||||
if ((code >= 0) && (code <= MAX_ERRNO))
|
||||
return -code;
|
||||
else
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
afs_linux_read(struct file *fp, char *buf, size_t count, loff_t * offp)
|
||||
{
|
||||
@ -98,7 +114,7 @@ afs_linux_read(struct file *fp, char *buf, size_t count, loff_t * offp)
|
||||
code = afs_VerifyVCache(vcp, &treq);
|
||||
|
||||
if (code)
|
||||
code = -code;
|
||||
code = afs_convert_code(code);
|
||||
else {
|
||||
#if defined(AFS_CACHE_BYPASS)
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
|
||||
@ -158,7 +174,7 @@ afs_linux_write(struct file *fp, const char *buf, size_t count, loff_t * offp)
|
||||
afs_FakeOpen(vcp);
|
||||
ReleaseWriteLock(&vcp->lock);
|
||||
if (code)
|
||||
code = -code;
|
||||
code = afs_convert_code(code);
|
||||
else {
|
||||
AFS_GUNLOCK();
|
||||
#ifdef DO_SYNC_READ
|
||||
@ -212,19 +228,25 @@ afs_linux_readdir(struct file *fp, void *dirbuf, filldir_t filldir)
|
||||
|
||||
code = afs_InitReq(&treq, credp);
|
||||
crfree(credp);
|
||||
if (code)
|
||||
if (code) {
|
||||
code = afs_convert_code(code);
|
||||
goto out1;
|
||||
}
|
||||
|
||||
afs_InitFakeStat(&fakestat);
|
||||
code = afs_EvalFakeStat(&avc, &fakestat, &treq);
|
||||
if (code)
|
||||
if (code) {
|
||||
code = afs_convert_code(code);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* update the cache entry */
|
||||
tagain:
|
||||
code = afs_VerifyVCache(avc, &treq);
|
||||
if (code)
|
||||
if (code) {
|
||||
code = afs_convert_code(code);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* get a reference to the entire directory */
|
||||
tdc = afs_GetDCache(avc, (afs_size_t) 0, &treq, &origOffset, &tlen, 1);
|
||||
@ -425,7 +447,7 @@ out:
|
||||
return code;
|
||||
|
||||
out_err:
|
||||
code = -code;
|
||||
code = afs_convert_code(code);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -447,7 +469,7 @@ afs_linux_open(struct inode *ip, struct file *fp)
|
||||
#endif
|
||||
|
||||
crfree(credp);
|
||||
return -code;
|
||||
return afs_convert_code(code);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -468,7 +490,7 @@ afs_linux_release(struct inode *ip, struct file *fp)
|
||||
#endif
|
||||
|
||||
crfree(credp);
|
||||
return -code;
|
||||
return afs_convert_code(code);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -492,7 +514,7 @@ afs_linux_fsync(struct file *fp, struct dentry *dp)
|
||||
maybe_unlock_kernel();
|
||||
#endif
|
||||
crfree(credp);
|
||||
return -code;
|
||||
return afs_convert_code(code);
|
||||
|
||||
}
|
||||
|
||||
@ -586,7 +608,7 @@ afs_linux_lock(struct file *fp, int cmd, struct file_lock *flp)
|
||||
flp->fl_end = flock.l_start + flock.l_len - 1;
|
||||
|
||||
crfree(credp);
|
||||
return -code;
|
||||
return afs_convert_code(code);
|
||||
}
|
||||
|
||||
#ifdef STRUCT_FILE_OPERATIONS_HAS_FLOCK
|
||||
@ -636,7 +658,7 @@ afs_linux_flock(struct file *fp, int cmd, struct file_lock *flp) {
|
||||
flp->fl_pid = flock.l_pid;
|
||||
|
||||
crfree(credp);
|
||||
return -code;
|
||||
return afs_convert_code(code);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -711,7 +733,7 @@ out:
|
||||
AFS_GUNLOCK();
|
||||
|
||||
crfree(credp);
|
||||
return -code;
|
||||
return afs_convert_code(code);
|
||||
}
|
||||
|
||||
#if !defined(AFS_LINUX24_ENV)
|
||||
@ -868,7 +890,7 @@ afs_linux_revalidate(struct dentry *dp)
|
||||
#endif
|
||||
crfree(credp);
|
||||
|
||||
return -code;
|
||||
return afs_convert_code(code);
|
||||
}
|
||||
|
||||
#if defined(AFS_LINUX26_ENV)
|
||||
@ -1121,7 +1143,7 @@ afs_linux_create(struct inode *dip, struct dentry *dp, int mode)
|
||||
maybe_unlock_kernel();
|
||||
#endif
|
||||
crfree(credp);
|
||||
return -code;
|
||||
return afs_convert_code(code);
|
||||
}
|
||||
|
||||
/* afs_linux_lookup */
|
||||
@ -1221,14 +1243,12 @@ afs_linux_lookup(struct inode *dip, struct dentry *dp)
|
||||
if (code == ENOENT)
|
||||
return ERR_PTR(0);
|
||||
#endif
|
||||
else if ((code >= 0) && (code <= MAX_ERRNO))
|
||||
return ERR_PTR(-code);
|
||||
else
|
||||
return ERR_PTR(-EIO);
|
||||
return ERR_PTR(afs_convert_code(code));
|
||||
#else
|
||||
if (code == ENOENT)
|
||||
code = 0;
|
||||
return -code;
|
||||
return afs_convert_code(code);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -1250,7 +1270,7 @@ afs_linux_link(struct dentry *olddp, struct inode *dip, struct dentry *newdp)
|
||||
|
||||
AFS_GUNLOCK();
|
||||
crfree(credp);
|
||||
return -code;
|
||||
return afs_convert_code(code);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -1329,7 +1349,7 @@ out:
|
||||
maybe_unlock_kernel();
|
||||
#endif
|
||||
crfree(credp);
|
||||
return -code;
|
||||
return afs_convert_code(code);
|
||||
}
|
||||
|
||||
|
||||
@ -1351,7 +1371,7 @@ afs_linux_symlink(struct inode *dip, struct dentry *dp, const char *target)
|
||||
code = afs_symlink(VTOAFS(dip), name, &vattr, target, credp);
|
||||
AFS_GUNLOCK();
|
||||
crfree(credp);
|
||||
return -code;
|
||||
return afs_convert_code(code);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -1388,7 +1408,7 @@ afs_linux_mkdir(struct inode *dip, struct dentry *dp, int mode)
|
||||
maybe_unlock_kernel();
|
||||
#endif
|
||||
crfree(credp);
|
||||
return -code;
|
||||
return afs_convert_code(code);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -1417,7 +1437,7 @@ afs_linux_rmdir(struct inode *dip, struct dentry *dp)
|
||||
}
|
||||
|
||||
crfree(credp);
|
||||
return -code;
|
||||
return afs_convert_code(code);
|
||||
}
|
||||
|
||||
|
||||
@ -1466,7 +1486,7 @@ afs_linux_rename(struct inode *oldip, struct dentry *olddp,
|
||||
#endif
|
||||
|
||||
crfree(credp);
|
||||
return -code;
|
||||
return afs_convert_code(code);
|
||||
}
|
||||
|
||||
|
||||
@ -1489,7 +1509,7 @@ afs_linux_ireadlink(struct inode *ip, char *target, int maxlen, uio_seg_t seg)
|
||||
if (!code)
|
||||
return maxlen - tuio.uio_resid;
|
||||
else
|
||||
return -code;
|
||||
return afs_convert_code(code);
|
||||
}
|
||||
|
||||
#if !defined(USABLE_KERNEL_PAGE_SYMLINK_CACHE)
|
||||
@ -1728,7 +1748,7 @@ afs_linux_readpages(struct file *fp, struct address_space *mapping,
|
||||
crfree(credp);
|
||||
|
||||
out:
|
||||
return -code;
|
||||
return afs_convert_code(code);
|
||||
}
|
||||
|
||||
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) */
|
||||
@ -1900,7 +1920,7 @@ afs_linux_readpage(struct file *fp, struct page *pp)
|
||||
|
||||
done:
|
||||
crfree(credp);
|
||||
return -code;
|
||||
return afs_convert_code(code);
|
||||
}
|
||||
|
||||
|
||||
@ -1963,7 +1983,7 @@ afs_linux_writepage_sync(struct inode *ip, struct page *pp,
|
||||
if (!afs_InitReq(&treq, credp))
|
||||
code = afs_DoPartialWrite(vcp, &treq);
|
||||
}
|
||||
code = code ? -code : count - tuio.uio_resid;
|
||||
code = code ? afs_convert_code(code) : count - tuio.uio_resid;
|
||||
|
||||
vcp->f.states &= ~CPageWrite;
|
||||
ReleaseWriteLock(&vcp->lock);
|
||||
@ -2077,7 +2097,7 @@ afs_linux_updatepage(struct file *fp, struct page *pp, unsigned long offset,
|
||||
ReleaseWriteLock(&vcp->lock);
|
||||
}
|
||||
|
||||
code = code ? -code : count - tuio.uio_resid;
|
||||
code = code ? afs_convert_code(code) : count - tuio.uio_resid;
|
||||
afs_Trace4(afs_iclSetp, CM_TRACE_UPDATEPAGE, ICL_TYPE_POINTER, vcp,
|
||||
ICL_TYPE_POINTER, pp, ICL_TYPE_INT32, page_count(pp),
|
||||
ICL_TYPE_INT32, code);
|
||||
@ -2116,7 +2136,7 @@ afs_linux_permission(struct inode *ip, int mode)
|
||||
|
||||
AFS_GUNLOCK();
|
||||
crfree(credp);
|
||||
return -code;
|
||||
return afs_convert_code(code);
|
||||
}
|
||||
|
||||
#if defined(AFS_LINUX24_ENV) && !defined(HAVE_WRITE_BEGIN)
|
||||
|
Loading…
Reference in New Issue
Block a user