Commit 91774904 authored by Arnd Bergmann's avatar Arnd Bergmann Committed by David S. Miller

net/x25: push BKL usage into x25_proto

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: default avatarArnd Bergmann <arnd@arndb.de>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 58a9d732
...@@ -415,6 +415,7 @@ static int x25_setsockopt(struct socket *sock, int level, int optname, ...@@ -415,6 +415,7 @@ static int x25_setsockopt(struct socket *sock, int level, int optname,
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
int rc = -ENOPROTOOPT; int rc = -ENOPROTOOPT;
lock_kernel();
if (level != SOL_X25 || optname != X25_QBITINCL) if (level != SOL_X25 || optname != X25_QBITINCL)
goto out; goto out;
...@@ -429,6 +430,7 @@ static int x25_setsockopt(struct socket *sock, int level, int optname, ...@@ -429,6 +430,7 @@ static int x25_setsockopt(struct socket *sock, int level, int optname,
x25_sk(sk)->qbitincl = !!opt; x25_sk(sk)->qbitincl = !!opt;
rc = 0; rc = 0;
out: out:
unlock_kernel();
return rc; return rc;
} }
...@@ -438,6 +440,7 @@ static int x25_getsockopt(struct socket *sock, int level, int optname, ...@@ -438,6 +440,7 @@ static int x25_getsockopt(struct socket *sock, int level, int optname,
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
int val, len, rc = -ENOPROTOOPT; int val, len, rc = -ENOPROTOOPT;
lock_kernel();
if (level != SOL_X25 || optname != X25_QBITINCL) if (level != SOL_X25 || optname != X25_QBITINCL)
goto out; goto out;
...@@ -458,6 +461,7 @@ static int x25_getsockopt(struct socket *sock, int level, int optname, ...@@ -458,6 +461,7 @@ static int x25_getsockopt(struct socket *sock, int level, int optname,
val = x25_sk(sk)->qbitincl; val = x25_sk(sk)->qbitincl;
rc = copy_to_user(optval, &val, len) ? -EFAULT : 0; rc = copy_to_user(optval, &val, len) ? -EFAULT : 0;
out: out:
unlock_kernel();
return rc; return rc;
} }
...@@ -466,12 +470,14 @@ static int x25_listen(struct socket *sock, int backlog) ...@@ -466,12 +470,14 @@ static int x25_listen(struct socket *sock, int backlog)
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
int rc = -EOPNOTSUPP; int rc = -EOPNOTSUPP;
lock_kernel();
if (sk->sk_state != TCP_LISTEN) { if (sk->sk_state != TCP_LISTEN) {
memset(&x25_sk(sk)->dest_addr, 0, X25_ADDR_LEN); memset(&x25_sk(sk)->dest_addr, 0, X25_ADDR_LEN);
sk->sk_max_ack_backlog = backlog; sk->sk_max_ack_backlog = backlog;
sk->sk_state = TCP_LISTEN; sk->sk_state = TCP_LISTEN;
rc = 0; rc = 0;
} }
unlock_kernel();
return rc; return rc;
} }
...@@ -598,6 +604,7 @@ static int x25_release(struct socket *sock) ...@@ -598,6 +604,7 @@ static int x25_release(struct socket *sock)
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
struct x25_sock *x25; struct x25_sock *x25;
lock_kernel();
if (!sk) if (!sk)
goto out; goto out;
...@@ -628,6 +635,7 @@ static int x25_release(struct socket *sock) ...@@ -628,6 +635,7 @@ static int x25_release(struct socket *sock)
sock_orphan(sk); sock_orphan(sk);
out: out:
unlock_kernel();
return 0; return 0;
} }
...@@ -635,18 +643,23 @@ static int x25_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) ...@@ -635,18 +643,23 @@ static int x25_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
{ {
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
struct sockaddr_x25 *addr = (struct sockaddr_x25 *)uaddr; struct sockaddr_x25 *addr = (struct sockaddr_x25 *)uaddr;
int rc = 0;
lock_kernel();
if (!sock_flag(sk, SOCK_ZAPPED) || if (!sock_flag(sk, SOCK_ZAPPED) ||
addr_len != sizeof(struct sockaddr_x25) || addr_len != sizeof(struct sockaddr_x25) ||
addr->sx25_family != AF_X25) addr->sx25_family != AF_X25) {
return -EINVAL; rc = -EINVAL;
goto out;
}
x25_sk(sk)->source_addr = addr->sx25_addr; x25_sk(sk)->source_addr = addr->sx25_addr;
x25_insert_socket(sk); x25_insert_socket(sk);
sock_reset_flag(sk, SOCK_ZAPPED); sock_reset_flag(sk, SOCK_ZAPPED);
SOCK_DEBUG(sk, "x25_bind: socket is bound\n"); SOCK_DEBUG(sk, "x25_bind: socket is bound\n");
out:
return 0; unlock_kernel();
return rc;
} }
static int x25_wait_for_connection_establishment(struct sock *sk) static int x25_wait_for_connection_establishment(struct sock *sk)
...@@ -687,6 +700,7 @@ static int x25_connect(struct socket *sock, struct sockaddr *uaddr, ...@@ -687,6 +700,7 @@ static int x25_connect(struct socket *sock, struct sockaddr *uaddr,
struct x25_route *rt; struct x25_route *rt;
int rc = 0; int rc = 0;
lock_kernel();
lock_sock(sk); lock_sock(sk);
if (sk->sk_state == TCP_ESTABLISHED && sock->state == SS_CONNECTING) { if (sk->sk_state == TCP_ESTABLISHED && sock->state == SS_CONNECTING) {
sock->state = SS_CONNECTED; sock->state = SS_CONNECTED;
...@@ -764,6 +778,7 @@ static int x25_connect(struct socket *sock, struct sockaddr *uaddr, ...@@ -764,6 +778,7 @@ static int x25_connect(struct socket *sock, struct sockaddr *uaddr,
x25_route_put(rt); x25_route_put(rt);
out: out:
release_sock(sk); release_sock(sk);
unlock_kernel();
return rc; return rc;
} }
...@@ -803,6 +818,7 @@ static int x25_accept(struct socket *sock, struct socket *newsock, int flags) ...@@ -803,6 +818,7 @@ static int x25_accept(struct socket *sock, struct socket *newsock, int flags)
struct sk_buff *skb; struct sk_buff *skb;
int rc = -EINVAL; int rc = -EINVAL;
lock_kernel();
if (!sk || sk->sk_state != TCP_LISTEN) if (!sk || sk->sk_state != TCP_LISTEN)
goto out; goto out;
...@@ -830,6 +846,7 @@ static int x25_accept(struct socket *sock, struct socket *newsock, int flags) ...@@ -830,6 +846,7 @@ static int x25_accept(struct socket *sock, struct socket *newsock, int flags)
out2: out2:
release_sock(sk); release_sock(sk);
out: out:
unlock_kernel();
return rc; return rc;
} }
...@@ -839,10 +856,14 @@ static int x25_getname(struct socket *sock, struct sockaddr *uaddr, ...@@ -839,10 +856,14 @@ static int x25_getname(struct socket *sock, struct sockaddr *uaddr,
struct sockaddr_x25 *sx25 = (struct sockaddr_x25 *)uaddr; struct sockaddr_x25 *sx25 = (struct sockaddr_x25 *)uaddr;
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
struct x25_sock *x25 = x25_sk(sk); struct x25_sock *x25 = x25_sk(sk);
int rc = 0;
lock_kernel();
if (peer) { if (peer) {
if (sk->sk_state != TCP_ESTABLISHED) if (sk->sk_state != TCP_ESTABLISHED) {
return -ENOTCONN; rc = -ENOTCONN;
goto out;
}
sx25->sx25_addr = x25->dest_addr; sx25->sx25_addr = x25->dest_addr;
} else } else
sx25->sx25_addr = x25->source_addr; sx25->sx25_addr = x25->source_addr;
...@@ -850,7 +871,21 @@ static int x25_getname(struct socket *sock, struct sockaddr *uaddr, ...@@ -850,7 +871,21 @@ static int x25_getname(struct socket *sock, struct sockaddr *uaddr,
sx25->sx25_family = AF_X25; sx25->sx25_family = AF_X25;
*uaddr_len = sizeof(*sx25); *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, int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb,
...@@ -1003,6 +1038,7 @@ static int x25_sendmsg(struct kiocb *iocb, struct socket *sock, ...@@ -1003,6 +1038,7 @@ static int x25_sendmsg(struct kiocb *iocb, struct socket *sock,
size_t size; size_t size;
int qbit = 0, rc = -EINVAL; int qbit = 0, rc = -EINVAL;
lock_kernel();
if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_OOB|MSG_EOR|MSG_CMSG_COMPAT)) if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_OOB|MSG_EOR|MSG_CMSG_COMPAT))
goto out; goto out;
...@@ -1167,6 +1203,7 @@ static int x25_sendmsg(struct kiocb *iocb, struct socket *sock, ...@@ -1167,6 +1203,7 @@ static int x25_sendmsg(struct kiocb *iocb, struct socket *sock,
release_sock(sk); release_sock(sk);
rc = len; rc = len;
out: out:
unlock_kernel();
return rc; return rc;
out_kfree_skb: out_kfree_skb:
kfree_skb(skb); kfree_skb(skb);
...@@ -1187,6 +1224,7 @@ static int x25_recvmsg(struct kiocb *iocb, struct socket *sock, ...@@ -1187,6 +1224,7 @@ static int x25_recvmsg(struct kiocb *iocb, struct socket *sock,
unsigned char *asmptr; unsigned char *asmptr;
int rc = -ENOTCONN; int rc = -ENOTCONN;
lock_kernel();
/* /*
* This works for seqpacket too. The receiver has ordered the queue for * This works for seqpacket too. The receiver has ordered the queue for
* us! We do one quick check first though * us! We do one quick check first though
...@@ -1260,6 +1298,7 @@ static int x25_recvmsg(struct kiocb *iocb, struct socket *sock, ...@@ -1260,6 +1298,7 @@ static int x25_recvmsg(struct kiocb *iocb, struct socket *sock,
out_free_dgram: out_free_dgram:
skb_free_datagram(sk, skb); skb_free_datagram(sk, skb);
out: out:
unlock_kernel();
return rc; return rc;
} }
...@@ -1271,6 +1310,7 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) ...@@ -1271,6 +1310,7 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
void __user *argp = (void __user *)arg; void __user *argp = (void __user *)arg;
int rc; int rc;
lock_kernel();
switch (cmd) { switch (cmd) {
case TIOCOUTQ: { case TIOCOUTQ: {
int amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk); int amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk);
...@@ -1473,6 +1513,7 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) ...@@ -1473,6 +1513,7 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
rc = -ENOIOCTLCMD; rc = -ENOIOCTLCMD;
break; break;
} }
unlock_kernel();
return rc; return rc;
} }
...@@ -1543,15 +1584,19 @@ static int compat_x25_ioctl(struct socket *sock, unsigned int cmd, ...@@ -1543,15 +1584,19 @@ static int compat_x25_ioctl(struct socket *sock, unsigned int cmd,
break; break;
case SIOCGSTAMP: case SIOCGSTAMP:
rc = -EINVAL; rc = -EINVAL;
lock_kernel();
if (sk) if (sk)
rc = compat_sock_get_timestamp(sk, rc = compat_sock_get_timestamp(sk,
(struct timeval __user*)argp); (struct timeval __user*)argp);
unlock_kernel();
break; break;
case SIOCGSTAMPNS: case SIOCGSTAMPNS:
rc = -EINVAL; rc = -EINVAL;
lock_kernel();
if (sk) if (sk)
rc = compat_sock_get_timestampns(sk, rc = compat_sock_get_timestampns(sk,
(struct timespec __user*)argp); (struct timespec __user*)argp);
unlock_kernel();
break; break;
case SIOCGIFADDR: case SIOCGIFADDR:
case SIOCSIFADDR: case SIOCSIFADDR:
...@@ -1570,16 +1615,22 @@ static int compat_x25_ioctl(struct socket *sock, unsigned int cmd, ...@@ -1570,16 +1615,22 @@ static int compat_x25_ioctl(struct socket *sock, unsigned int cmd,
rc = -EPERM; rc = -EPERM;
if (!capable(CAP_NET_ADMIN)) if (!capable(CAP_NET_ADMIN))
break; break;
lock_kernel();
rc = x25_route_ioctl(cmd, argp); rc = x25_route_ioctl(cmd, argp);
unlock_kernel();
break; break;
case SIOCX25GSUBSCRIP: case SIOCX25GSUBSCRIP:
lock_kernel();
rc = compat_x25_subscr_ioctl(cmd, argp); rc = compat_x25_subscr_ioctl(cmd, argp);
unlock_kernel();
break; break;
case SIOCX25SSUBSCRIP: case SIOCX25SSUBSCRIP:
rc = -EPERM; rc = -EPERM;
if (!capable(CAP_NET_ADMIN)) if (!capable(CAP_NET_ADMIN))
break; break;
lock_kernel();
rc = compat_x25_subscr_ioctl(cmd, argp); rc = compat_x25_subscr_ioctl(cmd, argp);
unlock_kernel();
break; break;
case SIOCX25GFACILITIES: case SIOCX25GFACILITIES:
case SIOCX25SFACILITIES: case SIOCX25SFACILITIES:
...@@ -1601,7 +1652,7 @@ static int compat_x25_ioctl(struct socket *sock, unsigned int cmd, ...@@ -1601,7 +1652,7 @@ static int compat_x25_ioctl(struct socket *sock, unsigned int cmd,
} }
#endif #endif
static const struct proto_ops SOCKOPS_WRAPPED(x25_proto_ops) = { static const struct proto_ops x25_proto_ops = {
.family = AF_X25, .family = AF_X25,
.owner = THIS_MODULE, .owner = THIS_MODULE,
.release = x25_release, .release = x25_release,
...@@ -1610,7 +1661,7 @@ static const struct proto_ops SOCKOPS_WRAPPED(x25_proto_ops) = { ...@@ -1610,7 +1661,7 @@ static const struct proto_ops SOCKOPS_WRAPPED(x25_proto_ops) = {
.socketpair = sock_no_socketpair, .socketpair = sock_no_socketpair,
.accept = x25_accept, .accept = x25_accept,
.getname = x25_getname, .getname = x25_getname,
.poll = datagram_poll, .poll = x25_datagram_poll,
.ioctl = x25_ioctl, .ioctl = x25_ioctl,
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
.compat_ioctl = compat_x25_ioctl, .compat_ioctl = compat_x25_ioctl,
...@@ -1625,8 +1676,6 @@ static const struct proto_ops SOCKOPS_WRAPPED(x25_proto_ops) = { ...@@ -1625,8 +1676,6 @@ static const struct proto_ops SOCKOPS_WRAPPED(x25_proto_ops) = {
.sendpage = sock_no_sendpage, .sendpage = sock_no_sendpage,
}; };
SOCKOPS_WRAP(x25_proto, AF_X25);
static struct packet_type x25_packet_type __read_mostly = { static struct packet_type x25_packet_type __read_mostly = {
.type = cpu_to_be16(ETH_P_X25), .type = cpu_to_be16(ETH_P_X25),
.func = x25_lapb_receive_frame, .func = x25_lapb_receive_frame,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment