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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.