aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2012-05-10 13:26:40 -0700
committerRoland McGrath <roland@hack.frob.com>2012-05-10 15:57:23 -0700
commit6753048948b86f3b045710f77e1616b348562fa9 (patch)
tree8326ae5092ddb035ad2aa29d7bf79f4a87e09772
parent18bad2ae1bd1797782d51231d24f7b773c2bfff6 (diff)
downloadglibc-6753048948b86f3b045710f77e1616b348562fa9.tar
glibc-6753048948b86f3b045710f77e1616b348562fa9.tar.gz
glibc-6753048948b86f3b045710f77e1616b348562fa9.tar.bz2
glibc-6753048948b86f3b045710f77e1616b348562fa9.zip
Hurd: ioctl() incorrectly decodes argument
-rw-r--r--ChangeLog6
-rw-r--r--sysdeps/mach/hurd/bits/ioctls.h3
-rw-r--r--sysdeps/mach/hurd/ioctl.c21
3 files changed, 20 insertions, 10 deletions
diff --git a/ChangeLog b/ChangeLog
index e3995421a6..b373406c03 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2012-05-10 Samuel Thibault <samuel.thibault@ens-lyon.org>
+
+ * sysdeps/mach/hurd/bits/ioctls.h (_IOIW): New macro for
+ immediate-write ioctls.
+ * sysdeps/mach/hurd/ioctl.c: Handle cases with no arguments.
+
2012-05-10 Thomas Schwinge <thomas@schwinge.name>
* sysdeps/mach/hurd/i386/init-first.c (init): Use
diff --git a/sysdeps/mach/hurd/bits/ioctls.h b/sysdeps/mach/hurd/bits/ioctls.h
index 65f2ec1dd0..c4cfce65a3 100644
--- a/sysdeps/mach/hurd/bits/ioctls.h
+++ b/sysdeps/mach/hurd/bits/ioctls.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992,93,96,97,98,99,2001,2007 Free Software Foundation, Inc.
+/* Copyright (C) 1992-2012 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -157,6 +157,7 @@ enum __ioctl_datum { IOC_8, IOC_16, IOC_32, IOC_64 };
_IOT_foobar is defined either in this file,
or where struct foobar is defined. */
#define _IO(g, n) _IOC (IOC_VOID, (g), (n), 0)
+#define _IOIW(g, n, t) _IOC (IOC_VOID, (g), (n), _IOC_ENCODE_TYPE (t))
#define _IOR(g, n, t) _IOC (IOC_OUT, (g), (n), _IOC_ENCODE_TYPE (t))
#define _IOW(g, n, t) _IOC (IOC_IN, (g), (n), _IOC_ENCODE_TYPE (t))
#define _IOWR(g, n, t) _IOC (IOC_INOUT, (g), (n), _IOC_ENCODE_TYPE (t))
diff --git a/sysdeps/mach/hurd/ioctl.c b/sysdeps/mach/hurd/ioctl.c
index beffe4365e..543d437c1e 100644
--- a/sysdeps/mach/hurd/ioctl.c
+++ b/sysdeps/mach/hurd/ioctl.c
@@ -1,5 +1,4 @@
-/* Copyright (C) 1992,93,94,95,96,97,99,2000,2002,2005
- Free Software Foundation, Inc.
+/* Copyright (C) 1992-2012 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -88,7 +87,7 @@ __ioctl (int fd, unsigned long int request, ...)
void *p;
#endif
- void *arg;
+ void *arg = NULL;
error_t err;
@@ -111,7 +110,7 @@ __ioctl (int fd, unsigned long int request, ...)
if (_IOC_INOUT (request) & IOC_IN)
{
/* We don't want to advance ARG since it will be used to copy out
- too if IOC_OUT is also set. */
+ too if IOC_OUT is also set. */
void *argptr = arg;
/* Pack an argument into the message buffer. */
@@ -139,7 +138,7 @@ __ioctl (int fd, unsigned long int request, ...)
in (_IOT_COUNT1 (type), _IOT_TYPE1 (type));
in (_IOT_COUNT2 (type), _IOT_TYPE2 (type));
}
- else if (_IOC_INOUT (request) == IOC_VOID)
+ else if (_IOC_INOUT (request) == IOC_VOID && _IOT_COUNT0 (type) != 0)
{
/* The RPC takes a single integer_t argument.
Rather than pointing to the value, ARG is the value itself. */
@@ -208,11 +207,15 @@ __ioctl (int fd, unsigned long int request, ...)
return msg.header.RetCode;
}
- va_list ap;
+ if (_IOT_COUNT0 (type) != 0)
+ {
+ /* Data need either be sent, received, or even both. */
+ va_list ap;
- va_start (ap, request);
- arg = va_arg (ap, void *);
- va_end (ap);
+ va_start (ap, request);
+ arg = va_arg (ap, void *);
+ va_end (ap);
+ }
{
/* Check for a registered handler for REQUEST. */