Test Case:
---------

$ cat aa-refcnt-af_alg.c
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <linux/if_alg.h>

int main() {
    int sockfd;
    struct sockaddr_alg sa;

    /* Setup the crypto API socket */
    sockfd = socket(AF_ALG, SOCK_SEQPACKET, 0);
    if (sockfd < 0) {
            perror("socket");
            return 1;
    }

    memset(&sa, 0, sizeof(sa));
    sa.salg_family = AF_ALG;
    strcpy((char *) sa.salg_type, "rng");
    strcpy((char *) sa.salg_name, "stdrng");

    if (bind(sockfd, (struct sockaddr *) &sa, sizeof(sa)) < 0) {
            perror("bind");
            return 1;
    }

    /* Accept a "connection" and close it; repeat. */
    while (!close(accept(sockfd, NULL, 0)));

    return 0;
}

$ gcc -o aa-refcnt-af_alg aa-refcnt-af_alg.c

$ ./aa-refcnt-af_alg
<a few hours later>

[ 9928.475953] refcount_t overflow at apparmor_sk_clone_security+0x37/0x70 in 
aa-refcnt-af_alg[1322], uid/euid: 1000/1000
...
[ 9928.507443] RIP: 0010:apparmor_sk_clone_security+0x37/0x70
...
[ 9928.514286]  security_sk_clone+0x33/0x50
[ 9928.514807]  af_alg_accept+0x81/0x1c0 [af_alg]
[ 9928.516091]  alg_accept+0x15/0x20 [af_alg]
[ 9928.516682]  SYSC_accept4+0xff/0x210
[ 9928.519609]  SyS_accept+0x10/0x20
[ 9928.520190]  do_syscall_64+0x73/0x130
[ 9928.520808]  entry_SYSCALL_64_after_hwframe+0x3d/0xa2

Note that other messages may be seen, not just overflow, depending on
the value being incremented by kref_get(); on another run:

[ 7273.182666] refcount_t: saturated; leaking memory.
...
[ 7273.185789] refcount_t: underflow; use-after-free.

** Description changed:

  [Impact]
  
-  * Users of the Crypto (user-space) API (i.e., AF_ALG)
-    can trigger refcount errors in AppArmor under high
-    load (might lead to memory leak or use after free.)
+  * Users of the Crypto (user-space) API (i.e., AF_ALG)
+    can trigger refcount errors in AppArmor under high
+    load (might lead to memory leak or use after free.)
  
-  * There is a reference leak in AppArmor when af_alg_accept()
-    calls security_sock_graft() and then security_sk_clone().
-    
-  * Both acquire a reference to a label, to assign it to the
-    same pointer, but the latter does not release the former's
-    acquired reference (before overwriting the pointer value.)
-    
-  * This reference leak builds up over time, and under high
-    load can eventually overflow/underflow/saturate refcount,
-    depending on which value it has when a program hits that.
-    
-  * The fix just checks if the pointer has an assigned label,
-    then releases its acquired reference.
+  * There is a reference leak in AppArmor when af_alg_accept()
+    calls security_sock_graft() and then security_sk_clone().
+ 
+  * Both acquire a reference to a label, to assign it to the
+    same pointer, but the latter does not release the former's
+    acquired reference (before overwriting the pointer value.)
+ 
+  * This reference leak builds up over time, and under high
+    load can eventually overflow/underflow/saturate refcount,
+    depending on which value it has when a program hits that.
+ 
+  * The fix just checks if the pointer has an assigned label,
+    then releases its acquired reference.
  
  [Test Case]
  
-  * See comment # for the test-case 'aa-refcnt-af_alg.c'.
+  * Exercise that code path indefinitely until it hits
+    the refcount_t overflow/underflow/saturate message
+    (or not, with the patch.)
  
-  * Exercise that code path indefinitely until it hits
-    the refcount_t overflow/underflow/saturate message.
-    (in a few hours.)
-    
-  * It's possible to monitor refcount values with kprobes.
+  * See comment #1 for the test-case 'aa-refcnt-af_alg.c'.
+ 
+    If the problem happens, in a few hours there is an
+    error message in the kernel logs (see comment #1.)
+ 
+  * It's possible to monitor refcount values with kprobes,
+    to confirm whether or not the problem is happening.
  
  [Other Info]
  
-  * Patch applied upstream on v5.8-rc1 [1]
-  * Applied on Unstable (tag Ubuntu-5.8-5.8.0-0.1)
-  * Not required on Groovy (still 5.4; should sync from Unstable)
-  * Not required on Eoan (EOL date before SRU cycle release date)
-  * Required on Bionic and Focal.
+  * Patch applied upstream on v5.8-rc1 [1]
+  * Applied on Unstable (tag Ubuntu-5.8-5.8.0-0.1)
+  * Not required on Groovy (still 5.4; should sync from Unstable)
+  * Not required on Eoan (EOL date before SRU cycle release date)
+  * Required on Bionic and Focal.
  
  [1]
  
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit?id=3b646abc5bc6c0df649daea4c2c976bd4d47e4c8

-- 
You received this bug notification because you are a member of Kernel
Packages, which is subscribed to linux in Ubuntu.
https://bugs.launchpad.net/bugs/1883962

Title:
  apparmor reference leak causes refcount_t overflow with
  af_alg_accept()

Status in linux package in Ubuntu:
  Fix Committed
Status in linux source package in Bionic:
  In Progress
Status in linux source package in Eoan:
  Won't Fix
Status in linux source package in Focal:
  In Progress
Status in linux source package in Groovy:
  Won't Fix

Bug description:
  [Impact]

   * Users of the Crypto (user-space) API (i.e., AF_ALG)
     can trigger refcount errors in AppArmor under high
     load (might lead to memory leak or use after free.)

   * There is a reference leak in AppArmor when af_alg_accept()
     calls security_sock_graft() and then security_sk_clone().

   * Both acquire a reference to a label, to assign it to the
     same pointer, but the latter does not release the former's
     acquired reference (before overwriting the pointer value.)

   * This reference leak builds up over time, and under high
     load can eventually overflow/underflow/saturate refcount,
     depending on which value it has when a program hits that.

   * The fix just checks if the pointer has an assigned label,
     then releases its acquired reference.

  [Test Case]

   * Exercise that code path indefinitely until it hits
     the refcount_t overflow/underflow/saturate message
     (or not, with the patch.)

   * See comment #1 for the test-case 'aa-refcnt-af_alg.c'.

     If the problem happens, in a few hours there is an
     error message in the kernel logs (see comment #1.)

   * It's possible to monitor refcount values with kprobes,
     to confirm whether or not the problem is happening.

  [Other Info]

   * Patch applied upstream on v5.8-rc1 [1]
   * Applied on Unstable (tag Ubuntu-5.8-5.8.0-0.1)
   * Not required on Groovy (still 5.4; should sync from Unstable)
   * Not required on Eoan (EOL date before SRU cycle release date)
   * Required on Bionic and Focal.

  [1]
  
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit?id=3b646abc5bc6c0df649daea4c2c976bd4d47e4c8

To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1883962/+subscriptions

-- 
Mailing list: https://launchpad.net/~kernel-packages
Post to     : kernel-packages@lists.launchpad.net
Unsubscribe : https://launchpad.net/~kernel-packages
More help   : https://help.launchpad.net/ListHelp

Reply via email to