]>
Commit | Line | Data |
---|---|---|
c3970671 GKH |
1 | From foo@baz Sat Mar 12 21:30:16 PST 2016 |
2 | Date: Sat, 12 Mar 2016 21:30:16 -0800 | |
3 | To: Greg KH <gregkh@linuxfoundation.org> | |
4 | From: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
5 | Subject: Revert: "crypto: af_alg - Disallow bind/setkey/... after accept(2)" | |
6 | ||
7 | This reverts commit 5a707f0972e1c9d8a4a921ddae79d0f9dc36a341 which is | |
8 | commit c840ac6af3f8713a71b4d2363419145760bd6044 upstream. | |
9 | ||
10 | It's been widely reported that this patch breaks existing userspace | |
11 | applications when backported to the stable kernel releases. As no fix | |
12 | seems to be forthcoming, just revert it to let systems work again. | |
13 | ||
14 | Reported-by: "J. Paul Reed" <preed@sigkill.com> | |
15 | Cc: Dmitry Vyukov <dvyukov@google.com> | |
16 | Cc: Herbert Xu <herbert@gondor.apana.org.au> | |
17 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
18 | --- | |
19 | crypto/af_alg.c | 35 +++-------------------------------- | |
20 | include/crypto/if_alg.h | 8 +++++--- | |
21 | 2 files changed, 8 insertions(+), 35 deletions(-) | |
22 | ||
23 | --- a/crypto/af_alg.c | |
24 | +++ b/crypto/af_alg.c | |
25 | @@ -125,23 +125,6 @@ int af_alg_release(struct socket *sock) | |
26 | } | |
27 | EXPORT_SYMBOL_GPL(af_alg_release); | |
28 | ||
29 | -void af_alg_release_parent(struct sock *sk) | |
30 | -{ | |
31 | - struct alg_sock *ask = alg_sk(sk); | |
32 | - bool last; | |
33 | - | |
34 | - sk = ask->parent; | |
35 | - ask = alg_sk(sk); | |
36 | - | |
37 | - lock_sock(sk); | |
38 | - last = !--ask->refcnt; | |
39 | - release_sock(sk); | |
40 | - | |
41 | - if (last) | |
42 | - sock_put(sk); | |
43 | -} | |
44 | -EXPORT_SYMBOL_GPL(af_alg_release_parent); | |
45 | - | |
46 | static int alg_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |
47 | { | |
48 | struct sock *sk = sock->sk; | |
49 | @@ -149,7 +132,6 @@ static int alg_bind(struct socket *sock, | |
50 | struct sockaddr_alg *sa = (void *)uaddr; | |
51 | const struct af_alg_type *type; | |
52 | void *private; | |
53 | - int err; | |
54 | ||
55 | if (sock->state == SS_CONNECTED) | |
56 | return -EINVAL; | |
57 | @@ -175,22 +157,16 @@ static int alg_bind(struct socket *sock, | |
58 | return PTR_ERR(private); | |
59 | } | |
60 | ||
61 | - err = -EBUSY; | |
62 | lock_sock(sk); | |
63 | - if (ask->refcnt) | |
64 | - goto unlock; | |
65 | ||
66 | swap(ask->type, type); | |
67 | swap(ask->private, private); | |
68 | ||
69 | - err = 0; | |
70 | - | |
71 | -unlock: | |
72 | release_sock(sk); | |
73 | ||
74 | alg_do_release(type, private); | |
75 | ||
76 | - return err; | |
77 | + return 0; | |
78 | } | |
79 | ||
80 | static int alg_setkey(struct sock *sk, char __user *ukey, | |
81 | @@ -223,15 +199,11 @@ static int alg_setsockopt(struct socket | |
82 | struct sock *sk = sock->sk; | |
83 | struct alg_sock *ask = alg_sk(sk); | |
84 | const struct af_alg_type *type; | |
85 | - int err = -EBUSY; | |
86 | + int err = -ENOPROTOOPT; | |
87 | ||
88 | lock_sock(sk); | |
89 | - if (ask->refcnt) | |
90 | - goto unlock; | |
91 | - | |
92 | type = ask->type; | |
93 | ||
94 | - err = -ENOPROTOOPT; | |
95 | if (level != SOL_ALG || !type) | |
96 | goto unlock; | |
97 | ||
98 | @@ -280,8 +252,7 @@ int af_alg_accept(struct sock *sk, struc | |
99 | ||
100 | sk2->sk_family = PF_ALG; | |
101 | ||
102 | - if (!ask->refcnt++) | |
103 | - sock_hold(sk); | |
104 | + sock_hold(sk); | |
105 | alg_sk(sk2)->parent = sk; | |
106 | alg_sk(sk2)->type = type; | |
107 | ||
108 | --- a/include/crypto/if_alg.h | |
109 | +++ b/include/crypto/if_alg.h | |
110 | @@ -30,8 +30,6 @@ struct alg_sock { | |
111 | ||
112 | struct sock *parent; | |
113 | ||
114 | - unsigned int refcnt; | |
115 | - | |
116 | const struct af_alg_type *type; | |
117 | void *private; | |
118 | }; | |
119 | @@ -66,7 +64,6 @@ int af_alg_register_type(const struct af | |
120 | int af_alg_unregister_type(const struct af_alg_type *type); | |
121 | ||
122 | int af_alg_release(struct socket *sock); | |
123 | -void af_alg_release_parent(struct sock *sk); | |
124 | int af_alg_accept(struct sock *sk, struct socket *newsock); | |
125 | ||
126 | int af_alg_make_sg(struct af_alg_sgl *sgl, void __user *addr, int len, | |
127 | @@ -83,6 +80,11 @@ static inline struct alg_sock *alg_sk(st | |
128 | return (struct alg_sock *)sk; | |
129 | } | |
130 | ||
131 | +static inline void af_alg_release_parent(struct sock *sk) | |
132 | +{ | |
133 | + sock_put(alg_sk(sk)->parent); | |
134 | +} | |
135 | + | |
136 | static inline void af_alg_init_completion(struct af_alg_completion *completion) | |
137 | { | |
138 | init_completion(&completion->completion); |