Re: Fix netbsd32's getfh()

2014-06-28 Thread Maxime Villard
Le 26/06/2014 20:46, Christos Zoulas a écrit :
 On Jun 26,  4:30pm, m...@m00nbsd.net (Maxime Villard) wrote:
 -- Subject: Re: Fix netbsd32's getfh()
 
 | I guess it's ok now?
 
 Yes, that looks fine. But why:
   if (error != 0)
 instead of:
   if (error)
 
 I think that most code in the tree uses the second form.

But the native code doesn't. Anyway, I've committed the fix.
Thanks.


Re: Fix netbsd32's getfh()

2014-06-26 Thread Maxime Villard
Le 26/06/2014 04:04, Christos Zoulas a écrit :
 On Jun 26, 11:30am, m...@eterna.com.au (matthew green) wrote:
 -- Subject: re: Fix netbsd32's getfh()
 
 | 
 | Christos Zoulas writes:
 |  Well, let's not propagate the evil design! I is is one thing having:
 |  
 |void *p = malloc(n);
 |free(p);
 |  
 |  where you know p is going to be NULL when it fails and another having:
 |  
 |foo *p;
 |error = allocate_foo(p);
 |free_foo(p);
 |  
 |  and expect p to be altered in the error path of allocate_foo.
 |  
 |  Please, let's fix it! I volunteer :-)
 | 
 | *tag*  you're it!
 
 Done.
 
 christos
 

I guess it's ok now?

Index: netbsd32_netbsd.c
===
RCS file: /cvsroot/src/sys/compat/netbsd32/netbsd32_netbsd.c,v
retrieving revision 1.190
diff -u -r1.190 netbsd32_netbsd.c
--- netbsd32_netbsd.c   22 Jun 2014 19:09:39 -  1.190
+++ netbsd32_netbsd.c   26 Jun 2014 14:21:24 -
@@ -1302,7 +1302,7 @@
int error;
struct pathbuf *pb;
struct nameidata nd;
-   netbsd32_size_t sz32;
+   netbsd32_size_t usz32, sz32;
size_t sz;
 
