summaryrefslogtreecommitdiff
path: root/crypto/af_alg.c
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@google.com>2020-07-09 10:27:40 +0200
committerGreg Kroah-Hartman <gregkh@google.com>2020-07-09 10:27:40 +0200
commit60cb6b82b45df384c0985642b3f2979c81a48fc5 (patch)
tree45aeec06fedcf69d8eae172534c56c710676d005 /crypto/af_alg.c
parent98e46e86d3e46d4fe709ce38ad41f74f1d186f0c (diff)
parent665a45788e4195f198e149c51defd186c8ef6548 (diff)
Merge 4.4.230 into android-4.4-p
Changes in 4.4.230 btrfs: cow_file_range() num_bytes and disk_num_bytes are same btrfs: fix data block group relocation failure due to concurrent scrub mm: fix swap cache node allocation mask EDAC/amd64: Read back the scrub rate PCI register on F15h mm/slub: fix stack overruns with SLUB_STATS usb: usbtest: fix missing kfree(dev->buf) in usbtest_disconnect kgdb: Avoid suspicious RCU usage warning crypto: af_alg - fix use-after-free in af_alg_accept() due to bh_lock_sock() sched/rt: Show the 'sched_rr_timeslice' SCHED_RR timeslice tuning knob in milliseconds hwmon: (max6697) Make sure the OVERT mask is set correctly hwmon: (acpi_power_meter) Fix potential memory leak in acpi_power_meter_add() virtio-blk: free vblk-vqs in error path of virtblk_probe() i2c: algo-pca: Add 0x78 as SCL stuck low status for PCA9665 Revert "ALSA: usb-audio: Improve frames size computation" SMB3: Honor 'seal' flag for multiuser mounts SMB3: Honor persistent/resilient handle flags for multiuser mounts cifs: Fix the target file was deleted when rename failed. MIPS: Add missing EHB in mtc0 -> mfc0 sequence for DSPen netfilter: nf_conntrack_h323: lost .data_len definition for Q.931/ipv6 Linux 4.4.230 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com> Change-Id: I5402fcb3d8e16e5bf6bec2151354cb207b064e91
Diffstat (limited to 'crypto/af_alg.c')
-rw-r--r--crypto/af_alg.c26
1 files changed, 11 insertions, 15 deletions
diff --git a/crypto/af_alg.c b/crypto/af_alg.c
index cf3975ee4fd8..c48ddeb6c328 100644
--- a/crypto/af_alg.c
+++ b/crypto/af_alg.c
@@ -130,21 +130,15 @@ EXPORT_SYMBOL_GPL(af_alg_release);
void af_alg_release_parent(struct sock *sk)
{
struct alg_sock *ask = alg_sk(sk);
- unsigned int nokey = ask->nokey_refcnt;
- bool last = nokey && !ask->refcnt;
+ unsigned int nokey = atomic_read(&ask->nokey_refcnt);
sk = ask->parent;
ask = alg_sk(sk);
- local_bh_disable();
- bh_lock_sock(sk);
- ask->nokey_refcnt -= nokey;
- if (!last)
- last = !--ask->refcnt;
- bh_unlock_sock(sk);
- local_bh_enable();
+ if (nokey)
+ atomic_dec(&ask->nokey_refcnt);
- if (last)
+ if (atomic_dec_and_test(&ask->refcnt))
sock_put(sk);
}
EXPORT_SYMBOL_GPL(af_alg_release_parent);
@@ -189,7 +183,7 @@ static int alg_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
err = -EBUSY;
lock_sock(sk);
- if (ask->refcnt | ask->nokey_refcnt)
+ if (atomic_read(&ask->refcnt))
goto unlock;
swap(ask->type, type);
@@ -238,7 +232,7 @@ static int alg_setsockopt(struct socket *sock, int level, int optname,
int err = -EBUSY;
lock_sock(sk);
- if (ask->refcnt)
+ if (atomic_read(&ask->refcnt) != atomic_read(&ask->nokey_refcnt))
goto unlock;
type = ask->type;
@@ -305,12 +299,14 @@ int af_alg_accept(struct sock *sk, struct socket *newsock)
sk2->sk_family = PF_ALG;
- if (nokey || !ask->refcnt++)
+ if (atomic_inc_return_relaxed(&ask->refcnt) == 1)
sock_hold(sk);
- ask->nokey_refcnt += nokey;
+ if (nokey) {
+ atomic_inc(&ask->nokey_refcnt);
+ atomic_set(&alg_sk(sk2)->nokey_refcnt, 1);
+ }
alg_sk(sk2)->parent = sk;
alg_sk(sk2)->type = type;
- alg_sk(sk2)->nokey_refcnt = nokey;
newsock->ops = type->ops;
newsock->state = SS_CONNECTED;