From 70be998c2b44f942f11383496622500136816acb Mon Sep 17 00:00:00 2001 From: andrew hendry Date: Thu, 18 Nov 2010 13:20:57 +0000 Subject: X25: pushdown bkl in ioctls Push down the bkl in the ioctls so they can be removed one at a time. Signed-off-by: Andrew Hendry Signed-off-by: David S. Miller --- net/x25/af_x25.c | 41 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 3 deletions(-) (limited to 'net/x25/af_x25.c') diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c index f7af98dff409..c99029bc411c 100644 --- a/net/x25/af_x25.c +++ b/net/x25/af_x25.c @@ -1357,14 +1357,16 @@ 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); + int amount; + lock_kernel(); + amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk); if (amount < 0) amount = 0; rc = put_user(amount, (unsigned int __user *)argp); + unlock_kernel(); break; } @@ -1375,23 +1377,29 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) * These two are safe on a single CPU system as * only user tasks fiddle here */ + lock_kernel(); if ((skb = skb_peek(&sk->sk_receive_queue)) != NULL) amount = skb->len; rc = put_user(amount, (unsigned int __user *)argp); + unlock_kernel(); break; } case SIOCGSTAMP: rc = -EINVAL; + lock_kernel(); if (sk) rc = sock_get_timestamp(sk, (struct timeval __user *)argp); + unlock_kernel(); break; case SIOCGSTAMPNS: rc = -EINVAL; + lock_kernel(); if (sk) rc = sock_get_timestampns(sk, (struct timespec __user *)argp); + unlock_kernel(); break; case SIOCGIFADDR: case SIOCSIFADDR: @@ -1410,27 +1418,36 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) rc = -EPERM; if (!capable(CAP_NET_ADMIN)) break; + lock_kernel(); rc = x25_route_ioctl(cmd, argp); + unlock_kernel(); break; case SIOCX25GSUBSCRIP: + lock_kernel(); rc = x25_subscr_ioctl(cmd, argp); + unlock_kernel(); break; case SIOCX25SSUBSCRIP: rc = -EPERM; if (!capable(CAP_NET_ADMIN)) break; + lock_kernel(); rc = x25_subscr_ioctl(cmd, argp); + unlock_kernel(); break; case SIOCX25GFACILITIES: { struct x25_facilities fac = x25->facilities; + lock_kernel(); rc = copy_to_user(argp, &fac, sizeof(fac)) ? -EFAULT : 0; + unlock_kernel(); break; } case SIOCX25SFACILITIES: { struct x25_facilities facilities; rc = -EFAULT; + lock_kernel(); if (copy_from_user(&facilities, argp, sizeof(facilities))) break; @@ -1466,12 +1483,15 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) break; x25->facilities = facilities; rc = 0; + unlock_kernel(); break; } case SIOCX25GDTEFACILITIES: { + lock_kernel(); rc = copy_to_user(argp, &x25->dte_facilities, sizeof(x25->dte_facilities)); + unlock_kernel(); if (rc) rc = -EFAULT; break; @@ -1480,6 +1500,7 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) case SIOCX25SDTEFACILITIES: { struct x25_dte_facilities dtefacs; rc = -EFAULT; + lock_kernel(); if (copy_from_user(&dtefacs, argp, sizeof(dtefacs))) break; rc = -EINVAL; @@ -1496,13 +1517,16 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) break; x25->dte_facilities = dtefacs; rc = 0; + unlock_kernel(); break; } case SIOCX25GCALLUSERDATA: { struct x25_calluserdata cud = x25->calluserdata; + lock_kernel(); rc = copy_to_user(argp, &cud, sizeof(cud)) ? -EFAULT : 0; + unlock_kernel(); break; } @@ -1510,6 +1534,7 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) struct x25_calluserdata calluserdata; rc = -EFAULT; + lock_kernel(); if (copy_from_user(&calluserdata, argp, sizeof(calluserdata))) break; @@ -1517,24 +1542,29 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) if (calluserdata.cudlength > X25_MAX_CUD_LEN) break; x25->calluserdata = calluserdata; + unlock_kernel(); rc = 0; break; } case SIOCX25GCAUSEDIAG: { struct x25_causediag causediag; + lock_kernel(); causediag = x25->causediag; rc = copy_to_user(argp, &causediag, sizeof(causediag)) ? -EFAULT : 0; + unlock_kernel(); break; } case SIOCX25SCAUSEDIAG: { struct x25_causediag causediag; rc = -EFAULT; + lock_kernel(); if (copy_from_user(&causediag, argp, sizeof(causediag))) break; x25->causediag = causediag; + unlock_kernel(); rc = 0; break; @@ -1543,6 +1573,7 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) case SIOCX25SCUDMATCHLEN: { struct x25_subaddr sub_addr; rc = -EINVAL; + lock_kernel(); if(sk->sk_state != TCP_CLOSE) break; rc = -EFAULT; @@ -1553,21 +1584,25 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) if(sub_addr.cudmatchlength > X25_MAX_CUD_LEN) break; x25->cudmatchlength = sub_addr.cudmatchlength; + unlock_kernel(); rc = 0; break; } case SIOCX25CALLACCPTAPPRV: { rc = -EINVAL; + lock_kernel(); if (sk->sk_state != TCP_CLOSE) break; clear_bit(X25_ACCPT_APPRV_FLAG, &x25->flags); + unlock_kernel(); rc = 0; break; } case SIOCX25SENDCALLACCPT: { rc = -EINVAL; + lock_kernel(); if (sk->sk_state != TCP_ESTABLISHED) break; /* must call accptapprv above */ @@ -1575,6 +1610,7 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) break; x25_write_internal(sk, X25_CALL_ACCEPTED); x25->state = X25_STATE_3; + unlock_kernel(); rc = 0; break; } @@ -1583,7 +1619,6 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) rc = -ENOIOCTLCMD; break; } - unlock_kernel(); return rc; } -- cgit v1.2.1 From 1ecd66bf2ce5e0f2bc72ffdeed814bb0e55a60dc Mon Sep 17 00:00:00 2001 From: andrew hendry Date: Thu, 18 Nov 2010 13:21:20 +0000 Subject: X25: remove bkl in timestamp ioctls Signed-off-by: Andrew Hendry Signed-off-by: David S. Miller --- net/x25/af_x25.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'net/x25/af_x25.c') diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c index c99029bc411c..22597838cc76 100644 --- a/net/x25/af_x25.c +++ b/net/x25/af_x25.c @@ -1387,19 +1387,15 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) case SIOCGSTAMP: rc = -EINVAL; - lock_kernel(); if (sk) rc = sock_get_timestamp(sk, (struct timeval __user *)argp); - unlock_kernel(); break; case SIOCGSTAMPNS: rc = -EINVAL; - lock_kernel(); if (sk) rc = sock_get_timestampns(sk, (struct timespec __user *)argp); - unlock_kernel(); break; case SIOCGIFADDR: case SIOCSIFADDR: @@ -1689,19 +1685,15 @@ 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: -- cgit v1.2.1 From 54aafbd4989a684ca876e49bf3e6eb931654dc02 Mon Sep 17 00:00:00 2001 From: andrew hendry Date: Thu, 18 Nov 2010 13:21:28 +0000 Subject: X25: remove bkl in inq and outq ioctls Signed-off-by: Andrew Hendry Signed-off-by: David S. Miller --- net/x25/af_x25.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'net/x25/af_x25.c') diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c index 22597838cc76..2f235a6cb3b1 100644 --- a/net/x25/af_x25.c +++ b/net/x25/af_x25.c @@ -1361,12 +1361,10 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) case TIOCOUTQ: { int amount; - lock_kernel(); amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk); if (amount < 0) amount = 0; rc = put_user(amount, (unsigned int __user *)argp); - unlock_kernel(); break; } @@ -1377,11 +1375,11 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) * These two are safe on a single CPU system as * only user tasks fiddle here */ - lock_kernel(); + lock_sock(sk); if ((skb = skb_peek(&sk->sk_receive_queue)) != NULL) amount = skb->len; + release_sock(sk); rc = put_user(amount, (unsigned int __user *)argp); - unlock_kernel(); break; } -- cgit v1.2.1 From 0670b8ae66daf1d326c7bd10e73daff5f18fcf92 Mon Sep 17 00:00:00 2001 From: andrew hendry Date: Thu, 18 Nov 2010 13:21:35 +0000 Subject: X25: remove bkl in routing ioctls Routing doesn't use the socket data and is protected by x25_route_list_lock Signed-off-by: Andrew Hendry Signed-off-by: David S. Miller --- net/x25/af_x25.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'net/x25/af_x25.c') diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c index 2f235a6cb3b1..2351aceb296d 100644 --- a/net/x25/af_x25.c +++ b/net/x25/af_x25.c @@ -1412,9 +1412,7 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) rc = -EPERM; if (!capable(CAP_NET_ADMIN)) break; - lock_kernel(); rc = x25_route_ioctl(cmd, argp); - unlock_kernel(); break; case SIOCX25GSUBSCRIP: lock_kernel(); @@ -1710,9 +1708,7 @@ 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(); -- cgit v1.2.1 From 5595a1a5997953dbd8c5df7c2f7d4b3a2eb2be4b Mon Sep 17 00:00:00 2001 From: andrew hendry Date: Thu, 25 Nov 2010 02:18:15 +0000 Subject: X25 remove bkl in subscription ioctls Signed-off-by: Andrew Hendry Signed-off-by: David S. Miller --- net/x25/af_x25.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'net/x25/af_x25.c') diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c index 2351aceb296d..45be72c3f940 100644 --- a/net/x25/af_x25.c +++ b/net/x25/af_x25.c @@ -1415,17 +1415,13 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) rc = x25_route_ioctl(cmd, argp); break; case SIOCX25GSUBSCRIP: - lock_kernel(); rc = x25_subscr_ioctl(cmd, argp); - unlock_kernel(); break; case SIOCX25SSUBSCRIP: rc = -EPERM; if (!capable(CAP_NET_ADMIN)) break; - lock_kernel(); rc = x25_subscr_ioctl(cmd, argp); - unlock_kernel(); break; case SIOCX25GFACILITIES: { struct x25_facilities fac = x25->facilities; @@ -1646,16 +1642,20 @@ static int compat_x25_subscr_ioctl(unsigned int cmd, dev_put(dev); if (cmd == SIOCX25GSUBSCRIP) { + read_lock_bh(&x25_neigh_list_lock); x25_subscr.extended = nb->extended; x25_subscr.global_facil_mask = nb->global_facil_mask; + read_unlock_bh(&x25_neigh_list_lock); rc = copy_to_user(x25_subscr32, &x25_subscr, sizeof(*x25_subscr32)) ? -EFAULT : 0; } else { rc = -EINVAL; if (x25_subscr.extended == 0 || x25_subscr.extended == 1) { rc = 0; + write_lock_bh(&x25_neigh_list_lock); nb->extended = x25_subscr.extended; nb->global_facil_mask = x25_subscr.global_facil_mask; + write_unlock_bh(&x25_neigh_list_lock); } } x25_neigh_put(nb); @@ -1711,17 +1711,13 @@ static int compat_x25_ioctl(struct socket *sock, unsigned int cmd, rc = x25_route_ioctl(cmd, argp); 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: -- cgit v1.2.1 From f90de660678cf553f63c387945830a2e4d26dd3e Mon Sep 17 00:00:00 2001 From: andrew hendry Date: Thu, 25 Nov 2010 02:18:35 +0000 Subject: X25 remove bkl in facility ioctls Signed-off-by: Andrew Hendry Signed-off-by: David S. Miller --- net/x25/af_x25.c | 48 +++++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 23 deletions(-) (limited to 'net/x25/af_x25.c') diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c index 45be72c3f940..2518efae8ec9 100644 --- a/net/x25/af_x25.c +++ b/net/x25/af_x25.c @@ -1424,34 +1424,34 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) rc = x25_subscr_ioctl(cmd, argp); break; case SIOCX25GFACILITIES: { - struct x25_facilities fac = x25->facilities; - lock_kernel(); - rc = copy_to_user(argp, &fac, - sizeof(fac)) ? -EFAULT : 0; - unlock_kernel(); + lock_sock(sk); + rc = copy_to_user(argp, &x25->facilities, + sizeof(x25->facilities)) + ? -EFAULT : 0; + release_sock(sk); break; } case SIOCX25SFACILITIES: { struct x25_facilities facilities; rc = -EFAULT; - lock_kernel(); if (copy_from_user(&facilities, argp, sizeof(facilities))) break; rc = -EINVAL; + lock_sock(sk); if (sk->sk_state != TCP_LISTEN && sk->sk_state != TCP_CLOSE) - break; + goto out_fac_release; if (facilities.pacsize_in < X25_PS16 || facilities.pacsize_in > X25_PS4096) - break; + goto out_fac_release; if (facilities.pacsize_out < X25_PS16 || facilities.pacsize_out > X25_PS4096) - break; + goto out_fac_release; if (facilities.winsize_in < 1 || facilities.winsize_in > 127) - break; + goto out_fac_release; if (facilities.throughput) { int out = facilities.throughput & 0xf0; int in = facilities.throughput & 0x0f; @@ -1459,27 +1459,28 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) facilities.throughput |= X25_DEFAULT_THROUGHPUT << 4; else if (out < 0x30 || out > 0xD0) - break; + goto out_fac_release; if (!in) facilities.throughput |= X25_DEFAULT_THROUGHPUT; else if (in < 0x03 || in > 0x0D) - break; + goto out_fac_release; } if (facilities.reverse && (facilities.reverse & 0x81) != 0x81) - break; + goto out_fac_release; x25->facilities = facilities; rc = 0; - unlock_kernel(); +out_fac_release: + release_sock(sk); break; } case SIOCX25GDTEFACILITIES: { - lock_kernel(); + lock_sock(sk); rc = copy_to_user(argp, &x25->dte_facilities, sizeof(x25->dte_facilities)); - unlock_kernel(); + release_sock(sk); if (rc) rc = -EFAULT; break; @@ -1488,24 +1489,25 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) case SIOCX25SDTEFACILITIES: { struct x25_dte_facilities dtefacs; rc = -EFAULT; - lock_kernel(); if (copy_from_user(&dtefacs, argp, sizeof(dtefacs))) break; rc = -EINVAL; + lock_sock(sk); if (sk->sk_state != TCP_LISTEN && sk->sk_state != TCP_CLOSE) - break; + goto out_dtefac_release; if (dtefacs.calling_len > X25_MAX_AE_LEN) - break; + goto out_dtefac_release; if (dtefacs.calling_ae == NULL) - break; + goto out_dtefac_release; if (dtefacs.called_len > X25_MAX_AE_LEN) - break; + goto out_dtefac_release; if (dtefacs.called_ae == NULL) - break; + goto out_dtefac_release; x25->dte_facilities = dtefacs; rc = 0; - unlock_kernel(); +out_dtefac_release: + release_sock(sk); break; } -- cgit v1.2.1 From 5b7958dfa5db758e36e92e1790075b470b4947f8 Mon Sep 17 00:00:00 2001 From: andrew hendry Date: Thu, 25 Nov 2010 02:18:40 +0000 Subject: X25 remove bkl from calluserdata ioctls Signed-off-by: Andrew Hendry Signed-off-by: David S. Miller --- net/x25/af_x25.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'net/x25/af_x25.c') diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c index 2518efae8ec9..e2eea0aec466 100644 --- a/net/x25/af_x25.c +++ b/net/x25/af_x25.c @@ -1512,11 +1512,11 @@ out_dtefac_release: } case SIOCX25GCALLUSERDATA: { - struct x25_calluserdata cud = x25->calluserdata; - lock_kernel(); - rc = copy_to_user(argp, &cud, - sizeof(cud)) ? -EFAULT : 0; - unlock_kernel(); + lock_sock(sk); + rc = copy_to_user(argp, &x25->calluserdata, + sizeof(x25->calluserdata)) + ? -EFAULT : 0; + release_sock(sk); break; } @@ -1524,15 +1524,15 @@ out_dtefac_release: struct x25_calluserdata calluserdata; rc = -EFAULT; - lock_kernel(); if (copy_from_user(&calluserdata, argp, sizeof(calluserdata))) break; rc = -EINVAL; if (calluserdata.cudlength > X25_MAX_CUD_LEN) break; + lock_sock(sk); x25->calluserdata = calluserdata; - unlock_kernel(); + release_sock(sk); rc = 0; break; } -- cgit v1.2.1 From 74a7e440807d34e586e9feb8e14851b5c80fbfe5 Mon Sep 17 00:00:00 2001 From: andrew hendry Date: Thu, 25 Nov 2010 02:18:43 +0000 Subject: X25 remove bkl from causediag ioctls Signed-off-by: Andrew Hendry Signed-off-by: David S. Miller --- net/x25/af_x25.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'net/x25/af_x25.c') diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c index e2eea0aec466..8cfc419cef4b 100644 --- a/net/x25/af_x25.c +++ b/net/x25/af_x25.c @@ -1538,23 +1538,22 @@ out_dtefac_release: } case SIOCX25GCAUSEDIAG: { - struct x25_causediag causediag; - lock_kernel(); - causediag = x25->causediag; - rc = copy_to_user(argp, &causediag, - sizeof(causediag)) ? -EFAULT : 0; - unlock_kernel(); + lock_sock(sk); + rc = copy_to_user(argp, &x25->causediag, + sizeof(x25->causediag)) + ? -EFAULT : 0; + release_sock(sk); break; } case SIOCX25SCAUSEDIAG: { struct x25_causediag causediag; rc = -EFAULT; - lock_kernel(); if (copy_from_user(&causediag, argp, sizeof(causediag))) break; + lock_sock(sk); x25->causediag = causediag; - unlock_kernel(); + release_sock(sk); rc = 0; break; -- cgit v1.2.1 From 3f0a069a1d5c0ccace735e3a62c1bcef53e4c354 Mon Sep 17 00:00:00 2001 From: andrew hendry Date: Thu, 25 Nov 2010 02:18:45 +0000 Subject: X25 remove bkl in call user data length ioctl Signed-off-by: Andrew Hendry Signed-off-by: David S. Miller --- net/x25/af_x25.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'net/x25/af_x25.c') diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c index 8cfc419cef4b..ad96ee90fe27 100644 --- a/net/x25/af_x25.c +++ b/net/x25/af_x25.c @@ -1562,19 +1562,20 @@ out_dtefac_release: case SIOCX25SCUDMATCHLEN: { struct x25_subaddr sub_addr; rc = -EINVAL; - lock_kernel(); + lock_sock(sk); if(sk->sk_state != TCP_CLOSE) - break; + goto out_cud_release; rc = -EFAULT; if (copy_from_user(&sub_addr, argp, sizeof(sub_addr))) - break; + goto out_cud_release; rc = -EINVAL; if(sub_addr.cudmatchlength > X25_MAX_CUD_LEN) - break; + goto out_cud_release; x25->cudmatchlength = sub_addr.cudmatchlength; - unlock_kernel(); rc = 0; +out_cud_release: + release_sock(sk); break; } -- cgit v1.2.1