af_alg.c (01b944fe1cd4e21a2a9ed51adbdbafe2d5e905ba) | af_alg.c (c840ac6af3f8713a71b4d2363419145760bd6044) |
---|---|
1/* 2 * af_alg: User-space algorithm interface 3 * 4 * This file provides the user-space API for algorithms. 5 * 6 * Copyright (c) 2010 Herbert Xu <herbert@gondor.apana.org.au> 7 * 8 * This program is free software; you can redistribute it and/or modify it --- 111 unchanged lines hidden (view full) --- 120int af_alg_release(struct socket *sock) 121{ 122 if (sock->sk) 123 sock_put(sock->sk); 124 return 0; 125} 126EXPORT_SYMBOL_GPL(af_alg_release); 127 | 1/* 2 * af_alg: User-space algorithm interface 3 * 4 * This file provides the user-space API for algorithms. 5 * 6 * Copyright (c) 2010 Herbert Xu <herbert@gondor.apana.org.au> 7 * 8 * This program is free software; you can redistribute it and/or modify it --- 111 unchanged lines hidden (view full) --- 120int af_alg_release(struct socket *sock) 121{ 122 if (sock->sk) 123 sock_put(sock->sk); 124 return 0; 125} 126EXPORT_SYMBOL_GPL(af_alg_release); 127 |
128void af_alg_release_parent(struct sock *sk) 129{ 130 struct alg_sock *ask = alg_sk(sk); 131 bool last; 132 133 sk = ask->parent; 134 ask = alg_sk(sk); 135 136 lock_sock(sk); 137 last = !--ask->refcnt; 138 release_sock(sk); 139 140 if (last) 141 sock_put(sk); 142} 143EXPORT_SYMBOL_GPL(af_alg_release_parent); 144 |
|
128static int alg_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) 129{ 130 const u32 forbidden = CRYPTO_ALG_INTERNAL; 131 struct sock *sk = sock->sk; 132 struct alg_sock *ask = alg_sk(sk); 133 struct sockaddr_alg *sa = (void *)uaddr; 134 const struct af_alg_type *type; 135 void *private; | 145static int alg_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) 146{ 147 const u32 forbidden = CRYPTO_ALG_INTERNAL; 148 struct sock *sk = sock->sk; 149 struct alg_sock *ask = alg_sk(sk); 150 struct sockaddr_alg *sa = (void *)uaddr; 151 const struct af_alg_type *type; 152 void *private; |
153 int err; |
|
136 137 if (sock->state == SS_CONNECTED) 138 return -EINVAL; 139 140 if (addr_len != sizeof(*sa)) 141 return -EINVAL; 142 143 sa->salg_type[sizeof(sa->salg_type) - 1] = 0; --- 11 unchanged lines hidden (view full) --- 155 private = type->bind(sa->salg_name, 156 sa->salg_feat & ~forbidden, 157 sa->salg_mask & ~forbidden); 158 if (IS_ERR(private)) { 159 module_put(type->owner); 160 return PTR_ERR(private); 161 } 162 | 154 155 if (sock->state == SS_CONNECTED) 156 return -EINVAL; 157 158 if (addr_len != sizeof(*sa)) 159 return -EINVAL; 160 161 sa->salg_type[sizeof(sa->salg_type) - 1] = 0; --- 11 unchanged lines hidden (view full) --- 173 private = type->bind(sa->salg_name, 174 sa->salg_feat & ~forbidden, 175 sa->salg_mask & ~forbidden); 176 if (IS_ERR(private)) { 177 module_put(type->owner); 178 return PTR_ERR(private); 179 } 180 |
181 err = -EBUSY; |
|
163 lock_sock(sk); | 182 lock_sock(sk); |
183 if (ask->refcnt) 184 goto unlock; |
|
164 165 swap(ask->type, type); 166 swap(ask->private, private); 167 | 185 186 swap(ask->type, type); 187 swap(ask->private, private); 188 |
189 err = 0; 190 191unlock: |
|
168 release_sock(sk); 169 170 alg_do_release(type, private); 171 | 192 release_sock(sk); 193 194 alg_do_release(type, private); 195 |
172 return 0; | 196 return err; |
173} 174 175static int alg_setkey(struct sock *sk, char __user *ukey, 176 unsigned int keylen) 177{ 178 struct alg_sock *ask = alg_sk(sk); 179 const struct af_alg_type *type = ask->type; 180 u8 *key; --- 16 unchanged lines hidden (view full) --- 197} 198 199static int alg_setsockopt(struct socket *sock, int level, int optname, 200 char __user *optval, unsigned int optlen) 201{ 202 struct sock *sk = sock->sk; 203 struct alg_sock *ask = alg_sk(sk); 204 const struct af_alg_type *type; | 197} 198 199static int alg_setkey(struct sock *sk, char __user *ukey, 200 unsigned int keylen) 201{ 202 struct alg_sock *ask = alg_sk(sk); 203 const struct af_alg_type *type = ask->type; 204 u8 *key; --- 16 unchanged lines hidden (view full) --- 221} 222 223static int alg_setsockopt(struct socket *sock, int level, int optname, 224 char __user *optval, unsigned int optlen) 225{ 226 struct sock *sk = sock->sk; 227 struct alg_sock *ask = alg_sk(sk); 228 const struct af_alg_type *type; |
205 int err = -ENOPROTOOPT; | 229 int err = -EBUSY; |
206 207 lock_sock(sk); | 230 231 lock_sock(sk); |
232 if (ask->refcnt) 233 goto unlock; 234 |
|
208 type = ask->type; 209 | 235 type = ask->type; 236 |
237 err = -ENOPROTOOPT; |
|
210 if (level != SOL_ALG || !type) 211 goto unlock; 212 213 switch (optname) { 214 case ALG_SET_KEY: 215 if (sock->state == SS_CONNECTED) 216 goto unlock; 217 if (!type->setkey) --- 41 unchanged lines hidden (view full) --- 259 err = type->accept(ask->private, sk2); 260 if (err) { 261 sk_free(sk2); 262 goto unlock; 263 } 264 265 sk2->sk_family = PF_ALG; 266 | 238 if (level != SOL_ALG || !type) 239 goto unlock; 240 241 switch (optname) { 242 case ALG_SET_KEY: 243 if (sock->state == SS_CONNECTED) 244 goto unlock; 245 if (!type->setkey) --- 41 unchanged lines hidden (view full) --- 287 err = type->accept(ask->private, sk2); 288 if (err) { 289 sk_free(sk2); 290 goto unlock; 291 } 292 293 sk2->sk_family = PF_ALG; 294 |
267 sock_hold(sk); | 295 if (!ask->refcnt++) 296 sock_hold(sk); |
268 alg_sk(sk2)->parent = sk; 269 alg_sk(sk2)->type = type; 270 271 newsock->ops = type->ops; 272 newsock->state = SS_CONNECTED; 273 274 err = 0; 275 --- 219 unchanged lines hidden --- | 297 alg_sk(sk2)->parent = sk; 298 alg_sk(sk2)->type = type; 299 300 newsock->ops = type->ops; 301 newsock->state = SS_CONNECTED; 302 303 err = 0; 304 --- 219 unchanged lines hidden --- |