Skip to content

Commit

Permalink
Revert: "crypto: af_alg - Disallow bind/setkey/... after accept(2)"
Browse files Browse the repository at this point in the history
This reverts commit 06b4194 which is
commit c840ac6 upstream.

It's been widely reported that this patch breaks existing userspace
applications when backported to the stable kernel releases.  As no fix
seems to be forthcoming, just revert it to let systems work again.

Reported-by: "J. Paul Reed" <preed@sigkill.com>
Cc: Dmitry Vyukov <dvyukov@google.com>
Cc: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Greg Kroah-Hartman committed Mar 16, 2016
1 parent 952b0e4 commit c4eb62d
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 35 deletions.
35 changes: 3 additions & 32 deletions crypto/af_alg.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,31 +125,13 @@ int af_alg_release(struct socket *sock)
}
EXPORT_SYMBOL_GPL(af_alg_release);

void af_alg_release_parent(struct sock *sk)
{
struct alg_sock *ask = alg_sk(sk);
bool last;

sk = ask->parent;
ask = alg_sk(sk);

lock_sock(sk);
last = !--ask->refcnt;
release_sock(sk);

if (last)
sock_put(sk);
}
EXPORT_SYMBOL_GPL(af_alg_release_parent);

static int alg_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
{
struct sock *sk = sock->sk;
struct alg_sock *ask = alg_sk(sk);
struct sockaddr_alg *sa = (void *)uaddr;
const struct af_alg_type *type;
void *private;
int err;

if (sock->state == SS_CONNECTED)
return -EINVAL;
Expand All @@ -175,22 +157,16 @@ static int alg_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
return PTR_ERR(private);
}

err = -EBUSY;
lock_sock(sk);
if (ask->refcnt)
goto unlock;

swap(ask->type, type);
swap(ask->private, private);

err = 0;

unlock:
release_sock(sk);

alg_do_release(type, private);

return err;
return 0;
}

static int alg_setkey(struct sock *sk, char __user *ukey,
Expand Down Expand Up @@ -223,15 +199,11 @@ static int alg_setsockopt(struct socket *sock, int level, int optname,
struct sock *sk = sock->sk;
struct alg_sock *ask = alg_sk(sk);
const struct af_alg_type *type;
int err = -EBUSY;
int err = -ENOPROTOOPT;

lock_sock(sk);
if (ask->refcnt)
goto unlock;

type = ask->type;

err = -ENOPROTOOPT;
if (level != SOL_ALG || !type)
goto unlock;

Expand Down Expand Up @@ -280,8 +252,7 @@ int af_alg_accept(struct sock *sk, struct socket *newsock)

sk2->sk_family = PF_ALG;

if (!ask->refcnt++)
sock_hold(sk);
sock_hold(sk);
alg_sk(sk2)->parent = sk;
alg_sk(sk2)->type = type;

Expand Down
8 changes: 5 additions & 3 deletions include/crypto/if_alg.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@ struct alg_sock {

struct sock *parent;

unsigned int refcnt;

const struct af_alg_type *type;
void *private;
};
Expand Down Expand Up @@ -66,7 +64,6 @@ int af_alg_register_type(const struct af_alg_type *type);
int af_alg_unregister_type(const struct af_alg_type *type);

int af_alg_release(struct socket *sock);
void af_alg_release_parent(struct sock *sk);
int af_alg_accept(struct sock *sk, struct socket *newsock);

int af_alg_make_sg(struct af_alg_sgl *sgl, void __user *addr, int len,
Expand All @@ -83,6 +80,11 @@ static inline struct alg_sock *alg_sk(struct sock *sk)
return (struct alg_sock *)sk;
}

static inline void af_alg_release_parent(struct sock *sk)
{
sock_put(alg_sk(sk)->parent);
}

static inline void af_alg_init_completion(struct af_alg_completion *completion)
{
init_completion(&completion->completion);
Expand Down

0 comments on commit c4eb62d

Please sign in to comment.