Skip to content

Commit

Permalink
net/x25: push BKL usage into x25_proto
Browse files Browse the repository at this point in the history
The x25 driver uses lock_kernel() implicitly through
its proto_ops wrapper. The makes the usage explicit
in order to get rid of that wrapper and to better document
the usage of the BKL.

The next step should be to get rid of the usage of the BKL
in x25 entirely, which requires understanding what data
structures need serialized accesses.

Cc: Henner Eisen <eis@baty.hanse.de>
Cc: David S. Miller <davem@davemloft.net>
Cc: linux-x25@vger.kernel.org
Cc: netdev@vger.kernel.org
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Arnd Bergmann authored and David S. Miller committed Nov 7, 2009
1 parent 58a9d73 commit 9177490
Showing 1 changed file with 60 additions and 11 deletions.
71 changes: 60 additions & 11 deletions net/x25/af_x25.c
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,7 @@ static int x25_setsockopt(struct socket *sock, int level, int optname,
struct sock *sk = sock->sk;
int rc = -ENOPROTOOPT;

lock_kernel();
if (level != SOL_X25 || optname != X25_QBITINCL)
goto out;

Expand All @@ -429,6 +430,7 @@ static int x25_setsockopt(struct socket *sock, int level, int optname,
x25_sk(sk)->qbitincl = !!opt;
rc = 0;
out:
unlock_kernel();
return rc;
}

Expand All @@ -438,6 +440,7 @@ static int x25_getsockopt(struct socket *sock, int level, int optname,
struct sock *sk = sock->sk;
int val, len, rc = -ENOPROTOOPT;

lock_kernel();
if (level != SOL_X25 || optname != X25_QBITINCL)
goto out;

Expand All @@ -458,6 +461,7 @@ static int x25_getsockopt(struct socket *sock, int level, int optname,
val = x25_sk(sk)->qbitincl;
rc = copy_to_user(optval, &val, len) ? -EFAULT : 0;
out:
unlock_kernel();
return rc;
}

Expand All @@ -466,12 +470,14 @@ static int x25_listen(struct socket *sock, int backlog)
struct sock *sk = sock->sk;
int rc = -EOPNOTSUPP;

lock_kernel();
if (sk->sk_state != TCP_LISTEN) {
memset(&x25_sk(sk)->dest_addr, 0, X25_ADDR_LEN);
sk->sk_max_ack_backlog = backlog;
sk->sk_state = TCP_LISTEN;
rc = 0;
}
unlock_kernel();

return rc;
}
Expand Down Expand Up @@ -598,6 +604,7 @@ static int x25_release(struct socket *sock)
struct sock *sk = sock->sk;
struct x25_sock *x25;

lock_kernel();
if (!sk)
goto out;

Expand Down Expand Up @@ -628,25 +635,31 @@ static int x25_release(struct socket *sock)

sock_orphan(sk);
out:
unlock_kernel();
return 0;
}

static int x25_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
{
struct sock *sk = sock->sk;
struct sockaddr_x25 *addr = (struct sockaddr_x25 *)uaddr;
int rc = 0;

lock_kernel();
if (!sock_flag(sk, SOCK_ZAPPED) ||
addr_len != sizeof(struct sockaddr_x25) ||
addr->sx25_family != AF_X25)
return -EINVAL;
addr->sx25_family != AF_X25) {
rc = -EINVAL;
goto out;
}

x25_sk(sk)->source_addr = addr->sx25_addr;
x25_insert_socket(sk);
sock_reset_flag(sk, SOCK_ZAPPED);
SOCK_DEBUG(sk, "x25_bind: socket is bound\n");

return 0;
out:
unlock_kernel();
return rc;
}

static int x25_wait_for_connection_establishment(struct sock *sk)
Expand Down Expand Up @@ -687,6 +700,7 @@ static int x25_connect(struct socket *sock, struct sockaddr *uaddr,
struct x25_route *rt;
int rc = 0;

lock_kernel();
lock_sock(sk);
if (sk->sk_state == TCP_ESTABLISHED && sock->state == SS_CONNECTING) {
sock->state = SS_CONNECTED;
Expand Down Expand Up @@ -764,6 +778,7 @@ static int x25_connect(struct socket *sock, struct sockaddr *uaddr,
x25_route_put(rt);
out:
release_sock(sk);
unlock_kernel();
return rc;
}

Expand Down Expand Up @@ -803,6 +818,7 @@ static int x25_accept(struct socket *sock, struct socket *newsock, int flags)
struct sk_buff *skb;
int rc = -EINVAL;

lock_kernel();
if (!sk || sk->sk_state != TCP_LISTEN)
goto out;

Expand Down Expand Up @@ -830,6 +846,7 @@ static int x25_accept(struct socket *sock, struct socket *newsock, int flags)
out2:
release_sock(sk);
out:
unlock_kernel();
return rc;
}

Expand All @@ -839,18 +856,36 @@ static int x25_getname(struct socket *sock, struct sockaddr *uaddr,
struct sockaddr_x25 *sx25 = (struct sockaddr_x25 *)uaddr;
struct sock *sk = sock->sk;
struct x25_sock *x25 = x25_sk(sk);
int rc = 0;

lock_kernel();
if (peer) {
if (sk->sk_state != TCP_ESTABLISHED)
return -ENOTCONN;
if (sk->sk_state != TCP_ESTABLISHED) {
rc = -ENOTCONN;
goto out;
}
sx25->sx25_addr = x25->dest_addr;
} else
sx25->sx25_addr = x25->source_addr;

sx25->sx25_family = AF_X25;
*uaddr_len = sizeof(*sx25);

return 0;
out:
unlock_kernel();
return rc;
}

static unsigned int x25_datagram_poll(struct file *file, struct socket *sock,
poll_table *wait)
{
int rc;

lock_kernel();
rc = datagram_poll(file, sock, wait);
unlock_kernel();

return rc;
}

int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb,
Expand Down Expand Up @@ -1003,6 +1038,7 @@ static int x25_sendmsg(struct kiocb *iocb, struct socket *sock,
size_t size;
int qbit = 0, rc = -EINVAL;

lock_kernel();
if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_OOB|MSG_EOR|MSG_CMSG_COMPAT))
goto out;

