Hi there,

I just did some preliminary analysis on this.
There are in fact three exploits involved in this.
CVE-2023-6546: https://github.com/Nassim-Asrir/ZDI-24-020/
jmpe4x's GSM exploit:
https://github.com/jmpe4x/GSM_Linux_Kernel_LPE_Nday_Exploit
YuriiCrimson's GSM exploit: https://github.com/YuriiCrimson/ExploitGSM

I tested all of them. All of them targeted the same subsystem (GSM),
used the same KASLR leak method ("/sys/kernel/notes"). But there are
two vulnerabilities involved here.
In short. jmpe4x's and YuriiCrimson's exploits are the same, but the
vulnerability is not CVE-2023-6546.
!!!!!!!!!!!!
It is a 0day that is not patched in the main tree yet.
Not a patch gap.
!!!!!!!!!!!!

My analysis is performed on the latest commit of Linus's tree:
```
commit e8c39d0f57f358950356a8e44ee5159f57f86ec5 (HEAD -> master,
origin/master, origin/HEAD)
Merge: 03a55b63919 325f3fb551f
Author: Linus Torvalds <torva...@linux-foundation.org>
Date:   Wed Apr 10 19:48:05 2024 -0700
```

And jmpe4x's and YuriiCrimson's are exactly the same. The difference
is mostly spaces. The diff is attached to this email.

Thanks,
Kyle Zeng


