From 22397ef2393fee6b6658d891c2109f6addeb45a1 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sun, 14 Feb 2016 13:30:29 -0800 Subject: [PATCH] 3.10-stable patches added patches: crypto-af_alg-disallow-bind-setkey-...-after-accept-2.patch crypto-af_alg-fix-socket-double-free-when-accept-fails.patch --- ...allow-bind-setkey-...-after-accept-2.patch | 145 ++++++++++++++++++ ...socket-double-free-when-accept-fails.patch | 37 +++++ queue-3.10/series | 2 + 3 files changed, 184 insertions(+) create mode 100644 queue-3.10/crypto-af_alg-disallow-bind-setkey-...-after-accept-2.patch create mode 100644 queue-3.10/crypto-af_alg-fix-socket-double-free-when-accept-fails.patch diff --git a/queue-3.10/crypto-af_alg-disallow-bind-setkey-...-after-accept-2.patch b/queue-3.10/crypto-af_alg-disallow-bind-setkey-...-after-accept-2.patch new file mode 100644 index 00000000000..83ad3082bcd --- /dev/null +++ b/queue-3.10/crypto-af_alg-disallow-bind-setkey-...-after-accept-2.patch @@ -0,0 +1,145 @@ +From c840ac6af3f8713a71b4d2363419145760bd6044 Mon Sep 17 00:00:00 2001 +From: Herbert Xu +Date: Wed, 30 Dec 2015 11:47:53 +0800 +Subject: crypto: af_alg - Disallow bind/setkey/... after accept(2) + +From: Herbert Xu + +commit c840ac6af3f8713a71b4d2363419145760bd6044 upstream. + +Each af_alg parent socket obtained by socket(2) corresponds to a +tfm object once bind(2) has succeeded. An accept(2) call on that +parent socket creates a context which then uses the tfm object. + +Therefore as long as any child sockets created by accept(2) exist +the parent socket must not be modified or freed. + +This patch guarantees this by using locks and a reference count +on the parent socket. Any attempt to modify the parent socket will +fail with EBUSY. + +Reported-by: Dmitry Vyukov +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman + +--- + crypto/af_alg.c | 35 ++++++++++++++++++++++++++++++++--- + include/crypto/if_alg.h | 8 +++----- + 2 files changed, 35 insertions(+), 8 deletions(-) + +--- a/crypto/af_alg.c ++++ b/crypto/af_alg.c +@@ -125,6 +125,23 @@ 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; +@@ -132,6 +149,7 @@ static int alg_bind(struct socket *sock, + struct sockaddr_alg *sa = (void *)uaddr; + const struct af_alg_type *type; + void *private; ++ int err; + + if (sock->state == SS_CONNECTED) + return -EINVAL; +@@ -157,16 +175,22 @@ static int alg_bind(struct socket *sock, + 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 0; ++ return err; + } + + static int alg_setkey(struct sock *sk, char __user *ukey, +@@ -199,11 +223,15 @@ static int alg_setsockopt(struct socket + struct sock *sk = sock->sk; + struct alg_sock *ask = alg_sk(sk); + const struct af_alg_type *type; +- int err = -ENOPROTOOPT; ++ int err = -EBUSY; + + lock_sock(sk); ++ if (ask->refcnt) ++ goto unlock; ++ + type = ask->type; + ++ err = -ENOPROTOOPT; + if (level != SOL_ALG || !type) + goto unlock; + +@@ -254,7 +282,8 @@ int af_alg_accept(struct sock *sk, struc + + sk2->sk_family = PF_ALG; + +- sock_hold(sk); ++ if (!ask->refcnt++) ++ sock_hold(sk); + alg_sk(sk2)->parent = sk; + alg_sk(sk2)->type = type; + +--- a/include/crypto/if_alg.h ++++ b/include/crypto/if_alg.h +@@ -30,6 +30,8 @@ struct alg_sock { + + struct sock *parent; + ++ unsigned int refcnt; ++ + const struct af_alg_type *type; + void *private; + }; +@@ -64,6 +66,7 @@ int af_alg_register_type(const struct af + 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, +@@ -80,11 +83,6 @@ static inline struct alg_sock *alg_sk(st + 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); diff --git a/queue-3.10/crypto-af_alg-fix-socket-double-free-when-accept-fails.patch b/queue-3.10/crypto-af_alg-fix-socket-double-free-when-accept-fails.patch new file mode 100644 index 00000000000..d97dabe1bb5 --- /dev/null +++ b/queue-3.10/crypto-af_alg-fix-socket-double-free-when-accept-fails.patch @@ -0,0 +1,37 @@ +From a383292c86663bbc31ac62cc0c04fc77504636a6 Mon Sep 17 00:00:00 2001 +From: Herbert Xu +Date: Wed, 30 Dec 2015 20:24:17 +0800 +Subject: crypto: af_alg - Fix socket double-free when accept fails + +From: Herbert Xu + +commit a383292c86663bbc31ac62cc0c04fc77504636a6 upstream. + +When we fail an accept(2) call we will end up freeing the socket +twice, once due to the direct sk_free call and once again through +newsock. + +This patch fixes this by removing the sk_free call. + +Reported-by: Dmitry Vyukov +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman + +--- + crypto/af_alg.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +--- a/crypto/af_alg.c ++++ b/crypto/af_alg.c +@@ -275,10 +275,8 @@ int af_alg_accept(struct sock *sk, struc + security_sk_clone(sk, sk2); + + err = type->accept(ask->private, sk2); +- if (err) { +- sk_free(sk2); ++ if (err) + goto unlock; +- } + + sk2->sk_family = PF_ALG; + diff --git a/queue-3.10/series b/queue-3.10/series index 06cf64ad3a9..df54d690b5d 100644 --- a/queue-3.10/series +++ b/queue-3.10/series @@ -52,3 +52,5 @@ usb-serial-option-adding-support-for-telit-le922.patch usb-option-fix-cinterion-ahxx-enumeration.patch tty-fix-unsafe-ldisc-reference-via-ioctl-tiocgetd.patch ext4-fix-handling-of-extended-tv_sec.patch +crypto-af_alg-disallow-bind-setkey-...-after-accept-2.patch +crypto-af_alg-fix-socket-double-free-when-accept-fails.patch -- 2.47.3