diff -urNp linux-2.4.21/arch/x86_64/ia32/ia32_ioctl.c linux-2.4.21.SUSE/arch/x86_64/ia32/ia32_ioctl.c --- linux-2.4.21/arch/x86_64/ia32/ia32_ioctl.c 2004-03-03 17:17:17.000000000 +0100 +++ linux-2.4.21.SUSE/arch/x86_64/ia32/ia32_ioctl.c 2004-03-03 17:18:20.000000000 +0100 @@ -1779,7 +1779,10 @@ struct cdrom_generic_command32 { unsigned int buflen; int stat; __kernel_caddr_t32 sense; - __kernel_caddr_t32 reserved[3]; + unsigned char data_direction; + int quiet; + int timeout; + __kernel_caddr_t32 reserved[1]; }; static int cdrom_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg) @@ -1821,17 +1824,25 @@ static int cdrom_ioctl_trans(unsigned in return -EFAULT; cdreadaudio.buf = (void *)A(addr); break; - case CDROM_SEND_PACKET: + case CDROM_SEND_PACKET: { + __kernel_caddr_t32 sense; karg = &cgc; err = copy_from_user(cgc.cmd, &((struct cdrom_generic_command32 *)arg)->cmd, sizeof(cgc.cmd)); err |= __get_user(addr, &((struct cdrom_generic_command32 *)arg)->buffer); err |= __get_user(cgc.buflen, &((struct cdrom_generic_command32 *)arg)->buflen); + err |= __get_user(sense, &((struct cdrom_generic_command32 *)arg)->sense); + err |= __get_user(cgc.data_direction, &((struct cdrom_generic_command32 *)arg)->data_direction); + err |= __get_user(cgc.timeout, &((struct cdrom_generic_command32 *)arg)->timeout); if (err) return -EFAULT; if (verify_area(VERIFY_WRITE, (void *)A(addr), cgc.buflen)) return -EFAULT; + if (sense && verify_area(VERIFY_WRITE, (void *)A(sense), sizeof(struct request_sense))) + return -EFAULT; cgc.buffer = (void *)A(addr); + cgc.sense = (void *)A(sense); break; + } default: do { static int count;