On Thu, Apr 11, 2024 at 8:07 AM Dr. Christopher Kunz
<i...@christopher-kunz.de> wrote:
>
> Hi,
>
> > There are two exploits in Yurii's repo above, according to Yurii for two
> > different bugs.  The above is one of them.  Perhaps also try the other?
> The two exploit versions are for different kernels. The 6.5 exploit
> doesn't compile on the Debian 12 6.1 kernel, and no Debian version
> currently distributes a 6.5 kernel, AFAICT. I used
> ExploitGSM_5_15_to_6_1/ExploitGSM and it worked.
> > I don't know, and apparently it'd need to be two CVEs for two bugs that
> > Yurii exploits.
> Possibly. I'm definitely out of my depth trying to analyze which bugs
> are being exploited.
> > CVE-2023-52564: Revert "tty: n_gsm: fix UAF in gsm_cleanup_mux"
> > https://lists.openwall.net/linux-cve-announce/2024/03/02/54
> >
> > Maybe CVE-2023-52564 is one of the bugs Yurii exploits, or maybe not.
> > I didn't look into this closely enough to tell.
>
> Apparently not. Debian 12 "Bookworm" currently runs this kernel:
>
> Linux debianexploitgsm 6.1.0-18-amd64 #1 SMP PREEMPT_DYNAMIC Debian
> 6.1.76-1 (2024-02-01) x86_64 GNU/Linux
>
> According to the changelog, this kernel has the fix for CVE-2023-52564
> included:
>      - Revert "tty: n_gsm: fix UAF in gsm_cleanup_mux"
> (from
> https://metadata.ftp-master.debian.org/changelogs//main/l/linux-signed-amd64/linux-signed-amd64_6.1.76+1_changelog)
>
> Still, the exploit works, so it must exploit a different issue.
>
> Just my two cents,
>
> --cku
>
0a1,2
> // GSM Linux Kernel Race Condition -> UAF 0day Exploit written by jmpe4x
> 
45a48
> #define PAGE_UP(addr)   (((addr)+((PAGE_SIZE)-1))&(~((PAGE_SIZE)-1)))
47d49
< #define MIN(X, Y) (((X) < (Y)) ? (X) : (Y))
49,51c51
< #define BIT(name)             (1ULL << name)
< #define HEAP_SPRAY_SIZE 1024
< #define BITS_PER_LONG 64
---
> #define MIN(X, Y) (((X) < (Y)) ? (X) : (Y))
54,60c54,60
<     __u32 channel;            /* DLCI (0 for the associated DLCI) */
<     __u32 adaption;           /* Convergence layer type */
<     __u32 mtu;                /* Maximum transfer unit */
<     __u32 priority;           /* Priority (0 for default value) */
<     __u32 i;          /* Frame type (1 = UIH, 2 = UI) */
<     __u32 k;          /* Window size (0 for default value) */
<     __u32 reserved[8];        /* For future use, must be initialized to zero 
*/
---
>     __u32 channel;              /* DLCI (0 for the associated DLCI) */
>     __u32 adaption;             /* Convergence layer type */
>     __u32 mtu;          /* Maximum transfer unit */
>     __u32 priority;             /* Priority (0 for default value) */
>     __u32 i;            /* Frame type (1 = UIH, 2 = UI) */
>     __u32 k;            /* Window size (0 for default value) */
>     __u32 reserved[8];  /* For future use, must be initialized to zero */
63,64c63,64
< #define GSMIOC_GETCONF_DLCI   _IOWR('G', 7, struct gsm_dlci_config)
< #define GSMIOC_SETCONF_DLCI   _IOW('G', 8, struct gsm_dlci_config)
---
> #define GSMIOC_GETCONF_DLCI     _IOWR('G', 7, struct gsm_dlci_config)
> #define GSMIOC_SETCONF_DLCI     _IOW('G', 8, struct gsm_dlci_config)
72c72
< const unsigned char CMD_MSC   =   0x71;
---
> const unsigned char CMD_MSC     =   0x71;
82a83,91
> const int KERNEL_PATH_READ_OFFSET = 11;
> const int SECTOR_SIZE = 512;
> const int BOOT_ENTRY_OFFSET = SECTOR_SIZE;
> const int BOOT_SECTOR_COUNT = 1;
> const int BOOT_FLAG = 0xAA55;
> const int UNCOMPRESSED_KERNEL_SIZE_OFFSET = 4;
> const int SETUP_HEADER_OFFSET = BOOT_ENTRY_OFFSET - 15;
> const int ASCII_OFFSET = 48;
> const int WQ_FLAG_BOOKMARK = 0x04;
84a94
> #define BIT(name)               (1ULL << name)
85a96,97
> 
> #define HEAP_SPRAY_SIZE 1024
87a100,101
> #define BITS_PER_LONG 64
> 
89,92c103,106
<     WORK_STRUCT_PENDING_BIT   = 0,    /* work item is pending execution */
<     WORK_STRUCT_INACTIVE_BIT= 1,      /* work item is inactive */
<     WORK_STRUCT_PWQ_BIT       = 2,    /* data points to pwq */
<     WORK_STRUCT_LINKED_BIT    = 3,    /* next work is linked to this one */
---
>     WORK_STRUCT_PENDING_BIT     = 0,    /* work item is pending execution */
>     WORK_STRUCT_INACTIVE_BIT= 1,        /* work item is inactive */
>     WORK_STRUCT_PWQ_BIT = 2,    /* data points to pwq */
>     WORK_STRUCT_LINKED_BIT      = 3,    /* next work is linked to this one */
94,95c108,109
<     WORK_STRUCT_STATIC_BIT    = 4,    /* static initializer (debugobjects) */
<     WORK_STRUCT_COLOR_SHIFT   = 5,    /* color for workqueue flushing */
---
>     WORK_STRUCT_STATIC_BIT      = 4,    /* static initializer (debugobjects) 
> */
>     WORK_STRUCT_COLOR_SHIFT     = 5,    /* color for workqueue flushing */
97c111
<     WORK_STRUCT_COLOR_SHIFT   = 4,    /* color for workqueue flushing */
---
>     WORK_STRUCT_COLOR_SHIFT     = 4,    /* color for workqueue flushing */
100c114
<     WORK_STRUCT_COLOR_BITS    = 4,
---
>     WORK_STRUCT_COLOR_BITS      = 4,
102,105c116,119
<     WORK_STRUCT_PENDING       = 1 << WORK_STRUCT_PENDING_BIT,
<     WORK_STRUCT_INACTIVE      = 1 << WORK_STRUCT_INACTIVE_BIT,
<     WORK_STRUCT_PWQ           = 1 << WORK_STRUCT_PWQ_BIT,
<     WORK_STRUCT_LINKED        = 1 << WORK_STRUCT_LINKED_BIT,
---
>     WORK_STRUCT_PENDING = 1 << WORK_STRUCT_PENDING_BIT,
>     WORK_STRUCT_INACTIVE        = 1 << WORK_STRUCT_INACTIVE_BIT,
>     WORK_STRUCT_PWQ             = 1 << WORK_STRUCT_PWQ_BIT,
>     WORK_STRUCT_LINKED  = 1 << WORK_STRUCT_LINKED_BIT,
107c121
<     WORK_STRUCT_STATIC        = 1 << WORK_STRUCT_STATIC_BIT,
---
>     WORK_STRUCT_STATIC  = 1 << WORK_STRUCT_STATIC_BIT,
109c123
<     WORK_STRUCT_STATIC        = 0,
---
>     WORK_STRUCT_STATIC  = 0,
112c126
<     WORK_NR_COLORS            = (1 << WORK_STRUCT_COLOR_BITS),
---
>     WORK_NR_COLORS              = (1 << WORK_STRUCT_COLOR_BITS),
115c129
<     WORK_CPU_UNBOUND  = 8192,
---
>     WORK_CPU_UNBOUND    = 8192,
122c136
<     WORK_STRUCT_FLAG_BITS     = WORK_STRUCT_COLOR_SHIFT +
---
>     WORK_STRUCT_FLAG_BITS       = WORK_STRUCT_COLOR_SHIFT +
126c140
<     WORK_OFFQ_FLAG_BASE       = WORK_STRUCT_COLOR_SHIFT,
---
>     WORK_OFFQ_FLAG_BASE = WORK_STRUCT_COLOR_SHIFT,
128c142
<     __WORK_OFFQ_CANCELING     = WORK_OFFQ_FLAG_BASE,
---
>     __WORK_OFFQ_CANCELING       = WORK_OFFQ_FLAG_BASE,
135,138c149,152
<     WORK_OFFQ_FLAG_BITS       = 1,
<     WORK_OFFQ_POOL_SHIFT      = WORK_OFFQ_FLAG_BASE + WORK_OFFQ_FLAG_BITS,
<     WORK_OFFQ_LEFT            = BITS_PER_LONG - WORK_OFFQ_POOL_SHIFT,
<     WORK_OFFQ_POOL_BITS       = WORK_OFFQ_LEFT <= 31 ? WORK_OFFQ_LEFT : 31,
---
>     WORK_OFFQ_FLAG_BITS = 1,
>     WORK_OFFQ_POOL_SHIFT        = WORK_OFFQ_FLAG_BASE + WORK_OFFQ_FLAG_BITS,
>     WORK_OFFQ_LEFT              = BITS_PER_LONG - WORK_OFFQ_POOL_SHIFT,
>     WORK_OFFQ_POOL_BITS = WORK_OFFQ_LEFT <= 31 ? WORK_OFFQ_LEFT : 31,
141,142c155,156
<     WORK_BUSY_PENDING = 1 << 0,
<     WORK_BUSY_RUNNING = 1 << 1,
---
>     WORK_BUSY_PENDING   = 1 << 0,
>     WORK_BUSY_RUNNING   = 1 << 1,
145c159
<     WORKER_DESC_LEN           = 24,
---
>     WORKER_DESC_LEN             = 24,
148,149c162,163
< #define WORK_OFFQ_POOL_NONE   ((1ul << WORK_OFFQ_POOL_BITS) - 1)
< #define WORK_STRUCT_NO_POOL   (WORK_OFFQ_POOL_NONE << WORK_OFFQ_POOL_SHIFT)
---
> #define WORK_OFFQ_POOL_NONE     ((1ul << WORK_OFFQ_POOL_BITS) - 1)
> #define WORK_STRUCT_NO_POOL     (WORK_OFFQ_POOL_NONE << WORK_OFFQ_POOL_SHIFT)
154,156c168,170
< #define ULL(x)                (_ULL(x))
< #define BIT_ULL(nr)           (ULL(1) << (nr))
< #define CAP_VALID_MASK         (BIT_ULL(CAP_LAST_CAP+1)-1)
---
> #define ULL(x)          (_ULL(x))
> #define BIT_ULL(nr)             (ULL(1) << (nr))
> #define CAP_VALID_MASK   (BIT_ULL(CAP_LAST_CAP+1)-1)
164,168c178,182
<     DLCI_WAITING_CONFIG,      /* Waiting for DLCI configuration from user */
<     DLCI_CONFIGURE,           /* Sending PN (for adaption > 1) */
<     DLCI_OPENING,             /* Sending SABM not seen UA */
<     DLCI_OPEN,                /* SABM/UA complete */
<     DLCI_CLOSING,             /* Sending DISC not seen UA/DM */
---
>     DLCI_WAITING_CONFIG,        /* Waiting for DLCI configuration from user */
>     DLCI_CONFIGURE,             /* Sending PN (for adaption > 1) */
>     DLCI_OPENING,               /* Sending SABM not seen UA */
>     DLCI_OPEN,          /* SABM/UA complete */
>     DLCI_CLOSING,               /* Sending DISC not seen UA/DM */
170a185,188
> const char* KALLSYMS_PATH = "/proc/kallsyms";
> const char* KPTR_RESTRICT_PATH = "/proc/sys/kernel/kptr_restrict";
> const char* PERF_EVENT_PARANOID_PATH = "/proc/sys/kernel/perf_event_paranoid";
> const char* CMDLINE_PATH = "/proc/cmdline";
267,281c285,299
<     int       usage;
<     kuid_t            uid;            /* real UID of the task */
<     kgid_t            gid;            /* real GID of the task */
<     kuid_t            suid;           /* saved UID of the task */
<     kgid_t            sgid;           /* saved GID of the task */
<     kuid_t            euid;           /* effective UID of the task */
<     kgid_t            egid;           /* effective GID of the task */
<     kuid_t            fsuid;          /* UID for VFS ops */
<     kgid_t            fsgid;          /* GID for VFS ops */
<     unsigned  securebits;     /* SUID-less security management */
<     kernel_cap_t      cap_inheritable; /* caps our children can inherit */
<     kernel_cap_t      cap_permitted;  /* caps we're permitted */
<     kernel_cap_t      cap_effective;  /* caps we can actually use */
<     kernel_cap_t      cap_bset;       /* capability bounding set */
<     kernel_cap_t      cap_ambient;    /* Ambient capability set */
---
>     int         usage;
>     kuid_t              uid;            /* real UID of the task */
>     kgid_t              gid;            /* real GID of the task */
>     kuid_t              suid;           /* saved UID of the task */
>     kgid_t              sgid;           /* saved GID of the task */
>     kuid_t              euid;           /* effective UID of the task */
>     kgid_t              egid;           /* effective GID of the task */
>     kuid_t              fsuid;          /* UID for VFS ops */
>     kgid_t              fsgid;          /* GID for VFS ops */
>     unsigned    securebits;     /* SUID-less security management */
>     kernel_cap_t        cap_inheritable; /* caps our children can inherit */
>     kernel_cap_t        cap_permitted;  /* caps we're permitted */
>     kernel_cap_t        cap_effective;  /* caps we can actually use */
>     kernel_cap_t        cap_bset;       /* capability bounding set */
>     kernel_cap_t        cap_ambient;    /* Ambient capability set */
292,293c310,311
<     uint8_t   num_parents;
<     uint8_t   new_parent_index;
---
>     uint8_t     num_parents;
>     uint8_t     new_parent_index;
307c325
<     int32_t   phase;
---
>     int32_t     phase;
310,311c328,329
<     struct hlist_node child_node;
<     uint64_t  clks;
---
>     struct hlist_node   child_node;
>     uint64_t    clks;
324,325c342,343
<     uint8_t   num_parents;
<     uint8_t   new_parent_index;
---
>     uint8_t     num_parents;
>     uint8_t     new_parent_index;
340c358
<     int32_t   phase;
---
>     int32_t     phase;
343,344c361,362
<     struct hlist_node child_node;
<     uint64_t  clks;
---
>     struct hlist_node   child_node;
>     uint64_t    clks;
376c394
< const int QUANTITY_KERNELS = 2;
---
> const int QUANTITY_KERNELS = 3;
379,381c397,399
< {"ubuntu", "6.5.0-25-generic", false, false, false, true, false, 0x26933c0, 
0x3910d00, 0xa22630, 0x1274c0, 0x133eb0, 0x1120a20},
< {"fedora", "6.5.6-300.fc39.x86_64", false, false, false, true, false, 
0x2ad7eb0, 0x3cfcc60, 0x9b4a30, 0x13c3d0, 0x148780, 0xfbbe20}
< };
---
> //{"ubuntu", "6.5.0-25-generic", false, false, false, true, false, 0x26933c0, 
> 0x3910d00, 0xa22630, 0x1274c0, 0x133eb0, 0x1120a20},
> {"fedora", "6.5.6-300.fc39.x86_64", false, false, false, true, false, 
> 0x2ad7eb0, 0x3cfcc60, 0x9b4a30, 0x13c3d0, 0x148780, 0xfbbe20},
> {"ubuntu", "6.5.0-26-generic", false, false, false, true, false, 0x26933c0, 
> 0x3910d00, 0xa22630, 0x1274c0, 0x133eb0, 0x1120a20}};
534,535c552,553
<         //if (strcmp(iter_kernel->os_name, argv[1]) || 
strcmp(iter_kernel->kernel, kernel_info.release))
<         //    continue;
---
>         if (strcmp(iter_kernel->os_name, argv[1]) || 
> strcmp(iter_kernel->kernel, kernel_info.release))
>             continue;

Reply via email to