linux-embedded.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Linux Rules <linuzoo@gmail.com>
To: linux-embedded@vger.kernel.org
Subject: Re: Help needed with porting 32-bit user ioctl to run on a 64-bit kernel
Date: Wed, 30 Nov 2011 14:11:52 -0800	[thread overview]
Message-ID: <CA+ib0qHSPqjnxp5E5CxLxKuQoHUCRvKm-dG0qUwvPWVob6GwLA@mail.gmail.com> (raw)
In-Reply-To: <CA+ib0qH_8Ex10sjYH7abbFgaQaRRwKq73exn3jehjpts+Hx=aQ@mail.gmail.com>

I did some more digging and found that there is a file compat_ioctl.c
which has this function (below) which is creating a local ifreq buffer
copy of the incoming 32-bit buffer and passing to ioctl in kernel, but
does not copy_to_user the data back for default switch case, could
this be the problem?
fs/compat_ioctl.cstatic int dev_ifsioc(unsigned int fd, unsigned int
cmd, unsigned long arg) 504{ 505        struct ifreq ifr; 506
struct ifreq32 __user *uifr32; 507        struct ifmap32 __user
*uifmap32; 508        mm_segment_t old_fs; 509        int err; 510
    511        uifr32 = compat_ptr(arg); 512        uifmap32 =
&uifr32->ifr_ifru.ifru_map; 513        switch (cmd) { 514        case
SIOCSIFMAP: 515                err = copy_from_user(&ifr, uifr32,
sizeof(ifr.ifr_name)); 516                err |=
__get_user(ifr.ifr_map.mem_start, &uifmap32->mem_start); 517
     err |= __get_user(ifr.ifr_map.mem_end, &uifmap32->mem_end); 518
             err |= __get_user(ifr.ifr_map.base_addr,
&uifmap32->base_addr); 519                err |=
__get_user(ifr.ifr_map.irq, &uifmap32->irq); 520                err |=
__get_user(ifr.ifr_map.dma, &uifmap32->dma); 521                err |=
__get_user(ifr.ifr_map.port, &uifmap32->port); 522                if
(err) 523                        return -EFAULT; 524
break; 525        default: 526                if (copy_from_user(&ifr,
uifr32, sizeof(*uifr32))) 527                        return -EFAULT;
528                break; 529        } 530        old_fs = get_fs();
531        set_fs (KERNEL_DS); 532        err = sys_ioctl (fd, cmd,
(unsigned long)&ifr); 533        set_fs (old_fs); 534        if (!err)
{ 535                switch (cmd) { 536                /* TUNSETIFF is
defined as _IOW, it should be _IORW 537                 * as the data
is copied back to user space, but that 538                 * cannot be
fixed without breaking all existing apps. 539                 */ 540
             case TUNSETIFF: 541                case SIOCGIFFLAGS: 542
               case SIOCGIFMETRIC: 543                case SIOCGIFMTU:
544                case SIOCGIFMEM: 545                case
SIOCGIFHWADDR: 546                case SIOCGIFINDEX: 547
 case SIOCGIFADDR: 548                case SIOCGIFBRDADDR: 549
       case SIOCGIFDSTADDR: 550                case SIOCGIFNETMASK:
551                case SIOCGIFTXQLEN: 552                        if
(copy_to_user(uifr32, &ifr, sizeof(*uifr32))) 553
          return -EFAULT; 554                        break; 555
        case SIOCGIFMAP: 556                        err =
copy_to_user(uifr32, &ifr, sizeof(ifr.ifr_name)); 557
      err |= __put_user(ifr.ifr_map.mem_start, &uifmap32->mem_start);
558                        err |= __put_user(ifr.ifr_map.mem_end,
&uifmap32->mem_end); 559                        err |=
__put_user(ifr.ifr_map.base_addr, &uifmap32->base_addr); 560
             err |= __put_user(ifr.ifr_map.irq, &uifmap32->irq); 561
                     err |= __put_user(ifr.ifr_map.dma,
&uifmap32->dma); 562                        err |=
__put_user(ifr.ifr_map.port, &uifmap32->port); 563
   if (err) 564                                err = -EFAULT; 565
                  break; 566                } 567        } 568
return err; 569} 570
On Wed, Nov 30, 2011 at 11:42 AM, Linux Rules <linuzoo@gmail.com> wrote:
> All,
>
> I am working on porting 32-bit application code to run over a 64-bit kernel.
>
> The 32 bit code calls socket ioctl to programs some registers in the
> driver (e1000) and then opens a raw socket.
>
> The struct ifreq is used to construct the command as expected.
>
> The problem i am facing is that, the data which is copied back into
> the ioctl buffer is not visible in the user space at all.
>
> [32-bit user space if req with command] ==> [IOCTL] ==> [64-bit
> KERNEL] ==> [reads register copies result into ifreq->ifr_data in
> kernel] ==> [The copied data is not visible in the user code].
>
> Since the data i require is having a length of only 4 bytes,  i used
> the ifr_data field itself as a buffer instead of using it as a pointer
> to a buffer because i see that the ifreq structure is of 32 bytes
> length and ifr_name is part of a union which has a size of 16 bytes.
>
> I tried to do some debugging on this issue and found these:
>
> the struct ifreq is 32 byte in 32-bit user space but is 40 bytes in
> kernel space, this is probably because of the size of sockaddr inside
> ifreq which is different for 64-bit, also copy_from/to_user is not
> required because do_ioctl is already working on a copy of the ifreq
> buffer.
>
> I did some googling and found suggestions to use compat_ioctl to do
> the porting, but that is pertaining to using the file_operations
> structure, netdevice does not have a compat_ioctl, does it?
>
> Any help is appreciated in this regard.
>
> kind regards,
> mz.

      reply	other threads:[~2011-11-30 22:11 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-11-30 19:42 Help needed with porting 32-bit user ioctl to run on a 64-bit kernel Linux Rules
2011-11-30 22:11 ` Linux Rules [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CA+ib0qHSPqjnxp5E5CxLxKuQoHUCRvKm-dG0qUwvPWVob6GwLA@mail.gmail.com \
    --to=linuzoo@gmail.com \
    --cc=linux-embedded@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).