public inbox for glibc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug libc/12080] New: setsockopt with a group_req argument fails when 32-bit binaries talk to 64-bit kernels
@ 2010-10-01 21:41 enh at google dot com
0 siblings, 0 replies; only message in thread
From: enh at google dot com @ 2010-10-01 21:41 UTC (permalink / raw)
To: glibc-bugs
setsockopt MCAST_JOIN_GROUP calls (et cetera) fail with EINVAL when my 32-bit
binary talks to a 64-bit kernel. this is because struct group_req isn't packed.
/tmp$ cat mc.cpp
#include <errno.h>
#include <inttypes.h>
#include <signal.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
int main() {
struct sockaddr_in addr;
memset (&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr ("239.192.0.1");
int recv_sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (-1 == recv_sock) { perror("socket failed"); return 1; }
struct sockaddr_in recv_addr;
memcpy (&recv_addr, &addr, sizeof(addr));
recv_addr.sin_port = 7500;
socklen_t l = sizeof(recv_addr);
if (0 != bind (recv_sock, (struct sockaddr*)&recv_addr, l)) {
perror("bind failed"); return 1; }
struct group_req gr;
memset (&gr, 0, sizeof(gr));
printf("sizeof(group_req)=%i\n", sizeof(group_req));
printf("offsetof(group_req, gr_interface)=%i\n", offsetof(group_req,
gr_interface));
printf("offsetof(group_req, gr_group)=%i\n", offsetof(group_req, gr_group));
sockaddr_storage ss;
printf("sizeof(ss.ss_family)=%i\n", sizeof(ss.ss_family));
((struct sockaddr*)&gr.gr_group)->sa_family = addr.sin_family;
((struct sockaddr_in*)&gr.gr_group)->sin_addr.s_addr = addr.sin_addr.s_addr;
if (0 != setsockopt (recv_sock, SOL_IP, MCAST_JOIN_GROUP, (const
char*)&gr, sizeof(gr))) { perror("setsockopt failed"); return 1; }
return 0;
}
/tmp$ g++ -m64 mc.cpp -o mc && ./mc
sizeof(group_req)=136
offsetof(group_req, gr_interface)=0
offsetof(group_req, gr_group)=8
sizeof(ss.ss_family)=2
/tmp$ g++ -m32 mc.cpp -o mc && ./mc
sizeof(group_req)=132
offsetof(group_req, gr_interface)=0
offsetof(group_req, gr_group)=4
sizeof(ss.ss_family)=2
setsockopt failed: Invalid argument
/tmp$
i've worked around this by changing my code to recognize EINVAL and try again
with its own fake struct instead
struct group_req64 {
uint32_t gr_interface;
uint32_t my_padding;
sockaddr_storage gr_group;
};
that works, but i wonder if glibc should be doing this for me? i know it does
stuff with statfs/statfs64 and suchlike.
--
Summary: setsockopt with a group_req argument fails when 32-bit
binaries talk to 64-bit kernels
Product: glibc
Version: 2.11
Status: NEW
Severity: normal
Priority: P2
Component: libc
AssignedTo: drepper dot fsp at gmail dot com
ReportedBy: enh at google dot com
CC: glibc-bugs at sources dot redhat dot com
http://sourceware.org/bugzilla/show_bug.cgi?id=12080
------- You are receiving this mail because: -------
You are on the CC list for the bug, or are watching someone who is.
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2010-10-01 21:41 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-10-01 21:41 [Bug libc/12080] New: setsockopt with a group_req argument fails when 32-bit binaries talk to 64-bit kernels enh at google dot com
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).