1. 19 May, 2014 33 commits
  2. 10 Jun, 2013 7 commits
    • Willy Tarreau's avatar
      Linux 2.6.32.61 · feb908dd
      Willy Tarreau authored
      Signed-off-by: default avatarWilly Tarreau <w@1wt.eu>
      feb908dd
    • Willy Tarreau's avatar
      x86, ptrace: fix build breakage with gcc 4.7 · 4ed3bb08
      Willy Tarreau authored
      Christoph Biedl reported that 2.6.32 does not build with gcc 4.7 on
      i386 :
      
        CC      arch/x86/kernel/ptrace.o
      arch/x86/kernel/ptrace.c:1472:17: error: conflicting types for 'syscall_trace_enter'
      In file included from /PKGBUILDDIR/arch/x86/include/asm/vm86.h:130:0,
                       from /PKGBUILDDIR/arch/x86/include/asm/processor.h:10,
                       from /PKGBUILDDIR/arch/x86/include/asm/thread_info.h:22,
                       from include/linux/thread_info.h:56,
                       from include/linux/preempt.h:9,
                       from include/linux/spinlock.h:50,
                       from include/linux/seqlock.h:29,
                       from include/linux/time.h:8,
                       from include/linux/timex.h:56,
                       from include/linux/sched.h:56,
                       from arch/x86/kernel/ptrace.c:11:
      /PKGBUILDDIR/arch/x86/include/asm/ptrace.h:145:13: note: previous declaration of 'syscall_trace_enter' was here
      arch/x86/kernel/ptrace.c:1517:17: error: conflicting types for 'syscall_trace_leave'
      In file included from /PKGBUILDDIR/arch/x86/include/asm/vm86.h:130:0,
                       from /PKGBUILDDIR/arch/x86/include/asm/processor.h:10,
                       from /PKGBUILDDIR/arch/x86/include/asm/thread_info.h:22,
                       from include/linux/thread_info.h:56,
                       from include/linux/preempt.h:9,
                       from include/linux/spinlock.h:50,
                       from include/linux/seqlock.h:29,
                       from include/linux/time.h:8,
                       from include/linux/timex.h:56,
                       from include/linux/sched.h:56,
                       from arch/x86/kernel/ptrace.c:11:
      /PKGBUILDDIR/arch/x86/include/asm/ptrace.h:146:13: note: previous declaration of 'syscall_trace_leave' was here
      make[4]: *** [arch/x86/kernel/ptrace.o] Error 1
      make[3]: *** [arch/x86/kernel] Error 2
      make[3]: *** Waiting for unfinished jobs....
      
      He also found that this issue did not appear in more recent kernels since
      this asmregparm disappeared in 3.0-rc1 with commit 1b4ac2a9 that was
      applied after some UM changes that we don't necessarily want in 2.6.32.
      
      Thus, the cleanest fix for older kernels is to make the declaration in
      ptrace.h match the one in ptrace.c by specifying asmregparm on these
      functions. They're only called from asm which explains why it used to
      work despite the inconsistency in the declaration.
      Reported-by: default avatarChristoph Biedl <linux-kernel.bfrz@manchmal.in-ulm.de>
      Tested-by: default avatarChristoph Biedl <linux-kernel.bfrz@manchmal.in-ulm.de>
      Signed-off-by: default avatarWilly Tarreau <w@1wt.eu>
      4ed3bb08
    • Kashyap, Desai's avatar
      mpt2sas: Send default descriptor for RAID pass through in mpt2ctl · ad6bb568
      Kashyap, Desai authored
      commit ebda4d38 upstream.
      
      RAID_SCSI_IO_PASSTHROUGH: Driver needs to be sending the default
      descriptor for RAID Passthru, currently its sending SCSI_IO descriptor.
      Signed-off-by: default avatarKashyap Desai <kashyap.desai@lsi.com>
      Signed-off-by: default avatarJames Bottomley <James.Bottomley@suse.de>
      Signed-off-by: default avatarWilly Tarreau <w@1wt.eu>
      ad6bb568
    • Mathias Krause's avatar
      tipc: fix info leaks via msg_name in recv_msg/recv_stream · 0736a717
      Mathias Krause authored
      commit 60085c3d upstream.
      
      The code in set_orig_addr() does not initialize all of the members of
      struct sockaddr_tipc when filling the sockaddr info -- namely the union
      is only partly filled. This will make recv_msg() and recv_stream() --
      the only users of this function -- leak kernel stack memory as the
      msg_name member is a local variable in net/socket.c.
      
      Additionally to that both recv_msg() and recv_stream() fail to update
      the msg_namelen member to 0 while otherwise returning with 0, i.e.
      "success". This is the case for, e.g., non-blocking sockets. This will
      lead to a 128 byte kernel stack leak in net/socket.c.
      
      Fix the first issue by initializing the memory of the union with
      memset(0). Fix the second one by setting msg_namelen to 0 early as it
      will be updated later if we're going to fill the msg_name member.
      
      Cc: Jon Maloy <jon.maloy@ericsson.com>
      Cc: Allan Stephens <allan.stephens@windriver.com>
      Signed-off-by: default avatarMathias Krause <minipli@googlemail.com>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      [dannf: backported to Debian's 2.6.32]
      Signed-off-by: default avatarWilly Tarreau <w@1wt.eu>
      0736a717
    • Mathias Krause's avatar
      irda: Fix missing msg_namelen update in irda_recvmsg_dgram() · 21f908c9
      Mathias Krause authored
      commit 5ae94c0d upstream.
      
      The current code does not fill the msg_name member in case it is set.
      It also does not set the msg_namelen member to 0 and therefore makes
      net/socket.c leak the local, uninitialized sockaddr_storage variable
      to userland -- 128 bytes of kernel stack memory.
      
      Fix that by simply setting msg_namelen to 0 as obviously nobody cared
      about irda_recvmsg_dgram() not filling the msg_name in case it was
      set.
      
      Cc: Samuel Ortiz <samuel@sortiz.org>
      Signed-off-by: default avatarMathias Krause <minipli@googlemail.com>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      [dannf: adjusted to apply to Debian's 2.6.32]
      Signed-off-by: default avatarWilly Tarreau <w@1wt.eu>
      21f908c9
    • Mathias Krause's avatar
      rose: fix info leak via msg_name in rose_recvmsg() · 3cab351d
      Mathias Krause authored
      [ Upstream commit 4a184233 ]
      
      The code in rose_recvmsg() does not initialize all of the members of
      struct sockaddr_rose/full_sockaddr_rose when filling the sockaddr info.
      Nor does it initialize the padding bytes of the structure inserted by
      the compiler for alignment. This will lead to leaking uninitialized
      kernel stack bytes in net/socket.c.
      
      Fix the issue by initializing the memory used for sockaddr info with
      memset(0).
      Signed-off-by: default avatarMathias Krause <minipli@googlemail.com>
      Cc: Ralf Baechle <ralf@linux-mips.org>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      Signed-off-by: default avatarWilly Tarreau <w@1wt.eu>
      3cab351d
    • Weiping Pan's avatar
      rds: set correct msg_namelen · a86c9b39
      Weiping Pan authored
      commit 06b6a1cf upstream
      
      Jay Fenlason (fenlason@redhat.com) found a bug,
      that recvfrom() on an RDS socket can return the contents of random kernel
      memory to userspace if it was called with a address length larger than
      sizeof(struct sockaddr_in).
      rds_recvmsg() also fails to set the addr_len paramater properly before
      returning, but that's just a bug.
      There are also a number of cases wher recvfrom() can return an entirely bogus
      address. Anything in rds_recvmsg() that returns a non-negative value but does
      not go through the "sin = (struct sockaddr_in *)msg->msg_name;" code path
      at the end of the while(1) loop will return up to 128 bytes of kernel memory
      to userspace.
      
      And I write two test programs to reproduce this bug, you will see that in
      rds_server, fromAddr will be overwritten and the following sock_fd will be
      destroyed.
      Yes, it is the programmer's fault to set msg_namelen incorrectly, but it is
      better to make the kernel copy the real length of address to user space in
      such case.
      
      How to run the test programs ?
      I test them on 32bit x86 system, 3.5.0-rc7.
      
      1 compile
      gcc -o rds_client rds_client.c
      gcc -o rds_server rds_server.c
      
      2 run ./rds_server on one console
      
      3 run ./rds_client on another console
      
      4 you will see something like:
      server is waiting to receive data...
      old socket fd=3
      server received data from client:data from client
      msg.msg_namelen=32
      new socket fd=-1067277685
      sendmsg()
      : Bad file descriptor
      
      /***************** rds_client.c ********************/
      
      int main(void)
      {
      	int sock_fd;
      	struct sockaddr_in serverAddr;
      	struct sockaddr_in toAddr;
      	char recvBuffer[128] = "data from client";
      	struct msghdr msg;
      	struct iovec iov;
      
      	sock_fd = socket(AF_RDS, SOCK_SEQPACKET, 0);
      	if (sock_fd < 0) {
      		perror("create socket error\n");
      		exit(1);
      	}
      
      	memset(&serverAddr, 0, sizeof(serverAddr));
      	serverAddr.sin_family = AF_INET;
      	serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
      	serverAddr.sin_port = htons(4001);
      
      	if (bind(sock_fd, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) < 0) {
      		perror("bind() error\n");
      		close(sock_fd);
      		exit(1);
      	}
      
      	memset(&toAddr, 0, sizeof(toAddr));
      	toAddr.sin_family = AF_INET;
      	toAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
      	toAddr.sin_port = htons(4000);
      	msg.msg_name = &toAddr;
      	msg.msg_namelen = sizeof(toAddr);
      	msg.msg_iov = &iov;
      	msg.msg_iovlen = 1;
      	msg.msg_iov->iov_base = recvBuffer;
      	msg.msg_iov->iov_len = strlen(recvBuffer) + 1;
      	msg.msg_control = 0;
      	msg.msg_controllen = 0;
      	msg.msg_flags = 0;
      
      	if (sendmsg(sock_fd, &msg, 0) == -1) {
      		perror("sendto() error\n");
      		close(sock_fd);
      		exit(1);
      	}
      
      	printf("client send data:%s\n", recvBuffer);
      
      	memset(recvBuffer, '\0', 128);
      
      	msg.msg_name = &toAddr;
      	msg.msg_namelen = sizeof(toAddr);
      	msg.msg_iov = &iov;
      	msg.msg_iovlen = 1;
      	msg.msg_iov->iov_base = recvBuffer;
      	msg.msg_iov->iov_len = 128;
      	msg.msg_control = 0;
      	msg.msg_controllen = 0;
      	msg.msg_flags = 0;
      	if (recvmsg(sock_fd, &msg, 0) == -1) {
      		perror("recvmsg() error\n");
      		close(sock_fd);
      		exit(1);
      	}
      
      	printf("receive data from server:%s\n", recvBuffer);
      
      	close(sock_fd);
      
      	return 0;
      }
      
      /***************** rds_server.c ********************/
      
      int main(void)
      {
      	struct sockaddr_in fromAddr;
      	int sock_fd;
      	struct sockaddr_in serverAddr;
      	unsigned int addrLen;
      	char recvBuffer[128];
      	struct msghdr msg;
      	struct iovec iov;
      
      	sock_fd = socket(AF_RDS, SOCK_SEQPACKET, 0);
      	if(sock_fd < 0) {
      		perror("create socket error\n");
      		exit(0);
      	}
      
      	memset(&serverAddr, 0, sizeof(serverAddr));
      	serverAddr.sin_family = AF_INET;
      	serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
      	serverAddr.sin_port = htons(4000);
      	if (bind(sock_fd, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) < 0) {
      		perror("bind error\n");
      		close(sock_fd);
      		exit(1);
      	}
      
      	printf("server is waiting to receive data...\n");
      	msg.msg_name = &fromAddr;
      
      	/*
      	 * I add 16 to sizeof(fromAddr), ie 32,
      	 * and pay attention to the definition of fromAddr,
      	 * recvmsg() will overwrite sock_fd,
      	 * since kernel will copy 32 bytes to userspace.
      	 *
      	 * If you just use sizeof(fromAddr), it works fine.
      	 * */
      	msg.msg_namelen = sizeof(fromAddr) + 16;
      	/* msg.msg_namelen = sizeof(fromAddr); */
      	msg.msg_iov = &iov;
      	msg.msg_iovlen = 1;
      	msg.msg_iov->iov_base = recvBuffer;
      	msg.msg_iov->iov_len = 128;
      	msg.msg_control = 0;
      	msg.msg_controllen = 0;
      	msg.msg_flags = 0;
      
      	while (1) {
      		printf("old socket fd=%d\n", sock_fd);
      		if (recvmsg(sock_fd, &msg, 0) == -1) {
      			perror("recvmsg() error\n");
      			close(sock_fd);
      			exit(1);
      		}
      		printf("server received data from client:%s\n", recvBuffer);
      		printf("msg.msg_namelen=%d\n", msg.msg_namelen);
      		printf("new socket fd=%d\n", sock_fd);
      		strcat(recvBuffer, "--data from server");
      		if (sendmsg(sock_fd, &msg, 0) == -1) {
      			perror("sendmsg()\n");
      			close(sock_fd);
      			exit(1);
      		}
      	}
      
      	close(sock_fd);
      	return 0;
      }
      Signed-off-by: default avatarWeiping Pan <wpan@redhat.com>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      [dannf: Adjusted to apply to Debian's 2.6.32]
      Signed-off-by: default avatarWilly Tarreau <w@1wt.eu>
      a86c9b39