revert-pioctl-return-negative-errors-on-linux-20030522
[openafs.git] / src / afs / afs_pioctl.c
index cf2a44a..f9120ca 100644 (file)
@@ -229,16 +229,18 @@ copyin_afs_ioctl(caddr_t cmarg, struct afs_ioctl *dst)
        }
 #endif /* defined(AFS_SGI_ENV) && (_MIPS_SZLONG==64) */
 
-#if defined(AFS_LINUX_64BIT_KERNEL) && !defined(AFS_ALPHA_LINUX20_ENV) && !defined(AFS_IA64_LINUX20_ENV) && !defined(AFS_AMD64_LINUX20_ENV)
+#if defined(AFS_LINUX_64BIT_KERNEL) && !defined(AFS_ALPHA_LINUX20_ENV) && !defined(AFS_IA64_LINUX20_ENV)
        struct afs_ioctl32 dst32;
 
 #ifdef AFS_SPARC64_LINUX24_ENV
         if (current->thread.flags & SPARC_FLAG_32BIT)
-#elif AFS_SPARC64_LINUX20_ENV
+#elif defined(AFS_SPARC64_LINUX20_ENV)
        if (current->tss.flags & SPARC_FLAG_32BIT)
+#elif defined(AFS_AMD64_LINUX20_ENV)
+        if (current->thread.flags & THREAD_IA32)
 #else
 #error Not done for this linux type
-#endif /* AFS_SPARC64_LINUX20_ENV */
+#endif
          {
                AFS_COPYIN(cmarg, (caddr_t) &dst32, sizeof dst32, code);
                if (!code)
@@ -711,9 +713,8 @@ afs_pioctl(struct pioctlargs *uap, rval_t *rvp)
     return u.u_error;
 #endif
 }
-#endif /* AFS_SGI_ENV */
 
-#ifdef AFS_OSF_ENV
+#elif defined(AFS_OSF_ENV)
 afs_pioctl(p, args, retval)
         struct proc *p;
         void *args;
@@ -730,8 +731,25 @@ afs_pioctl(p, args, retval)
     return (afs_syscall_pioctl(uap->path, uap->cmd, uap->cmarg, uap->follow));
 }
 
-#else  /* AFS_OSF_ENV */
-#if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
+#elif defined(AFS_FBSD50_ENV)
+int
+afs_pioctl(td, args, retval)
+        struct thread *td;
+        void *args;
+        int *retval;
+{
+    struct a {
+        char    *path;
+        int     cmd;
+        caddr_t cmarg;
+        int     follow;
+    } *uap = (struct a *) args;
+
+    AFS_STATCNT(afs_pioctl);
+    return (afs_syscall_pioctl(uap->path, uap->cmd, uap->cmarg, uap->follow, td->td_ucred));
+}
+
+#elif defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
 int
 afs_pioctl(p, args, retval)
         struct proc *p;
@@ -749,8 +767,6 @@ afs_pioctl(p, args, retval)
     return (afs_syscall_pioctl(uap->path, uap->cmd, uap->cmarg, uap->follow, p->p_cred->pc_ucred));
 }
 
-#else   /* AFS_OSF_ENV */
-#endif
 #endif
 
 /* macro to avoid adding any more #ifdef's to pioctl code. */
@@ -1052,7 +1068,11 @@ int afs_HandlePioctl(struct vnode *avp, afs_int32 acom,
        return EINVAL;          /* out of range */
     }
     inSize = ablob->in_size;
-    if (inSize >= PIGGYSIZE) return E2BIG;
+
+    /* Do all range checking before continuing */
+    if (inSize >= PIGGYSIZE || inSize < 0 || ablob->out_size < 0)
+       return E2BIG;
+
     inData = osi_AllocLargeSpace(AFS_LRALLOCSIZ);
     if (inSize > 0) {
        AFS_COPYIN(ablob->in, inData, inSize, code);