pioctl-return-negative-errors-on-linux-20030522
[openafs.git] / src / afs / afs_pioctl.c
index a344e1f..230ad5e 100644 (file)
@@ -234,11 +234,13 @@ copyin_afs_ioctl(caddr_t cmarg, struct afs_ioctl *dst)
 
 #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)
@@ -371,7 +373,6 @@ afs_ioctl(OSI_VN_DECL(tvc), int cmd, void * arg, int flag, cred_t *cr, rval_t *r
 }
 #endif /* AFS_SGI_ENV */
 
-
 /* unlike most calls here, this one uses u.u_error to return error conditions,
    since this is really an intercepted chapter 2 call, rather than a vnode
    interface call.
@@ -381,7 +382,11 @@ afs_ioctl(OSI_VN_DECL(tvc), int cmd, void * arg, int flag, cred_t *cr, rval_t *r
 #if !defined(AFS_SGI_ENV)
 #ifdef AFS_AIX32_ENV
 #ifdef AFS_AIX51_ENV
+#ifdef __64BIT__
 kioctl(fdes, com, arg, ext, arg2, arg3)
+#else /* __64BIT__ */
+kioctl32(fdes, com, arg, ext, arg2, arg3)
+#endif /* __64BIT__ */
      caddr_t arg2, arg3;
 #else
 kioctl(fdes, com, arg, ext)
@@ -614,12 +619,16 @@ int afs_xioctl (void)
 #ifdef AFS_AIX41_ENV
        ufdrele(uap->fd);
 #ifdef AFS_AIX51_ENV
+#ifdef __64BIT__
        code = okioctl(fdes, com, arg, ext, arg2, arg3);
-#else
+#else /* __64BIT__ */
+       code = okioctl32(fdes, com, arg, ext, arg2, arg3);
+#endif /* __64BIT__ */
+#else /* !AFS_AIX51_ENV */
        code = okioctl(fdes, com, arg, ext);
-#endif
+#endif /* AFS_AIX51_ENV */
        return code;
-#else
+#else /* !AFS_AIX41_ENV */
 #ifdef AFS_AIX32_ENV
        okioctl(fdes, com, arg, ext);
 #elif defined(AFS_SUN5_ENV)
@@ -704,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;
@@ -723,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;
@@ -742,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. */
@@ -989,6 +1012,9 @@ afs_syscall_pioctl(path, com, cmarg, follow)
 #endif
     }
     PIOCTL_FREE_CRED();
+#ifdef AFS_LINUX22_ENV
+    return -code;
+#else
 #if defined(KERNEL_HAVE_UERROR)
     if (!getuerror())
        setuerror(code);
@@ -996,6 +1022,7 @@ afs_syscall_pioctl(path, com, cmarg, follow)
 #else
     return (code);
 #endif
+#endif
 }
 
 
@@ -1045,7 +1072,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);