]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
Avoid converting more negative errors into invalid pointers
authorRuss Allbery <rra@debian.org>
Tue, 7 Jul 2009 02:27:28 +0000 (19:27 -0700)
committerRuss Allbery <rra@debian.org>
Tue, 7 Jul 2009 02:27:28 +0000 (19:27 -0700)
* Apply upstream patch to avoid converting more negative errors into
  invalid kernel memory pointers.

debian/changelog
src/afs/LINUX/osi_vnodeops.c

index 20a72ebafcf260c4fcf6f90baf243cce4d47fab6..6a8bed80dd0afe6c4ef8c131fac85b2f3136b1c9 100644 (file)
@@ -1,3 +1,10 @@
+openafs (1.4.7.dfsg1-6+lenny2) UNRELEASED; urgency=low
+
+  * Apply upstream patch to avoid converting more negative errors into
+    invalid kernel memory pointers.
+
+ -- Russ Allbery <rra@debian.org>  Mon, 06 Jul 2009 19:27:22 -0700
+
 openafs (1.4.7.dfsg1-6+lenny1) stable-security; urgency=high
 
   * Apply upstream security patches from 1.4.9:
index 7a0af650ede6444fe1fefbb4bffc35c757a47947..ed4354ee2313f82eb3cf5377b46d76597a9183b2 100644 (file)
@@ -56,6 +56,22 @@ RCSID
 extern struct vcache *afs_globalVp;
 
 
+
+/* 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)
 {
@@ -75,7 +91,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 {
            osi_FlushPages(vcp, credp); /* ensure stale pages are gone */
            AFS_GUNLOCK();
@@ -125,7 +141,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
@@ -180,19 +196,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);
@@ -373,7 +395,7 @@ out:
     return code;
 
 out_err:
-    code = -code;
+    code = afs_convert_code(code);
     goto out;
 }
 
@@ -395,7 +417,7 @@ afs_linux_open(struct inode *ip, struct file *fp)
 #endif
 
     crfree(credp);
-    return -code;
+    return afs_convert_code(code);
 }
 
 static int
@@ -416,7 +438,7 @@ afs_linux_release(struct inode *ip, struct file *fp)
 #endif
 
     crfree(credp);
-    return -code;
+    return afs_convert_code(code);
 }
 
 static int
@@ -440,7 +462,7 @@ afs_linux_fsync(struct file *fp, struct dentry *dp)
     unlock_kernel();
 #endif
     crfree(credp);
-    return -code;
+    return afs_convert_code(code);
 
 }
 
@@ -500,7 +522,7 @@ afs_linux_lock(struct file *fp, int cmd, struct file_lock *flp)
     flp->fl_end = flock.l_start + flock.l_len;
 
     crfree(credp);
-    return -code;
+    return afs_convert_code(code);
 
 }
 
@@ -599,7 +621,7 @@ out:
     AFS_GUNLOCK();
 
     crfree(credp);
-    return -code;
+    return afs_convert_code(code);
 }
 
 #if !defined(AFS_LINUX24_ENV)
@@ -756,7 +778,7 @@ afs_linux_revalidate(struct dentry *dp)
 #endif
     crfree(credp);
 
-    return -code;
+    return afs_convert_code(code);
 }
 
 #if defined(AFS_LINUX26_ENV)
@@ -981,7 +1003,7 @@ afs_linux_create(struct inode *dip, struct dentry *dp, int mode)
     unlock_kernel();
 #endif
     crfree(credp);
-    return -code;
+    return afs_convert_code(code);
 }
 
 /* afs_linux_lookup */
@@ -1055,14 +1077,12 @@ 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 if ((code >= 0) && (code <= MAX_ERRNO))
-       return ERR_PTR(-code);
-    else 
-       return ERR_PTR(-EIO);
+    else
+       return ERR_PTR(afs_convert_code(code));
 #else
     if (code == ENOENT)
        code = 0;
-    return -code;
+    return afs_convert_code(code);
 #endif
 }
 
@@ -1084,7 +1104,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
@@ -1164,7 +1184,7 @@ out:
     unlock_kernel();
 #endif
     crfree(credp);
-    return -code;
+    return afs_convert_code(code);
 }
 
 
@@ -1186,7 +1206,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
@@ -1223,7 +1243,7 @@ afs_linux_mkdir(struct inode *dip, struct dentry *dp, int mode)
     unlock_kernel();
 #endif
     crfree(credp);
-    return -code;
+    return afs_convert_code(code);
 }
 
 static int
@@ -1252,7 +1272,7 @@ afs_linux_rmdir(struct inode *dip, struct dentry *dp)
     }
 
     crfree(credp);
-    return -code;
+    return afs_convert_code(code);
 }
 
 
@@ -1304,7 +1324,7 @@ afs_linux_rename(struct inode *oldip, struct dentry *olddp,
 #endif
 
     crfree(credp);
-    return -code;
+    return afs_convert_code(code);
 }
 
 
@@ -1327,7 +1347,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)
@@ -1506,7 +1526,7 @@ afs_linux_readpage(struct file *fp, struct page *pp)
     }
 
     crfree(credp);
-    return -code;
+    return afs_convert_code(code);
 }
 
 
@@ -1549,7 +1569,7 @@ afs_linux_writepage_sync(struct inode *ip, struct page *pp,
            code = afs_DoPartialWrite(vcp, &treq);
        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),
@@ -1654,7 +1674,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);
@@ -1692,7 +1712,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)