From 6753048948b86f3b045710f77e1616b348562fa9 Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Thu, 10 May 2012 13:26:40 -0700 Subject: [PATCH] Hurd: ioctl() incorrectly decodes argument --- ChangeLog | 6 ++++++ sysdeps/mach/hurd/bits/ioctls.h | 3 ++- sysdeps/mach/hurd/ioctl.c | 21 ++++++++++++--------- 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 + + * 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 * 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. */ -- 2.43.5