"Unimplemented system call" wrong?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello,


in the kernel log, I found this message the other day:
Mar 30 10:06:30 localhost kernel: Unimplemented SPARC system call 139

Looking it up in arch/sparc64/kernel/systbls.S shows that 139 maps to 
compat_sys_stat64.

arch/sparc64/kernel/sys_sparc32.c contains a cp_compat_stat64() function 
which is called from compat_sys_stat64(); here's a little excerpt:

int cp_compat_stat64(struct kstat *stat, struct compat_stat64 __user 
*statbuf)
{
        int err;

        err  = put_user(huge_encode_dev(stat->dev), &statbuf->st_dev);
        err |= put_user(stat->ino, &statbuf->st_ino);
        err |= put_user(stat->mode, &statbuf->st_mode);
        ...
        return err;
}

I seriously doubt that put_user() can return -ENOSYS (the kernel would be 
pretty useless then). I rather think someone borked the error reporting 
here by ORing error values. Let's imagine that

  err  = put_user(huge_enc...    returns ENOENT
  err |= put_user(stat->in...    returns EINTR
  err |= put_user(stat->mo...    returns EPIPE

ENOENT/EINTR/EPIPE may be dumb for put_user too, but it shows the problem 
with |. err is now 00100110 in binary (sign omitted). ENOSYS. Although it 
should have been, preferably ENOENT (in this example case).

Here are two patches (varying in coding style) that try to resolve this issue.
There are many more places within the kernel that use the |= technique.
Any thoughts on the issue?

--- arch/sparc64/kernel/sys_sparc32.c~	2006-01-29 10:59:36.000000000 +0100
+++ arch/sparc64/kernel/sys_sparc32.c	2006-03-31 13:50:47.046525000 +0200
@@ -345,23 +345,40 @@ int cp_compat_stat(struct kstat *stat, s
 		return -EOVERFLOW;
 
 	err  = put_user(old_encode_dev(stat->dev), &statbuf->st_dev);
-	err |= put_user(stat->ino, &statbuf->st_ino);
-	err |= put_user(stat->mode, &statbuf->st_mode);
-	err |= put_user(stat->nlink, &statbuf->st_nlink);
-	err |= put_user(high2lowuid(stat->uid), &statbuf->st_uid);
-	err |= put_user(high2lowgid(stat->gid), &statbuf->st_gid);
-	err |= put_user(old_encode_dev(stat->rdev), &statbuf->st_rdev);
-	err |= put_user(stat->size, &statbuf->st_size);
-	err |= put_user(stat->atime.tv_sec, &statbuf->st_atime);
-	err |= put_user(stat->atime.tv_nsec, &statbuf->st_atime_nsec);
-	err |= put_user(stat->mtime.tv_sec, &statbuf->st_mtime);
-	err |= put_user(stat->mtime.tv_nsec, &statbuf->st_mtime_nsec);
-	err |= put_user(stat->ctime.tv_sec, &statbuf->st_ctime);
-	err |= put_user(stat->ctime.tv_nsec, &statbuf->st_ctime_nsec);
-	err |= put_user(stat->blksize, &statbuf->st_blksize);
-	err |= put_user(stat->blocks, &statbuf->st_blocks);
-	err |= put_user(0, &statbuf->__unused4[0]);
-	err |= put_user(0, &statbuf->__unused4[1]);
+        if(err != 0) return err;
+	err = put_user(stat->ino, &statbuf->st_ino);
+        if(err != 0) return err;
+	err = put_user(stat->mode, &statbuf->st_mode);
+        if(err != 0) return err;
+	err = put_user(stat->nlink, &statbuf->st_nlink);
+        if(err != 0) return err;
+	err = put_user(high2lowuid(stat->uid), &statbuf->st_uid);
+        if(err != 0) return err;
+	err = put_user(high2lowgid(stat->gid), &statbuf->st_gid);
+        if(err != 0) return err;
+	err = put_user(old_encode_dev(stat->rdev), &statbuf->st_rdev);
+        if(err != 0) return err;
+	err = put_user(stat->size, &statbuf->st_size);
+        if(err != 0) return err;
+	err = put_user(stat->atime.tv_sec, &statbuf->st_atime);
+        if(err != 0) return err;
+	err = put_user(stat->atime.tv_nsec, &statbuf->st_atime_nsec);
+        if(err != 0) return err;
+	err = put_user(stat->mtime.tv_sec, &statbuf->st_mtime);
+        if(err != 0) return err;
+	err = put_user(stat->mtime.tv_nsec, &statbuf->st_mtime_nsec);
+        if(err != 0) return err;
+	err = put_user(stat->ctime.tv_sec, &statbuf->st_ctime);
+        if(err != 0) return err;
+	err = put_user(stat->ctime.tv_nsec, &statbuf->st_ctime_nsec);
+        if(err != 0) return err;
+	err = put_user(stat->blksize, &statbuf->st_blksize);
+        if(err != 0) return err;
+	err = put_user(stat->blocks, &statbuf->st_blocks);
+        if(err != 0) return err;
+	err = put_user(0, &statbuf->__unused4[0]);
+        if(err != 0) return err;
+	err = put_user(0, &statbuf->__unused4[1]);
 
 	return err;
 }
@@ -370,27 +387,47 @@ int cp_compat_stat64(struct kstat *stat,
 {
 	int err;
 
-	err  = put_user(huge_encode_dev(stat->dev), &statbuf->st_dev);
-	err |= put_user(stat->ino, &statbuf->st_ino);
-	err |= put_user(stat->mode, &statbuf->st_mode);
-	err |= put_user(stat->nlink, &statbuf->st_nlink);
-	err |= put_user(stat->uid, &statbuf->st_uid);
-	err |= put_user(stat->gid, &statbuf->st_gid);
-	err |= put_user(huge_encode_dev(stat->rdev), &statbuf->st_rdev);
-	err |= put_user(0, (unsigned long __user *) &statbuf->__pad3[0]);
-	err |= put_user(stat->size, &statbuf->st_size);
-	err |= put_user(stat->blksize, &statbuf->st_blksize);
-	err |= put_user(0, (unsigned int __user *) &statbuf->__pad4[0]);
-	err |= put_user(0, (unsigned int __user *) &statbuf->__pad4[4]);
-	err |= put_user(stat->blocks, &statbuf->st_blocks);
-	err |= put_user(stat->atime.tv_sec, &statbuf->st_atime);
-	err |= put_user(stat->atime.tv_nsec, &statbuf->st_atime_nsec);
-	err |= put_user(stat->mtime.tv_sec, &statbuf->st_mtime);
-	err |= put_user(stat->mtime.tv_nsec, &statbuf->st_mtime_nsec);
-	err |= put_user(stat->ctime.tv_sec, &statbuf->st_ctime);
-	err |= put_user(stat->ctime.tv_nsec, &statbuf->st_ctime_nsec);
-	err |= put_user(0, &statbuf->__unused4);
-	err |= put_user(0, &statbuf->__unused5);
+	err = put_user(huge_encode_dev(stat->dev), &statbuf->st_dev);
+        if(err != 0) return err;
+	err = put_user(stat->ino, &statbuf->st_ino);
+        if(err != 0) return err;
+	err = put_user(stat->mode, &statbuf->st_mode);
+        if(err != 0) return err;
+	err = put_user(stat->nlink, &statbuf->st_nlink);
+        if(err != 0) return err;
+	err = put_user(stat->uid, &statbuf->st_uid);
+        if(err != 0) return err;
+	err = put_user(stat->gid, &statbuf->st_gid);
+        if(err != 0) return err;
+	err = put_user(huge_encode_dev(stat->rdev), &statbuf->st_rdev);
+        if(err != 0) return err;
+	err = put_user(0, (unsigned long __user *) &statbuf->__pad3[0]);
+        if(err != 0) return err;
+	err = put_user(stat->size, &statbuf->st_size);
+        if(err != 0) return err;
+	err = put_user(stat->blksize, &statbuf->st_blksize);
+        if(err != 0) return err;
+	err = put_user(0, (unsigned int __user *) &statbuf->__pad4[0]);
+        if(err != 0) return err;
+	err = put_user(0, (unsigned int __user *) &statbuf->__pad4[4]);
+        if(err != 0) return err;
+	err = put_user(stat->blocks, &statbuf->st_blocks);
+        if(err != 0) return err;
+	err = put_user(stat->atime.tv_sec, &statbuf->st_atime);
+        if(err != 0) return err;
+	err = put_user(stat->atime.tv_nsec, &statbuf->st_atime_nsec);
+        if(err != 0) return err;
+	err = put_user(stat->mtime.tv_sec, &statbuf->st_mtime);
+        if(err != 0) return err;
+	err = put_user(stat->mtime.tv_nsec, &statbuf->st_mtime_nsec);
+        if(err != 0) return err;
+	err = put_user(stat->ctime.tv_sec, &statbuf->st_ctime);
+        if(err != 0) return err;
+	err = put_user(stat->ctime.tv_nsec, &statbuf->st_ctime_nsec);
+        if(err != 0) return err;
+	err = put_user(0, &statbuf->__unused4);
+        if(err != 0) return err;
+	err = put_user(0, &statbuf->__unused5);
 
 	return err;
 }
#<<eof>>

--- arch/sparc64/kernel/sys_sparc32.c~	2006-01-29 10:59:36.000000000 +0100
+++ arch/sparc64/kernel/sys_sparc32.c	2006-03-31 13:52:24.366525000 +0200
@@ -344,24 +344,25 @@ int cp_compat_stat(struct kstat *stat, s
 	    !old_valid_dev(stat->rdev))
 		return -EOVERFLOW;
 
-	err  = put_user(old_encode_dev(stat->dev), &statbuf->st_dev);
-	err |= put_user(stat->ino, &statbuf->st_ino);
-	err |= put_user(stat->mode, &statbuf->st_mode);
-	err |= put_user(stat->nlink, &statbuf->st_nlink);
-	err |= put_user(high2lowuid(stat->uid), &statbuf->st_uid);
-	err |= put_user(high2lowgid(stat->gid), &statbuf->st_gid);
-	err |= put_user(old_encode_dev(stat->rdev), &statbuf->st_rdev);
-	err |= put_user(stat->size, &statbuf->st_size);
-	err |= put_user(stat->atime.tv_sec, &statbuf->st_atime);
-	err |= put_user(stat->atime.tv_nsec, &statbuf->st_atime_nsec);
-	err |= put_user(stat->mtime.tv_sec, &statbuf->st_mtime);
-	err |= put_user(stat->mtime.tv_nsec, &statbuf->st_mtime_nsec);
-	err |= put_user(stat->ctime.tv_sec, &statbuf->st_ctime);
-	err |= put_user(stat->ctime.tv_nsec, &statbuf->st_ctime_nsec);
-	err |= put_user(stat->blksize, &statbuf->st_blksize);
-	err |= put_user(stat->blocks, &statbuf->st_blocks);
-	err |= put_user(0, &statbuf->__unused4[0]);
-	err |= put_user(0, &statbuf->__unused4[1]);
+	if((err = put_user(old_encode_dev(stat->dev), &statbuf->st_dev)) == 0)
+	if((err = put_user(stat->ino, &statbuf->st_ino)) == 0)
+	if((err = put_user(stat->mode, &statbuf->st_mode) == 0)
+	if((err = put_user(stat->nlink, &statbuf->st_nlink) == 0)
+	if((err = put_user(high2lowuid(stat->uid), &statbuf->st_uid) == 0)
+	if((err = put_user(high2lowgid(stat->gid), &statbuf->st_gid) == 0)
+	if((err = put_user(old_encode_dev(stat->rdev), &statbuf->st_rdev) == 0)
+	if((err = put_user(stat->size, &statbuf->st_size) == 0)
+	if((err = put_user(stat->atime.tv_sec, &statbuf->st_atime) == 0)
+	if((err = put_user(stat->atime.tv_nsec, &statbuf->st_atime_nsec) == 0)
+	if((err = put_user(stat->mtime.tv_sec, &statbuf->st_mtime) == 0)
+	if((err = put_user(stat->mtime.tv_nsec, &statbuf->st_mtime_nsec) == 0)
+	if((err = put_user(stat->ctime.tv_sec, &statbuf->st_ctime) == 0)
+	if((err = put_user(stat->ctime.tv_nsec, &statbuf->st_ctime_nsec) == 0)
+	if((err = put_user(stat->blksize, &statbuf->st_blksize) == 0)
+	if((err = put_user(stat->blocks, &statbuf->st_blocks) == 0)
+	if((err = put_user(0, &statbuf->__unused4[0]) == 0)
+	if((err = put_user(0, &statbuf->__unused4[1]) == 0)
+            return 0;
 
 	return err;
 }
@@ -370,27 +371,28 @@ int cp_compat_stat64(struct kstat *stat,
 {
 	int err;
 
-	err  = put_user(huge_encode_dev(stat->dev), &statbuf->st_dev);
-	err |= put_user(stat->ino, &statbuf->st_ino);
-	err |= put_user(stat->mode, &statbuf->st_mode);
-	err |= put_user(stat->nlink, &statbuf->st_nlink);
-	err |= put_user(stat->uid, &statbuf->st_uid);
-	err |= put_user(stat->gid, &statbuf->st_gid);
-	err |= put_user(huge_encode_dev(stat->rdev), &statbuf->st_rdev);
-	err |= put_user(0, (unsigned long __user *) &statbuf->__pad3[0]);
-	err |= put_user(stat->size, &statbuf->st_size);
-	err |= put_user(stat->blksize, &statbuf->st_blksize);
-	err |= put_user(0, (unsigned int __user *) &statbuf->__pad4[0]);
-	err |= put_user(0, (unsigned int __user *) &statbuf->__pad4[4]);
-	err |= put_user(stat->blocks, &statbuf->st_blocks);
-	err |= put_user(stat->atime.tv_sec, &statbuf->st_atime);
-	err |= put_user(stat->atime.tv_nsec, &statbuf->st_atime_nsec);
-	err |= put_user(stat->mtime.tv_sec, &statbuf->st_mtime);
-	err |= put_user(stat->mtime.tv_nsec, &statbuf->st_mtime_nsec);
-	err |= put_user(stat->ctime.tv_sec, &statbuf->st_ctime);
-	err |= put_user(stat->ctime.tv_nsec, &statbuf->st_ctime_nsec);
-	err |= put_user(0, &statbuf->__unused4);
-	err |= put_user(0, &statbuf->__unused5);
+	if((err = put_user(huge_encode_dev(stat->dev), &statbuf->st_dev) == 0)
+	if((err = put_user(stat->ino, &statbuf->st_ino) == 0)
+	if((err = put_user(stat->mode, &statbuf->st_mode) == 0)
+	if((err = put_user(stat->nlink, &statbuf->st_nlink) == 0)
+	if((err = put_user(stat->uid, &statbuf->st_uid) == 0)
+	if((err = put_user(stat->gid, &statbuf->st_gid) == 0)
+	if((err = put_user(huge_encode_dev(stat->rdev), &statbuf->st_rdev) == 0)
+	if((err = put_user(0, (unsigned long __user *) &statbuf->__pad3[0]) == 0)
+	if((err = put_user(stat->size, &statbuf->st_size) == 0)
+	if((err = put_user(stat->blksize, &statbuf->st_blksize) == 0)
+	if((err = put_user(0, (unsigned int __user *) &statbuf->__pad4[0]) == 0)
+	if((err = put_user(0, (unsigned int __user *) &statbuf->__pad4[4]) == 0)
+	if((err = put_user(stat->blocks, &statbuf->st_blocks) == 0)
+	if((err = put_user(stat->atime.tv_sec, &statbuf->st_atime) == 0)
+	if((err = put_user(stat->atime.tv_nsec, &statbuf->st_atime_nsec) == 0)
+	if((err = put_user(stat->mtime.tv_sec, &statbuf->st_mtime) == 0)
+	if((err = put_user(stat->mtime.tv_nsec, &statbuf->st_mtime_nsec) == 0)
+	if((err = put_user(stat->ctime.tv_sec, &statbuf->st_ctime) == 0)
+	if((err = put_user(stat->ctime.tv_nsec, &statbuf->st_ctime_nsec) == 0)
+	if((err = put_user(0, &statbuf->__unused4) == 0)
+	if((err = put_user(0, &statbuf->__unused5) == 0)
+            return 0;
 
 	return err;
 }
#<<eof>>

Jan Engelhardt
-- 
| Software Engineer and Linux/Unix Network Administrator
| Alphagate Systems, http://alphagate.hopto.org/
| jengelh's site, http://jengelh.hopto.org/
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux