From: Dan Carpenter <dan.carpenter@oracle.com>
To: David Howells <dhowells@redhat.com>
Cc: David Miller <davem@davemloft.net>,
netdev@vger.kernel.org, kernel-janitors@vger.kernel.org
Subject: Re: [patch] RxRPC: use copy_to_user() instead of memcpy()
Date: Wed, 20 Mar 2013 01:51:02 +0300 [thread overview]
Message-ID: <20130319225101.GZ9189@mwanda> (raw)
In-Reply-To: <30707.1363701570@warthog.procyon.org.uk>
[-- Attachment #1: Type: text/plain, Size: 260 bytes --]
Thanks for the explanation. I misread the code and then managed to
trigger an unrelated locking bug and got confused.
I think there is a spin_unlock(call->lock) missing somewhere on an
error path. I have attached a reproducer file.
regards,
dan carpenter
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: test_rxrpc.c --]
[-- Type: text/x-csrc; charset=utf-8, Size: 7271 bytes --]
/* klog.c: description
*
* Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* Based on code:
*
* Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#define _XOPEN_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <ctype.h>
#include <time.h>
#include <signal.h>
#include <errno.h>
#include <termios.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <keyutils.h>
//#include <rpc/xdr.h>
#define KA_SERVICE 731
#define KA_TICKET_GRANTING_SERVICE 732
#define OSERROR(X, Y) do { if ((long)(X) == -1) { perror(Y); exit(1); } } while(0)
struct sockaddr_rxrpc {
sa_family_t srx_family; /* address family */
unsigned short srx_service; /* service desired */
unsigned short transport_type; /* type of transport socket (SOCK_DGRAM) */
unsigned short transport_len; /* length of transport address */
union {
sa_family_t family; /* transport address family */
struct sockaddr_in sin; /* IPv4 transport address */
struct sockaddr_in6 sin6; /* IPv6 transport address */
} transport;
};
#define SOL_RXRPC 272
#define RXRPC_USER_CALL_ID 1 /* User call ID specifier */
#define RXRPC_ABORT 2 /* Abort request / notification */
#define RXRPC_ACK 3 /* [Server] RPC op final ACK received */
#define RXRPC_RESPONSE 4 /* [Server] security response received */
#define RXRPC_NET_ERROR 5 /* network error received */
#define RXRPC_BUSY 6 /* server busy received */
#define RXRPC_LOCAL_ERROR 7 /* local error generated */
#define RXRPC_PREPARE_CALL_SLOT 8 /* Propose user call ID specifier for next call */
#define RXRPC_SECURITY_KEY 1 /* [clnt] set client security key */
#define RXRPC_SECURITY_KEYRING 2 /* [srvr] set ring of server security keys */
#define RXRPC_EXCLUSIVE_CONNECTION 3 /* [clnt] use exclusive RxRPC connection */
#define RXRPC_MIN_SECURITY_LEVEL 4 /* minimum security level */
#define OSERROR(X, Y) do { if ((long)(X) == -1) { perror(Y); exit(1); } } while(0)
static const unsigned char local_addr[4] = { 0, 0, 0, 0 };
static const unsigned char remote_addr[4] = { 127, 0, 0, 1 };
#define RXRPC_ADD_CALLID(control, ctrllen, id) \
do { \
struct cmsghdr *__cmsg; \
__cmsg = (void *)(control) + (ctrllen); \
__cmsg->cmsg_len = CMSG_LEN(sizeof(unsigned long)); \
__cmsg->cmsg_level = SOL_RXRPC; \
__cmsg->cmsg_type = RXRPC_USER_CALL_ID; \
*(unsigned long *)CMSG_DATA(__cmsg) = (id); \
(ctrllen) += __cmsg->cmsg_len; \
\
} while (0)
int main(int argc, char *argv[])
{
struct sockaddr_rxrpc srx;
struct msghdr send;
struct msghdr msg;
struct iovec iov[1];
size_t ctrllen, replen;
unsigned char control[4096];
void *preply;
int client, ret;
int service = KA_SERVICE;
char buffer[16384] __attribute__((aligned(4)));
void *request = buffer;
size_t reqlen = sizeof(buffer);
void *reply = buffer;
size_t replen_tmp = sizeof(buffer);
size_t *_replen = &replen_tmp;
void *p = NULL;
int i;
client = socket(AF_RXRPC, SOCK_DGRAM, PF_INET);
OSERROR(client, "socket");
/* the authentication is associated with the virtual
* connection, so we need to open an exclusive channel */
ret = setsockopt(client, SOL_RXRPC, RXRPC_EXCLUSIVE_CONNECTION,
NULL, 0);
OSERROR(ret, "setsockopt");
/* bind an address to the local endpoint */
srx.srx_family = AF_RXRPC;
srx.srx_service = 0; /* it's a client */
srx.transport_type = SOCK_DGRAM;
srx.transport_len = sizeof(srx.transport.sin);
srx.transport.sin.sin_family = AF_INET;
srx.transport.sin.sin_port = htons(7001);
memcpy(&srx.transport.sin.sin_addr, &local_addr, 4);
ret = bind(client, (struct sockaddr *) &srx, sizeof(srx));
OSERROR(ret, "bind");
/* connect to the remote server */
srx.srx_family = AF_RXRPC;
srx.srx_service = service;
srx.transport_type = SOCK_DGRAM;
srx.transport_len = sizeof(srx.transport.sin);
srx.transport.sin.sin_family = AF_INET;
srx.transport.sin.sin_port = htons(7004);
memcpy(&srx.transport.sin.sin_addr, &remote_addr, 4);
ret = connect(client, (struct sockaddr *) &srx, sizeof(srx));
OSERROR(ret, "connect");
/* request an operation */
ctrllen = 0;
RXRPC_ADD_CALLID(control, ctrllen, 0x12345);
iov[0].iov_base = (void *) request;
iov[0].iov_len = reqlen;
send.msg_name = NULL;
send.msg_namelen = 0;
send.msg_iov = iov;
send.msg_iovlen = 1;
send.msg_control = control;
send.msg_controllen = ctrllen;
send.msg_flags = 0;
/* wait for a reply */
preply = reply;
replen = 0;
for (i = 0; i < 2; i++) {
iov[0].iov_base = preply;
iov[0].iov_len = *_replen - replen;
ret = sendmsg(client, &send, 0);
if (ret == -1 && (errno == ENOANO || errno == ECONNABORTED))
perror("sendmsg/data");
else
OSERROR(ret, "sendmsg/data");
p += 10000;
msg.msg_name = p;
msg.msg_namelen = sizeof(struct sockaddr_rxrpc);
msg.msg_iov = iov;
msg.msg_iovlen = 1;
msg.msg_control = control;
msg.msg_controllen = sizeof(control);
msg.msg_flags = 0;
ret = recvmsg(client, &msg, 0);
if (ret < 0) {
printf("%d %p recvmsg %s\n", i, p, strerror(errno));
continue;
}
printf("RECV: %d [fl:%d]\n", ret, msg.msg_flags);
printf("CMSG: %zu\n", msg.msg_controllen);
printf("IOV: %zu [0]=%zu\n", msg.msg_iovlen, iov[0].iov_len);
preply += ret;
replen += ret;
if (msg.msg_flags & MSG_EOR)
break;
}
*_replen = replen;
close(client);
return 0;
}
next prev parent reply other threads:[~2013-03-19 22:51 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-03-18 10:55 [patch] RxRPC: use copy_to_user() instead of memcpy() Dan Carpenter
2013-03-19 13:42 ` David Miller
2013-03-19 13:59 ` David Howells
2013-03-19 22:51 ` Dan Carpenter [this message]
2013-03-20 10:23 ` David Howells
2013-03-20 15:52 ` Dan Carpenter
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=20130319225101.GZ9189@mwanda \
--to=dan.carpenter@oracle.com \
--cc=davem@davemloft.net \
--cc=dhowells@redhat.com \
--cc=kernel-janitors@vger.kernel.org \
--cc=netdev@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;
as well as URLs for NNTP newsgroup(s).