aboutsummaryrefslogtreecommitdiffstats
path: root/net/appletalk
diff options
context:
space:
mode:
Diffstat (limited to 'net/appletalk')
-rw-r--r--net/appletalk/ddp.c105
1 files changed, 77 insertions, 28 deletions
diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c
index 7cd08b45c52b..31fca64d17a2 100644
--- a/net/appletalk/ddp.c
+++ b/net/appletalk/ddp.c
@@ -1055,11 +1055,13 @@ static int atalk_release(struct socket *sock)
1055{ 1055{
1056 struct sock *sk = sock->sk; 1056 struct sock *sk = sock->sk;
1057 1057
1058 lock_kernel();
1058 if (sk) { 1059 if (sk) {
1059 sock_orphan(sk); 1060 sock_orphan(sk);
1060 sock->sk = NULL; 1061 sock->sk = NULL;
1061 atalk_destroy_socket(sk); 1062 atalk_destroy_socket(sk);
1062 } 1063 }
1064 unlock_kernel();
1063 return 0; 1065 return 0;
1064} 1066}
1065 1067
@@ -1135,6 +1137,7 @@ static int atalk_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
1135 struct sockaddr_at *addr = (struct sockaddr_at *)uaddr; 1137 struct sockaddr_at *addr = (struct sockaddr_at *)uaddr;
1136 struct sock *sk = sock->sk; 1138 struct sock *sk = sock->sk;
1137 struct atalk_sock *at = at_sk(sk); 1139 struct atalk_sock *at = at_sk(sk);
1140 int err;
1138 1141
1139 if (!sock_flag(sk, SOCK_ZAPPED) || 1142 if (!sock_flag(sk, SOCK_ZAPPED) ||
1140 addr_len != sizeof(struct sockaddr_at)) 1143 addr_len != sizeof(struct sockaddr_at))
@@ -1143,37 +1146,44 @@ static int atalk_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
1143 if (addr->sat_family != AF_APPLETALK) 1146 if (addr->sat_family != AF_APPLETALK)
1144 return -EAFNOSUPPORT; 1147 return -EAFNOSUPPORT;
1145 1148
1149 lock_kernel();
1146 if (addr->sat_addr.s_net == htons(ATADDR_ANYNET)) { 1150 if (addr->sat_addr.s_net == htons(ATADDR_ANYNET)) {
1147 struct atalk_addr *ap = atalk_find_primary(); 1151 struct atalk_addr *ap = atalk_find_primary();
1148 1152
1153 err = -EADDRNOTAVAIL;
1149 if (!ap) 1154 if (!ap)
1150 return -EADDRNOTAVAIL; 1155 goto out;
1151 1156
1152 at->src_net = addr->sat_addr.s_net = ap->s_net; 1157 at->src_net = addr->sat_addr.s_net = ap->s_net;
1153 at->src_node = addr->sat_addr.s_node= ap->s_node; 1158 at->src_node = addr->sat_addr.s_node= ap->s_node;
1154 } else { 1159 } else {
1160 err = -EADDRNOTAVAIL;
1155 if (!atalk_find_interface(addr->sat_addr.s_net, 1161 if (!atalk_find_interface(addr->sat_addr.s_net,
1156 addr->sat_addr.s_node)) 1162 addr->sat_addr.s_node))
1157 return -EADDRNOTAVAIL; 1163 goto out;
1158 1164
1159 at->src_net = addr->sat_addr.s_net; 1165 at->src_net = addr->sat_addr.s_net;
1160 at->src_node = addr->sat_addr.s_node; 1166 at->src_node = addr->sat_addr.s_node;
1161 } 1167 }
1162 1168
1163 if (addr->sat_port == ATADDR_ANYPORT) { 1169 if (addr->sat_port == ATADDR_ANYPORT) {
1164 int n = atalk_pick_and_bind_port(sk, addr); 1170 err = atalk_pick_and_bind_port(sk, addr);
1165 1171
1166 if (n < 0) 1172 if (err < 0)
1167 return n; 1173 goto out;
1168 } else { 1174 } else {
1169 at->src_port = addr->sat_port; 1175 at->src_port = addr->sat_port;
1170 1176
1177 err = -EADDRINUSE;
1171 if (atalk_find_or_insert_socket(sk, addr)) 1178 if (atalk_find_or_insert_socket(sk, addr))
1172 return -EADDRINUSE; 1179 goto out;
1173 } 1180 }
1174 1181
1175 sock_reset_flag(sk, SOCK_ZAPPED); 1182 sock_reset_flag(sk, SOCK_ZAPPED);
1176 return 0; 1183 err = 0;
1184out:
1185 unlock_kernel();
1186 return err;
1177} 1187}
1178 1188
1179/* Set the address we talk to */ 1189/* Set the address we talk to */
@@ -1183,6 +1193,7 @@ static int atalk_connect(struct socket *sock, struct sockaddr *uaddr,
1183 struct sock *sk = sock->sk; 1193 struct sock *sk = sock->sk;
1184 struct atalk_sock *at = at_sk(sk); 1194 struct atalk_sock *at = at_sk(sk);
1185 struct sockaddr_at *addr; 1195 struct sockaddr_at *addr;
1196 int err;
1186 1197
1187 sk->sk_state = TCP_CLOSE; 1198 sk->sk_state = TCP_CLOSE;
1188 sock->state = SS_UNCONNECTED; 1199 sock->state = SS_UNCONNECTED;
@@ -1207,12 +1218,15 @@ static int atalk_connect(struct socket *sock, struct sockaddr *uaddr,
1207#endif 1218#endif
1208 } 1219 }
1209 1220
1221 lock_kernel();
1222 err = -EBUSY;
1210 if (sock_flag(sk, SOCK_ZAPPED)) 1223 if (sock_flag(sk, SOCK_ZAPPED))
1211 if (atalk_autobind(sk) < 0) 1224 if (atalk_autobind(sk) < 0)
1212 return -EBUSY; 1225 goto out;
1213 1226
1227 err = -ENETUNREACH;
1214 if (!atrtr_get_dev(&addr->sat_addr)) 1228 if (!atrtr_get_dev(&addr->sat_addr))
1215 return -ENETUNREACH; 1229 goto out;
1216 1230
1217 at->dest_port = addr->sat_port; 1231 at->dest_port = addr->sat_port;
1218 at->dest_net = addr->sat_addr.s_net; 1232 at->dest_net = addr->sat_addr.s_net;
@@ -1220,7 +1234,10 @@ static int atalk_connect(struct socket *sock, struct sockaddr *uaddr,
1220 1234
1221 sock->state = SS_CONNECTED; 1235 sock->state = SS_CONNECTED;
1222 sk->sk_state = TCP_ESTABLISHED; 1236 sk->sk_state = TCP_ESTABLISHED;
1223 return 0; 1237 err = 0;
1238out:
1239 unlock_kernel();
1240 return err;
1224} 1241}
1225 1242
1226/* 1243/*
@@ -1233,17 +1250,21 @@ static int atalk_getname(struct socket *sock, struct sockaddr *uaddr,
1233 struct sockaddr_at sat; 1250 struct sockaddr_at sat;
1234 struct sock *sk = sock->sk; 1251 struct sock *sk = sock->sk;
1235 struct atalk_sock *at = at_sk(sk); 1252 struct atalk_sock *at = at_sk(sk);
1253 int err;
1236 1254
1255 lock_kernel();
1256 err = -ENOBUFS;
1237 if (sock_flag(sk, SOCK_ZAPPED)) 1257 if (sock_flag(sk, SOCK_ZAPPED))
1238 if (atalk_autobind(sk) < 0) 1258 if (atalk_autobind(sk) < 0)
1239 return -ENOBUFS; 1259 goto out;
1240 1260
1241 *uaddr_len = sizeof(struct sockaddr_at); 1261 *uaddr_len = sizeof(struct sockaddr_at);
1242 memset(&sat.sat_zero, 0, sizeof(sat.sat_zero)); 1262 memset(&sat.sat_zero, 0, sizeof(sat.sat_zero));
1243 1263
1244 if (peer) { 1264 if (peer) {
1265 err = -ENOTCONN;
1245 if (sk->sk_state != TCP_ESTABLISHED) 1266 if (sk->sk_state != TCP_ESTABLISHED)
1246 return -ENOTCONN; 1267 goto out;
1247 1268
1248 sat.sat_addr.s_net = at->dest_net; 1269 sat.sat_addr.s_net = at->dest_net;
1249 sat.sat_addr.s_node = at->dest_node; 1270 sat.sat_addr.s_node = at->dest_node;
@@ -1254,9 +1275,23 @@ static int atalk_getname(struct socket *sock, struct sockaddr *uaddr,
1254 sat.sat_port = at->src_port; 1275 sat.sat_port = at->src_port;
1255 } 1276 }
1256 1277
1278 err = 0;
1257 sat.sat_family = AF_APPLETALK; 1279 sat.sat_family = AF_APPLETALK;
1258 memcpy(uaddr, &sat, sizeof(sat)); 1280 memcpy(uaddr, &sat, sizeof(sat));
1259 return 0; 1281
1282out:
1283 unlock_kernel();
1284 return err;
1285}
1286
1287static unsigned int atalk_poll(struct file *file, struct socket *sock,
1288 poll_table *wait)
1289{
1290 int err;
1291 lock_kernel();
1292 err = datagram_poll(file, sock, wait);
1293 unlock_kernel();
1294 return err;
1260} 1295}
1261 1296
1262#if defined(CONFIG_IPDDP) || defined(CONFIG_IPDDP_MODULE) 1297#if defined(CONFIG_IPDDP) || defined(CONFIG_IPDDP_MODULE)
@@ -1564,23 +1599,28 @@ static int atalk_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr
1564 if (len > DDP_MAXSZ) 1599 if (len > DDP_MAXSZ)
1565 return -EMSGSIZE; 1600 return -EMSGSIZE;
1566 1601
1602 lock_kernel();
1567 if (usat) { 1603 if (usat) {
1604 err = -EBUSY;
1568 if (sock_flag(sk, SOCK_ZAPPED)) 1605 if (sock_flag(sk, SOCK_ZAPPED))
1569 if (atalk_autobind(sk) < 0) 1606 if (atalk_autobind(sk) < 0)
1570 return -EBUSY; 1607 goto out;
1571 1608
1609 err = -EINVAL;
1572 if (msg->msg_namelen < sizeof(*usat) || 1610 if (msg->msg_namelen < sizeof(*usat) ||
1573 usat->sat_family != AF_APPLETALK) 1611 usat->sat_family != AF_APPLETALK)
1574 return -EINVAL; 1612 goto out;
1575 1613
1614 err = -EPERM;
1576 /* netatalk didn't implement this check */ 1615 /* netatalk didn't implement this check */
1577 if (usat->sat_addr.s_node == ATADDR_BCAST && 1616 if (usat->sat_addr.s_node == ATADDR_BCAST &&
1578 !sock_flag(sk, SOCK_BROADCAST)) { 1617 !sock_flag(sk, SOCK_BROADCAST)) {
1579 return -EPERM; 1618 goto out;
1580 } 1619 }
1581 } else { 1620 } else {
1621 err = -ENOTCONN;
1582 if (sk->sk_state != TCP_ESTABLISHED) 1622 if (sk->sk_state != TCP_ESTABLISHED)
1583 return -ENOTCONN; 1623 goto out;
1584 usat = &local_satalk; 1624 usat = &local_satalk;
1585 usat->sat_family = AF_APPLETALK; 1625 usat->sat_family = AF_APPLETALK;
1586 usat->sat_port = at->dest_port; 1626 usat->sat_port = at->dest_port;
@@ -1604,8 +1644,9 @@ static int atalk_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr
1604 1644
1605 rt = atrtr_find(&at_hint); 1645 rt = atrtr_find(&at_hint);
1606 } 1646 }
1647 err = ENETUNREACH;
1607 if (!rt) 1648 if (!rt)
1608 return -ENETUNREACH; 1649 goto out;
1609 1650
1610 dev = rt->dev; 1651 dev = rt->dev;
1611 1652
@@ -1615,7 +1656,7 @@ static int atalk_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr
1615 size += dev->hard_header_len; 1656 size += dev->hard_header_len;
1616 skb = sock_alloc_send_skb(sk, size, (flags & MSG_DONTWAIT), &err); 1657 skb = sock_alloc_send_skb(sk, size, (flags & MSG_DONTWAIT), &err);
1617 if (!skb) 1658 if (!skb)
1618 return err; 1659 goto out;
1619 1660
1620 skb->sk = sk; 1661 skb->sk = sk;
1621 skb_reserve(skb, ddp_dl->header_length); 1662 skb_reserve(skb, ddp_dl->header_length);
@@ -1638,7 +1679,8 @@ static int atalk_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr
1638 err = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len); 1679 err = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len);
1639 if (err) { 1680 if (err) {
1640 kfree_skb(skb); 1681 kfree_skb(skb);
1641 return -EFAULT; 1682 err = -EFAULT;
1683 goto out;
1642 } 1684 }
1643 1685
1644 if (sk->sk_no_check == 1) 1686 if (sk->sk_no_check == 1)
@@ -1677,7 +1719,8 @@ static int atalk_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr
1677 rt = atrtr_find(&at_lo); 1719 rt = atrtr_find(&at_lo);
1678 if (!rt) { 1720 if (!rt) {
1679 kfree_skb(skb); 1721 kfree_skb(skb);
1680 return -ENETUNREACH; 1722 err = -ENETUNREACH;
1723 goto out;
1681 } 1724 }
1682 dev = rt->dev; 1725 dev = rt->dev;
1683 skb->dev = dev; 1726 skb->dev = dev;
@@ -1697,7 +1740,9 @@ static int atalk_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr
1697 } 1740 }
1698 SOCK_DEBUG(sk, "SK %p: Done write (%Zd).\n", sk, len); 1741 SOCK_DEBUG(sk, "SK %p: Done write (%Zd).\n", sk, len);
1699 1742
1700 return len; 1743out:
1744 unlock_kernel();
1745 return err ? : len;
1701} 1746}
1702 1747
1703static int atalk_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, 1748static int atalk_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
@@ -1709,10 +1754,13 @@ static int atalk_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr
1709 int copied = 0; 1754 int copied = 0;
1710 int offset = 0; 1755 int offset = 0;
1711 int err = 0; 1756 int err = 0;
1712 struct sk_buff *skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT, 1757 struct sk_buff *skb;
1758
1759 lock_kernel();
1760 skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT,
1713 flags & MSG_DONTWAIT, &err); 1761 flags & MSG_DONTWAIT, &err);
1714 if (!skb) 1762 if (!skb)
1715 return err; 1763 goto out;
1716 1764
1717 /* FIXME: use skb->cb to be able to use shared skbs */ 1765 /* FIXME: use skb->cb to be able to use shared skbs */
1718 ddp = ddp_hdr(skb); 1766 ddp = ddp_hdr(skb);
@@ -1740,6 +1788,9 @@ static int atalk_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr
1740 } 1788 }
1741 1789
1742 skb_free_datagram(sk, skb); /* Free the datagram. */ 1790 skb_free_datagram(sk, skb); /* Free the datagram. */
1791
1792out:
1793 unlock_kernel();
1743 return err ? : copied; 1794 return err ? : copied;
1744} 1795}
1745 1796
@@ -1830,7 +1881,7 @@ static const struct net_proto_family atalk_family_ops = {
1830 .owner = THIS_MODULE, 1881 .owner = THIS_MODULE,
1831}; 1882};
1832 1883
1833static const struct proto_ops SOCKOPS_WRAPPED(atalk_dgram_ops) = { 1884static const struct proto_ops atalk_dgram_ops = {
1834 .family = PF_APPLETALK, 1885 .family = PF_APPLETALK,
1835 .owner = THIS_MODULE, 1886 .owner = THIS_MODULE,
1836 .release = atalk_release, 1887 .release = atalk_release,
@@ -1839,7 +1890,7 @@ static const struct proto_ops SOCKOPS_WRAPPED(atalk_dgram_ops) = {
1839 .socketpair = sock_no_socketpair, 1890 .socketpair = sock_no_socketpair,
1840 .accept = sock_no_accept, 1891 .accept = sock_no_accept,
1841 .getname = atalk_getname, 1892 .getname = atalk_getname,
1842 .poll = datagram_poll, 1893 .poll = atalk_poll,
1843 .ioctl = atalk_ioctl, 1894 .ioctl = atalk_ioctl,
1844#ifdef CONFIG_COMPAT 1895#ifdef CONFIG_COMPAT
1845 .compat_ioctl = atalk_compat_ioctl, 1896 .compat_ioctl = atalk_compat_ioctl,
@@ -1854,8 +1905,6 @@ static const struct proto_ops SOCKOPS_WRAPPED(atalk_dgram_ops) = {
1854 .sendpage = sock_no_sendpage, 1905 .sendpage = sock_no_sendpage,
1855}; 1906};
1856 1907
1857SOCKOPS_WRAP(atalk_dgram, PF_APPLETALK);
1858
1859static struct notifier_block ddp_notifier = { 1908static struct notifier_block ddp_notifier = {
1860 .notifier_call = ddp_device_event, 1909 .notifier_call = ddp_device_event,
1861}; 1910};