diff options
author | Mike Christie <michaelc@cs.wisc.edu> | 2006-02-01 22:07:01 -0500 |
---|---|---|
committer | <jejb@mulgrave.il.steeleye.com> | 2006-02-04 17:18:51 -0500 |
commit | ee7f8e405342722e42c15fe8e841a679f8951eea (patch) | |
tree | 3b21836a9bee874442817ac8f4433f552c6ccb26 /drivers/scsi | |
parent | 142e301fc818de9b116706835cd9fc864e73f203 (diff) |
[SCSI] iscsi update: set deamon pid earlier
>From michaelc@cs.wisc.edu:
If the transport lookup fails we set the daemon pid too late.
This can cause us deadlock since the netlink code will think we
meant to call back into our iscsi_if_rx function.
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: Alex Aizman <itn780@yahoo.com>
Signed-off-by: Dmitry Yusupov <dmitry_yus@yahoo.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/scsi_transport_iscsi.c | 16 |
1 files changed, 10 insertions, 6 deletions
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index 448fd78777f9..7fb69183c72d 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c | |||
@@ -846,9 +846,6 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
846 | struct iscsi_cls_session *session; | 846 | struct iscsi_cls_session *session; |
847 | struct iscsi_cls_conn *conn; | 847 | struct iscsi_cls_conn *conn; |
848 | 848 | ||
849 | if (NETLINK_CREDS(skb)->uid) | ||
850 | return -EPERM; | ||
851 | |||
852 | priv = iscsi_if_transport_lookup(iscsi_ptr(ev->transport_handle)); | 849 | priv = iscsi_if_transport_lookup(iscsi_ptr(ev->transport_handle)); |
853 | if (!priv) | 850 | if (!priv) |
854 | return -EINVAL; | 851 | return -EINVAL; |
@@ -857,8 +854,6 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
857 | if (!try_module_get(transport->owner)) | 854 | if (!try_module_get(transport->owner)) |
858 | return -EINVAL; | 855 | return -EINVAL; |
859 | 856 | ||
860 | daemon_pid = NETLINK_CREDS(skb)->pid; | ||
861 | |||
862 | switch (nlh->nlmsg_type) { | 857 | switch (nlh->nlmsg_type) { |
863 | case ISCSI_UEVENT_CREATE_SESSION: | 858 | case ISCSI_UEVENT_CREATE_SESSION: |
864 | err = iscsi_if_create_session(priv, ev); | 859 | err = iscsi_if_create_session(priv, ev); |
@@ -934,7 +929,7 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
934 | 929 | ||
935 | /* Get message from skb (based on rtnetlink_rcv_skb). Each message is | 930 | /* Get message from skb (based on rtnetlink_rcv_skb). Each message is |
936 | * processed by iscsi_if_recv_msg. Malformed skbs with wrong length are | 931 | * processed by iscsi_if_recv_msg. Malformed skbs with wrong length are |
937 | * discarded silently. */ | 932 | * or invalid creds discarded silently. */ |
938 | static void | 933 | static void |
939 | iscsi_if_rx(struct sock *sk, int len) | 934 | iscsi_if_rx(struct sock *sk, int len) |
940 | { | 935 | { |
@@ -942,6 +937,12 @@ iscsi_if_rx(struct sock *sk, int len) | |||
942 | 937 | ||
943 | mutex_lock(&rx_queue_mutex); | 938 | mutex_lock(&rx_queue_mutex); |
944 | while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) { | 939 | while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) { |
940 | if (NETLINK_CREDS(skb)->uid) { | ||
941 | skb_pull(skb, skb->len); | ||
942 | goto free_skb; | ||
943 | } | ||
944 | daemon_pid = NETLINK_CREDS(skb)->pid; | ||
945 | |||
945 | while (skb->len >= NLMSG_SPACE(0)) { | 946 | while (skb->len >= NLMSG_SPACE(0)) { |
946 | int err; | 947 | int err; |
947 | uint32_t rlen; | 948 | uint32_t rlen; |
@@ -953,10 +954,12 @@ iscsi_if_rx(struct sock *sk, int len) | |||
953 | skb->len < nlh->nlmsg_len) { | 954 | skb->len < nlh->nlmsg_len) { |
954 | break; | 955 | break; |
955 | } | 956 | } |
957 | |||
956 | ev = NLMSG_DATA(nlh); | 958 | ev = NLMSG_DATA(nlh); |
957 | rlen = NLMSG_ALIGN(nlh->nlmsg_len); | 959 | rlen = NLMSG_ALIGN(nlh->nlmsg_len); |
958 | if (rlen > skb->len) | 960 | if (rlen > skb->len) |
959 | rlen = skb->len; | 961 | rlen = skb->len; |
962 | |||
960 | err = iscsi_if_recv_msg(skb, nlh); | 963 | err = iscsi_if_recv_msg(skb, nlh); |
961 | if (err) { | 964 | if (err) { |
962 | ev->type = ISCSI_KEVENT_IF_ERROR; | 965 | ev->type = ISCSI_KEVENT_IF_ERROR; |
@@ -980,6 +983,7 @@ iscsi_if_rx(struct sock *sk, int len) | |||
980 | } while (err < 0 && err != -ECONNREFUSED); | 983 | } while (err < 0 && err != -ECONNREFUSED); |
981 | skb_pull(skb, rlen); | 984 | skb_pull(skb, rlen); |
982 | } | 985 | } |
986 | free_skb: | ||
983 | kfree_skb(skb); | 987 | kfree_skb(skb); |
984 | } | 988 | } |
985 | mutex_unlock(&rx_queue_mutex); | 989 | mutex_unlock(&rx_queue_mutex); |