summaryrefslogtreecommitdiffstats
path: root/net/atm/svc.c
diff options
context:
space:
mode:
authorStefan Hajnoczi <stefanha@redhat.com>2016-05-19 02:42:13 +0200
committerDavid S. Miller <davem@davemloft.net>2016-05-23 22:51:10 +0200
commitc685293aa379b9d17e44fcc2f96a402b7648e838 (patch)
tree7c20c6c980b5df0c3d003eac0f13a0f087d6ecbb /net/atm/svc.c
parentnet: pegasus: simplify logical constraint (diff)
downloadlinux-c685293aa379b9d17e44fcc2f96a402b7648e838.tar.xz
linux-c685293aa379b9d17e44fcc2f96a402b7648e838.zip
net/atm: sk_err_soft must be positive
The sk_err and sk_err_soft fields are positive errno values and userspace applications rely on this when using getsockopt(SO_ERROR). ATM code places an -errno into sk_err_soft in sigd_send() and returns it from svc_addparty()/svc_dropparty(). Although I am not familiar with ATM code I came to this conclusion because: 1. sigd_send() msg->type cases as_okay and as_error both have: sk->sk_err = -msg->reply; while the as_addparty and as_dropparty cases have: sk->sk_err_soft = msg->reply; This is the source of the inconsistency. 2. svc_addparty() returns an -errno and assumes sk_err_soft is also an -errno: if (flags & O_NONBLOCK) { error = -EINPROGRESS; goto out; } ... error = xchg(&sk->sk_err_soft, 0); out: release_sock(sk); return error; This shows that sk_err_soft is indeed being treated as an -errno. This patch ensures that sk_err_soft is always a positive errno. Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/atm/svc.c')
-rw-r--r--net/atm/svc.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/net/atm/svc.c b/net/atm/svc.c
index 3fa0a9ee98d1..878563a8354d 100644
--- a/net/atm/svc.c
+++ b/net/atm/svc.c
@@ -546,7 +546,7 @@ static int svc_addparty(struct socket *sock, struct sockaddr *sockaddr,
schedule();
}
finish_wait(sk_sleep(sk), &wait);
- error = xchg(&sk->sk_err_soft, 0);
+ error = -xchg(&sk->sk_err_soft, 0);
out:
release_sock(sk);
return error;
@@ -573,7 +573,7 @@ static int svc_dropparty(struct socket *sock, int ep_ref)
error = -EUNATCH;
goto out;
}
- error = xchg(&sk->sk_err_soft, 0);
+ error = -xchg(&sk->sk_err_soft, 0);
out:
release_sock(sk);
return error;