* [Bug 31192] New: ioctl SG_GET_REQUEST_TABLE returns 64-bit structure to 32-bit app.
@ 2011-03-16 13:24 bugzilla-daemon
2011-03-16 13:53 ` [Bug 31192] " bugzilla-daemon
2012-08-20 14:59 ` bugzilla-daemon
0 siblings, 2 replies; 3+ messages in thread
From: bugzilla-daemon @ 2011-03-16 13:24 UTC (permalink / raw)
To: linux-scsi
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.
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2012-08-20 14:59 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-03-16 13:24 [Bug 31192] New: ioctl SG_GET_REQUEST_TABLE returns 64-bit structure to 32-bit app bugzilla-daemon
2011-03-16 13:53 ` [Bug 31192] " bugzilla-daemon
2012-08-20 14:59 ` bugzilla-daemon
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 NNTP newsgroup(s).