Expand Down Expand Up @@ -1167,6 +1203,7 @@ static int x25_sendmsg(struct kiocb *iocb, struct socket *sock,
release_sock(sk);
rc = len;
out:
unlock_kernel();
return rc;
out_kfree_skb:
kfree_skb(skb);
Expand All @@ -1187,6 +1224,7 @@ static int x25_recvmsg(struct kiocb *iocb, struct socket *sock,
unsigned char *asmptr;
int rc = -ENOTCONN;

lock_kernel();
/*
* This works for seqpacket too. The receiver has ordered the queue for
* us! We do one quick check first though
Expand Down Expand Up @@ -1260,6 +1298,7 @@ static int x25_recvmsg(struct kiocb *iocb, struct socket *sock,
out_free_dgram:
skb_free_datagram(sk, skb);
out:
unlock_kernel();
return rc;
}

Expand All @@ -1271,6 +1310,7 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
void __user *argp = (void __user *)arg;
int rc;

lock_kernel();
switch (cmd) {
case TIOCOUTQ: {
int amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk);
Expand Down Expand Up @@ -1473,6 +1513,7 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
rc = -ENOIOCTLCMD;
break;
}
unlock_kernel();

return rc;
}
Expand Down Expand Up @@ -1543,15 +1584,19 @@ static int compat_x25_ioctl(struct socket *sock, unsigned int cmd,
break;
case SIOCGSTAMP:
rc = -EINVAL;
lock_kernel();
if (sk)
rc = compat_sock_get_timestamp(sk,
(struct timeval __user*)argp);
unlock_kernel();
break;
case SIOCGSTAMPNS:
rc = -EINVAL;
lock_kernel();
if (sk)
rc = compat_sock_get_timestampns(sk,
(struct timespec __user*)argp);
unlock_kernel();
break;
case SIOCGIFADDR:
case SIOCSIFADDR:
Expand All @@ -1570,16 +1615,22 @@ static int compat_x25_ioctl(struct socket *sock, unsigned int cmd,
rc = -EPERM;
if (!capable(CAP_NET_ADMIN))
break;
lock_kernel();
rc = x25_route_ioctl(cmd, argp);
unlock_kernel();
break;
case SIOCX25GSUBSCRIP:
lock_kernel();
rc = compat_x25_subscr_ioctl(cmd, argp);
unlock_kernel();
break;
case SIOCX25SSUBSCRIP:
rc = -EPERM;
if (!capable(CAP_NET_ADMIN))
break;
lock_kernel();
rc = compat_x25_subscr_ioctl(cmd, argp);
unlock_kernel();
break;
case SIOCX25GFACILITIES:
case SIOCX25SFACILITIES:
Expand All @@ -1601,7 +1652,7 @@ static int compat_x25_ioctl(struct socket *sock, unsigned int cmd,
}
#endif

static const struct proto_ops SOCKOPS_WRAPPED(x25_proto_ops) = {
static const struct proto_ops x25_proto_ops = {
.family = AF_X25,
.owner = THIS_MODULE,
.release = x25_release,
Expand All @@ -1610,7 +1661,7 @@ static const struct proto_ops SOCKOPS_WRAPPED(x25_proto_ops) = {
.socketpair = sock_no_socketpair,
.accept = x25_accept,
.getname = x25_getname,
.poll = datagram_poll,
.poll = x25_datagram_poll,
.ioctl = x25_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = compat_x25_ioctl,
Expand All @@ -1625,8 +1676,6 @@ static const struct proto_ops SOCKOPS_WRAPPED(x25_proto_ops) = {
.sendpage = sock_no_sendpage,
};

SOCKOPS_WRAP(x25_proto, AF_X25);

static struct packet_type x25_packet_type __read_mostly = {
.type = cpu_to_be16(ETH_P_X25),
.func = x25_lapb_receive_frame,
Expand Down

0 comments on commit 9177490

Please sign in to comment.