diff options
author | Sebastian Siewior <sebastian@breakpoint.cc> | 2007-07-27 16:55:59 -0400 |
---|---|---|
committer | Vlad Yasevich <vladislav.yasevich@hp.com> | 2007-08-01 11:19:06 -0400 |
commit | d6f9fdaf643eca8fb49fffdd6269b78f4ef1ef86 (patch) | |
tree | 785178ed69f6e7c24f929f439bfde1972c95dce7 | |
parent | c86dabcf00f3ca167df59f3526a53b3da3ede2c8 (diff) |
sctp: try to fix readlock
unlock the reader lock in error case.
Signed-off-by: Sebastian Siewior <sebastian@breakpoint.cc>
Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com>
-rw-r--r-- | net/sctp/socket.c | 16 |
1 files changed, 11 insertions, 5 deletions
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index b31be0994572..be743d4a7c09 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -4350,7 +4350,7 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len, | |||
4350 | space_left, &bytes_copied); | 4350 | space_left, &bytes_copied); |
4351 | if (cnt < 0) { | 4351 | if (cnt < 0) { |
4352 | err = cnt; | 4352 | err = cnt; |
4353 | goto error; | 4353 | goto error_lock; |
4354 | } | 4354 | } |
4355 | goto copy_getaddrs; | 4355 | goto copy_getaddrs; |
4356 | } | 4356 | } |
@@ -4364,7 +4364,7 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len, | |||
4364 | addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len; | 4364 | addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len; |
4365 | if (space_left < addrlen) { | 4365 | if (space_left < addrlen) { |
4366 | err = -ENOMEM; /*fixme: right error?*/ | 4366 | err = -ENOMEM; /*fixme: right error?*/ |
4367 | goto error; | 4367 | goto error_lock; |
4368 | } | 4368 | } |
4369 | memcpy(buf, &temp, addrlen); | 4369 | memcpy(buf, &temp, addrlen); |
4370 | buf += addrlen; | 4370 | buf += addrlen; |
@@ -4378,15 +4378,21 @@ copy_getaddrs: | |||
4378 | 4378 | ||
4379 | if (copy_to_user(to, addrs, bytes_copied)) { | 4379 | if (copy_to_user(to, addrs, bytes_copied)) { |
4380 | err = -EFAULT; | 4380 | err = -EFAULT; |
4381 | goto error; | 4381 | goto out; |
4382 | } | 4382 | } |
4383 | if (put_user(cnt, &((struct sctp_getaddrs __user *)optval)->addr_num)) { | 4383 | if (put_user(cnt, &((struct sctp_getaddrs __user *)optval)->addr_num)) { |
4384 | err = -EFAULT; | 4384 | err = -EFAULT; |
4385 | goto error; | 4385 | goto out; |
4386 | } | 4386 | } |
4387 | if (put_user(bytes_copied, optlen)) | 4387 | if (put_user(bytes_copied, optlen)) |
4388 | err = -EFAULT; | 4388 | err = -EFAULT; |
4389 | error: | 4389 | |
4390 | goto out; | ||
4391 | |||
4392 | error_lock: | ||
4393 | sctp_read_unlock(addr_lock); | ||
4394 | |||
4395 | out: | ||
4390 | kfree(addrs); | 4396 | kfree(addrs); |
4391 | return err; | 4397 | return err; |
4392 | } | 4398 | } |