lkml.org 
[lkml]   [2016]   [Feb]   [10]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
Subjectcompat_ioctl question/problem
From
Hi,

following is the code in question.

+static int compat_hdio_ioctl(struct inode *inode, struct file *file,
+ struct gendisk *disk, unsigned int cmd,
unsigned long arg)
+{
+ mm_segment_t old_fs = get_fs();
+ unsigned long kval;
+ unsigned int __user *uvp;
+ int error;
+
+ set_fs(KERNEL_DS);
+ error = blkdev_driver_ioctl(inode, file, disk,
+ cmd, (unsigned long)(&kval));
+ set_fs(old_fs);
+
+ if (error == 0) {
+ uvp = compat_ptr(arg);
+ if (put_user(kval, uvp))
+ error = -EFAULT;
+ }
+ return error;
+}


kval is local so it has random value.
But one of syscall like HDIO_GET_32BIT/ATA_IOC_GET_IO32 only updates
one byte so if kval has 0xaaaaaaaa and ioctl() updates one byte then
it becomes 0xaaaaaa01.
And put_user() writes 4bytes.

Because of that I’m having problem with 32bit hdparm.

void process_dev (char *devname)
{
static long parm, multcount; <-- parm is static so it’s zero
…..
if (do_defaults || get_io32bit) {
if (0 == ioctl(fd, HDIO_GET_32BIT, &parm)) {


so parm becomes 0xaaaaaa01 and reports wrong mode.

If hdparm is 64bit then 64bit syscall will update 1byte of parm so it
becomes 0x1.

What would be a good fix if I can't use 64bit hdparm?
- Modify hdparm to look at only 1byte
- Initialize kval to zero
- Copy parm to kval before blkdev_driver_ioctl() to be more
accurately close to 64bit syscall.


Thanks,
Soohoon.

\
 
 \ /
  Last update: 2016-02-10 21:21    [W:0.068 / U:0.692 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site