/*
@@ -1312,7 +1312,6 @@
0, NULL, NULL, NULL);
if (error)
return (error);
-   fh = NULL;
 
error = pathbuf_copyin(SCARG_P32(uap, fname), pb);
if (error) {
@@ -1328,30 +1327,29 @@
vp = nd.ni_vp;
pathbuf_destroy(pb);
 
-   error = copyin(SCARG_P32(uap, fh_size), sz32,
-   sizeof(netbsd32_size_t));
-   if (error) {
-   vput(vp);
+   error = vfs_composefh_alloc(vp, fh);
+   vput(vp);
+   if (error != 0) {
return error;
}
-   fh = kmem_alloc(sz32, KM_SLEEP);
-   if (fh == NULL) 
-   return EINVAL;
-   sz = sz32;
-   error = vfs_composefh(vp, fh, sz);
-   vput(vp);
+   error = copyin(SCARG_P32(uap, fh_size), usz32, sizeof(usz32));
+   if (error != 0) {
+   goto out;
+   }
+   sz = FHANDLE_SIZE(fh);
+   sz32 = sz;
 
-   if (error == 0) {
-   const netbsd32_size_t nsz32 = sz;
-   error = copyout(nsz32, SCARG_P32(uap, fh_size),
-   sizeof(netbsd32_size_t));
-   if (!error) {
-   error = copyout(fh, SCARG_P32(uap, fhp), sz);
-   }
-   } else if (error == E2BIG) {
-   error = copyout(sz, SCARG_P32(uap, fh_size), sizeof(size_t));
+   error = copyout(sz32, SCARG_P32(uap, fh_size), sizeof(sz32));
+   if (error != 0) {
+   goto out;
+   }
+   if (usz32 = sz32) {
+   error = copyout(fh, SCARG_P32(uap, fhp), sz);
+   } else {
+   error = E2BIG;
}
-   kmem_free(fh, sz32);
+out:
+   vfs_composefh_free(fh);
return (error);
 }
 


Re: Fix netbsd32's getfh()

2014-06-26 Thread Christos Zoulas
On Jun 26,  4:30pm, m...@m00nbsd.net (Maxime Villard) wrote:
-- Subject: Re: Fix netbsd32's getfh()

| I guess it's ok now?

Yes, that looks fine. But why:
if (error != 0)
instead of:
if (error)

I think that most code in the tree uses the second form.

christos
| 
| Index: netbsd32_netbsd.c
| ===
| RCS file: /cvsroot/src/sys/compat/netbsd32/netbsd32_netbsd.c,v
| retrieving revision 1.190
| diff -u -r1.190 netbsd32_netbsd.c
| --- netbsd32_netbsd.c 22 Jun 2014 19:09:39 -  1.190
| +++ netbsd32_netbsd.c 26 Jun 2014 14:21:24 -
| @@ -1302,7 +1302,7 @@
|   int error;
|   struct pathbuf *pb;
|   struct nameidata nd;
| - netbsd32_size_t sz32;
| + netbsd32_size_t usz32, sz32;
|   size_t sz;
|  
|   /*
| @@ -1312,7 +1312,6 @@
|   0, NULL, NULL, NULL);
|   if (error)
|   return (error);
| - fh = NULL;
|  
|   error = pathbuf_copyin(SCARG_P32(uap, fname), pb);
|   if (error) {
| @@ -1328,30 +1327,29 @@
|   vp = nd.ni_vp;
|   pathbuf_destroy(pb);
|  
| - error = copyin(SCARG_P32(uap, fh_size), sz32,
| - sizeof(netbsd32_size_t));
| - if (error) {
| - vput(vp);
| + error = vfs_composefh_alloc(vp, fh);
| + vput(vp);
| + if (error != 0) {
|   return error;
|   }
| - fh = kmem_alloc(sz32, KM_SLEEP);
| - if (fh == NULL) 
| - return EINVAL;
| - sz = sz32;
| - error = vfs_composefh(vp, fh, sz);
| - vput(vp);
| + error = copyin(SCARG_P32(uap, fh_size), usz32, sizeof(usz32));
| + if (error != 0) {
| + goto out;
| + }
| + sz = FHANDLE_SIZE(fh);
| + sz32 = sz;
|  
| - if (error == 0) {
| - const netbsd32_size_t nsz32 = sz;
| - error = copyout(nsz32, SCARG_P32(uap, fh_size),
| - sizeof(netbsd32_size_t));
| - if (!error) {
| - error = copyout(fh, SCARG_P32(uap, fhp), sz);
| - }
| - } else if (error == E2BIG) {
| - error = copyout(sz, SCARG_P32(uap, fh_size), sizeof(size_t));
| + error = copyout(sz32, SCARG_P32(uap, fh_size), sizeof(sz32));
| + if (error != 0) {
| + goto out;
| + }
| + if (usz32 = sz32) {
| + error = copyout(fh, SCARG_P32(uap, fhp), sz);
| + } else {
| + error = E2BIG;
|   }
| - kmem_free(fh, sz32);
| +out:
| + vfs_composefh_free(fh);
|   return (error);
|  }
|  
-- End of excerpt from Maxime Villard




Re: Fix netbsd32's getfh()

2014-06-25 Thread Christos Zoulas
In article 53aa91a3.1070...@m00nbsd.net,
Maxime Villard  m...@m00nbsd.net wrote:
Hi,
Here is a patch to sync netbsd32 with the native getfh() syscall. In addition
to making it consistent, it also:

a) fixes the return value:
   } else if (error == E2BIG) {
   error = copyout(sz, SCARG_P32(uap, fh_size), 
 sizeof(size_t));
   }
   here the error code is overwritten by copyout(), so it won't ever return
   E2BIG

b) fixes a leak:
   if (fh == NULL) 
   return EINVAL;
   a vput(vp) is missing here

c) fixes a user-controlled allocation:
   fh = kmem_alloc(sz32, KM_SLEEP);

I would like some ok's before committing it. Tested on NetBSD-current/amd64.

Thanks.


Index: netbsd32_netbsd.c
===
RCS file: /cvsroot/src/sys/compat/netbsd32/netbsd32_netbsd.c,v
retrieving revision 1.190
diff -u -r1.190 netbsd32_netbsd.c
--- netbsd32_netbsd.c  22 Jun 2014 19:09:39 -  1.190
+++ netbsd32_netbsd.c  25 Jun 2014 07:21:23 -
@@ -1302,7 +1302,7 @@
   int error;
   struct pathbuf *pb;
   struct nameidata nd;
-  netbsd32_size_t sz32;
+  netbsd32_size_t usz32, sz32;
   size_t sz;
 
   /*
@@ -1312,7 +1312,6 @@
   0, NULL, NULL, NULL);
   if (error)
   return (error);
-  fh = NULL;
 
   error = pathbuf_copyin(SCARG_P32(uap, fname), pb);
   if (error) {
@@ -1328,30 +1327,31 @@
   vp = nd.ni_vp;
   pathbuf_destroy(pb);
 
-  error = copyin(SCARG_P32(uap, fh_size), sz32,
+  error = vfs_composefh_alloc(vp, fh);
+  vput(vp);
+  if (error != 0) {
+  goto out;

That should probably be:

return error;

since vfs_composefh_alloc() failed, and we should not be calling 
vfs_composefh_free().

+  }
+  error = copyin(SCARG_P32(uap, fh_size), usz32,
   sizeof(netbsd32_size_t));

I would change sizeof(netbsd32_size_t) sizeof(usz32), that makes it
fit on one line too :-)

-  if (error) {
-  vput(vp);
-  return error;
+  if (error != 0) {
+  goto out;
   }
-  fh = kmem_alloc(sz32, KM_SLEEP);
-  if (fh == NULL) 
-  return EINVAL;
-  sz = sz32;
-  error = vfs_composefh(vp, fh, sz);
-  vput(vp);
+  sz = FHANDLE_SIZE(fh);
+  sz32 = sz;
 
-  if (error == 0) {
-  const netbsd32_size_t nsz32 = sz;
-  error = copyout(nsz32, SCARG_P32(uap, fh_size),
-  sizeof(netbsd32_size_t));
-  if (!error) {
-  error = copyout(fh, SCARG_P32(uap, fhp), sz);
-  }
-  } else if (error == E2BIG) {
-  error = copyout(sz, SCARG_P32(uap, fh_size), sizeof(size_t));
+  error = copyout(sz32, SCARG_P32(uap, fh_size),
+  sizeof(netbsd32_size_t));

Again perhaps sizeof(sz32)...

christos

+  if (error != 0) {
+  goto out;
+  }
+  if (usz32 = sz32) {
+  error = copyout(fh, SCARG_P32(uap, fhp), sz);
+  } else {
+  error = E2BIG;
   }
-  kmem_free(fh, sz32);
+out:
+  vfs_composefh_free(fh);
   return (error);
 }
 






Re: Fix netbsd32's getfh()

2014-06-25 Thread Maxime Villard
Le 25/06/2014 17:28, Christos Zoulas a écrit :
 In article 53aa91a3.1070...@m00nbsd.net,
 Maxime Villard  m...@m00nbsd.net wrote:
 Hi,
 Here is a patch to sync netbsd32 with the native getfh() syscall. In addition
 to making it consistent, it also:

 a) fixes the return value:
  } else if (error == E2BIG) {
  error = copyout(sz, SCARG_P32(uap, fh_size), 
 sizeof(size_t));
  }
   here the error code is overwritten by copyout(), so it won't ever return
   E2BIG

 b) fixes a leak:
  if (fh == NULL) 
  return EINVAL;
   a vput(vp) is missing here

 c) fixes a user-controlled allocation:
  fh = kmem_alloc(sz32, KM_SLEEP);

 I would like some ok's before committing it. Tested on NetBSD-current/amd64.

 Thanks.


 Index: netbsd32_netbsd.c
 ===
 RCS file: /cvsroot/src/sys/compat/netbsd32/netbsd32_netbsd.c,v
 retrieving revision 1.190
 diff -u -r1.190 netbsd32_netbsd.c
 --- netbsd32_netbsd.c22 Jun 2014 19:09:39 -  1.190
 +++ netbsd32_netbsd.c25 Jun 2014 07:21:23 -
 @@ -1302,7 +1302,7 @@
  int error;
  struct pathbuf *pb;
  struct nameidata nd;
 -netbsd32_size_t sz32;
 +netbsd32_size_t usz32, sz32;
  size_t sz;

  /*
 @@ -1312,7 +1312,6 @@
  0, NULL, NULL, NULL);
  if (error)
  return (error);
 -fh = NULL;

  error = pathbuf_copyin(SCARG_P32(uap, fname), pb);
  if (error) {
 @@ -1328,30 +1327,31 @@
  vp = nd.ni_vp;
  pathbuf_destroy(pb);

 -error = copyin(SCARG_P32(uap, fh_size), sz32,
 +error = vfs_composefh_alloc(vp, fh);
 +vput(vp);
 +if (error != 0) {
 +goto out;
 
 That should probably be:
 
   return error;
 
 since vfs_composefh_alloc() failed, and we should not be calling 
 vfs_composefh_free().

Yes, but no. Actually, vfs_composefh_free() handles NULL correctly,
and that's what the native code does. I know it's an evil design.

 
 +}
 +error = copyin(SCARG_P32(uap, fh_size), usz32,
  sizeof(netbsd32_size_t));
 
 I would change sizeof(netbsd32_size_t) sizeof(usz32), that makes it
 fit on one line too :-)

Yep

 
 [...]
 


Index: netbsd32_netbsd.c
===
RCS file: /cvsroot/src/sys/compat/netbsd32/netbsd32_netbsd.c,v
retrieving revision 1.190
diff -u -r1.190 netbsd32_netbsd.c
--- netbsd32_netbsd.c   22 Jun 2014 19:09:39 -  1.190
+++ netbsd32_netbsd.c   25 Jun 2014 17:11:15 -
@@ -1302,7 +1302,7 @@
int error;
struct pathbuf *pb;
struct nameidata nd;
-   netbsd32_size_t sz32;
+   netbsd32_size_t usz32, sz32;
size_t sz;
 
/*
@@ -1312,7 +1312,6 @@
0, NULL, NULL, NULL);
if (error)
return (error);
-   fh = NULL;
 
error = pathbuf_copyin(SCARG_P32(uap, fname), pb);
if (error) {
@@ -1328,30 +1327,29 @@
vp = nd.ni_vp;
pathbuf_destroy(pb);
 
-   error = copyin(SCARG_P32(uap, fh_size), sz32,
-   sizeof(netbsd32_size_t));
-   if (error) {
-   vput(vp);
-   return error;
-   }
-   fh = kmem_alloc(sz32, KM_SLEEP);
-   if (fh == NULL) 
-   return EINVAL;
-   sz = sz32;
-   error = vfs_composefh(vp, fh, sz);
+   error = vfs_composefh_alloc(vp, fh);
vput(vp);
+   if (error != 0) {
+   goto out;
+   }
+   error = copyin(SCARG_P32(uap, fh_size), usz32, sizeof(usz32));
+   if (error != 0) {
+   goto out;
+   }
+   sz = FHANDLE_SIZE(fh);
+   sz32 = sz;
 
-   if (error == 0) {
-   const netbsd32_size_t nsz32 = sz;
-   error = copyout(nsz32, SCARG_P32(uap, fh_size),
-   sizeof(netbsd32_size_t));
-   if (!error) {
-   error = copyout(fh, SCARG_P32(uap, fhp), sz);
-   }
-   } else if (error == E2BIG) {
-   error = copyout(sz, SCARG_P32(uap, fh_size), sizeof(size_t));
+   error = copyout(sz32, SCARG_P32(uap, fh_size), sizeof(sz32));
+   if (error != 0) {
+   goto out;
+   }
+   if (usz32 = sz32) {
+   error = copyout(fh, SCARG_P32(uap, fhp), sz);
+   } else {
+   error = E2BIG;
}
-   kmem_free(fh, sz32);
+out:
+   vfs_composefh_free(fh);
return (error);
 }
 


Re: Fix netbsd32's getfh()

2014-06-25 Thread Christos Zoulas
In article 53ab0471.4080...@m00nbsd.net,
Maxime Villard  m...@m00nbsd.net wrote:
 
 That should probably be:
 
  return error;
 
 since vfs_composefh_alloc() failed, and we should not be calling 
 vfs_composefh_free().

Yes, but no. Actually, vfs_composefh_free() handles NULL correctly,
and that's what the native code does. I know it's an evil design.

Well, let's not propagate the evil design! I is is one thing having:

void *p = malloc(n);
free(p);

where you know p is going to be NULL when it fails and another having:

foo *p;
error = allocate_foo(p);
free_foo(p);

and expect p to be altered in the error path of allocate_foo.

Please, let's fix it! I volunteer :-)

christos



re: Fix netbsd32's getfh()

2014-06-25 Thread matthew green

Christos Zoulas writes:
 Well, let's not propagate the evil design! I is is one thing having:
 
   void *p = malloc(n);
   free(p);
 
 where you know p is going to be NULL when it fails and another having:
 
   foo *p;
   error = allocate_foo(p);
   free_foo(p);
 
 and expect p to be altered in the error path of allocate_foo.
 
 Please, let's fix it! I volunteer :-)

*tag*  you're it!


re: Fix netbsd32's getfh()

2014-06-25 Thread Christos Zoulas
On Jun 26, 11:30am, m...@eterna.com.au (matthew green) wrote:
-- Subject: re: Fix netbsd32's getfh()

| 
| Christos Zoulas writes:
|  Well, let's not propagate the evil design! I is is one thing having:
|  
|  void *p = malloc(n);
|  free(p);
|  
|  where you know p is going to be NULL when it fails and another having:
|  
|  foo *p;
|  error = allocate_foo(p);
|  free_foo(p);
|  
|  and expect p to be altered in the error path of allocate_foo.
|  
|  Please, let's fix it! I volunteer :-)
| 
| *tag*  you're it!

Done.

christos