From: bugzilla-daemon@bugzilla.kernel.org
To: linux-scsi@vger.kernel.org
Subject: [Bug 31192] New: ioctl SG_GET_REQUEST_TABLE returns 64-bit structure to 32-bit app.
Date: Wed, 16 Mar 2011 13:24:13 GMT [thread overview]
Message-ID: <bug-31192-11613@https.bugzilla.kernel.org/> (raw)
https://bugzilla.kernel.org/show_bug.cgi?id=31192
Summary: ioctl SG_GET_REQUEST_TABLE returns 64-bit structure to
32-bit app.
Product: SCSI Drivers
Version: 2.5
Kernel Version: 2.6.18-194.32.1.el5
Platform: All
OS/Version: Linux
Tree: Mainline
Status: NEW
Severity: normal
Priority: P1
Component: Other
AssignedTo: scsi_drivers-other@kernel-bugs.osdl.org
ReportedBy: jbyers@stonefly.com
CC: jbyers@stonefly.com
Regression: No
The 'sg' module ioctl 'SG_GET_REQUEST_TABLE', when run on an
2.6.18-194.32.1.el5 x86_64 kernel, from a 32-bit application
seems to return the 64-bit version of the
sg_req_info_t[SG_MAX_QUEUE] table, not the 32-bit version.
Because there is a pointer in the sg_req_info_t structure,
the returned size is (4 * SG_MAX_QUEUE) = 64 bytes too
large, and it corrupts neighboring user memory, as well as
not returning the correct data.
Although there is code in 'fs/compat_ioctl.c' that looks to
be handling the 32-bit user to 64-bit kernel conversion, the
"COMPATIBLE_IOCTL(SG_GET_REQUEST_TABLE)" line in
'include/linux/compat_ioctl.h' conflicts with it and seems
to prevent the conversion code from being called.
The same ioctl called from a 64-bit app works fine.
The problem looks to still be present in the newest kernel
source, although I haven't tested it.
It seems like the "COMPATIBLE_IOCTL(SG_GET_REQUEST_TABLE)"
line should be removed from 'compat_ioctl.h' ('compat_ioctl.c'
in the newest kernel).
~ Jeff Byers ~
# gcc -m32 -Wall -o sg_get_request_table sg_get_request_table.c
# ./sg_get_request_table /dev/sg1
SG Request Table:
Memory fence damaged:
0xff90c034: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0xff90c044: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0xff90c054: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0xff90c064: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0xff90c074: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0xff90c084: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0xff90c094: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0xff90c0a4: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
============================
// Test sg 'SG_GET_REQUEST_TABLE ioctl.
// Build with:
// gcc -m32 -Wall -o sg_get_request_table sg_get_request_table.c
// gcc -m64 -Wall -o sg_get_request_table sg_get_request_table.c
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <scsi/sg.h> /* take care: fetches glibc's /usr/include/scsi/sg.h */
static void hex_dump(const unsigned char *buf, int len, const char *str);
static int memunchr(const void *s, int c, size_t n);
int main(int argc, char * argv[])
{
int sg_fd;
int idx;
unsigned char fence[128];
sg_req_info_t req_info[SG_MAX_QUEUE] = {{0}};
if (2 != argc) {
printf("Usage: '%s <sg_device>'\n", argv[0]);
return 1;
}
if ((sg_fd = open(argv[1], O_RDONLY)) < 0) {
perror("error opening given file name");
return 1;
}
printf("SG Request Table:\n");
memset(req_info, 0xFF, sizeof(req_info));
memset(fence, 0xFF, sizeof(fence));
if (ioctl(sg_fd, SG_GET_REQUEST_TABLE, &req_info) < 0) {
perror("SG_GET_REQUEST_TABLE ioctl error");
return 1;
}
for(idx=0; idx < SG_MAX_QUEUE; idx++){
if(req_info[idx].req_state == 0)
continue;
printf("req_info[%u]: req_state=%u, pack_id=%u, usr_ptr=%p,
duration=%u\n",
idx, req_info[idx].req_state, req_info[idx].pack_id,
req_info[idx].usr_ptr, req_info[idx].duration);
}
if (memunchr(fence, 0xFF, sizeof(fence)) != 0){
hex_dump(fence, sizeof(fence), "Memory fence damaged:");
}
close(sg_fd);
return 0;
}
static void hex_dump(const unsigned char *buf, int len, const char *str)
{
printf("%s\n", str);
int idx;
for(idx=0; idx < len; idx++){
if ((idx > 0) && ((idx & 0x0F) == 0)){
printf("\n");
}
if ((idx & 0x0F) == 0){
printf("%p:", &buf[idx]);
}
printf(" %02x", buf[idx]);
}
printf("\n");
return;
}
static int memunchr(const void *s, int c, size_t n)
{
unsigned char *ptr = (unsigned char *)s;
for(; n > 0; n--){
if (*ptr++ != c)
return 1;
}
return 0;
}
--
Configure bugmail: https://bugzilla.kernel.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are watching the assignee of the bug.
next reply other threads:[~2011-03-16 13:24 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-03-16 13:24 bugzilla-daemon [this message]
2011-03-16 13:53 ` [Bug 31192] ioctl SG_GET_REQUEST_TABLE returns 64-bit structure to 32-bit app bugzilla-daemon
2012-08-20 14:59 ` bugzilla-daemon
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=bug-31192-11613@https.bugzilla.kernel.org/ \
--to=bugzilla-daemon@bugzilla.kernel.org \
--cc=linux-scsi@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