linux "Dereferencing uninitialized pointer causes Kernel crash

During the initialization of a UNIX98 pseudo-terminal by ptmx_open, a tty_struct structure is allocated. But before its pointer field link->driver_data is properly initialized, ptmx_open will try to allocate an inode structure for the PTY slave. If this allocation fails, some cleanup code must be executed to free the already allocated resources. Namely, pty_close will be called to release the previously opened tty, and this eventually dereferences tty->link->driver_data, which is assumed to have been already initialized."
Bug fixed by commit 7acf6cd80b2
Type UninitializedVariable
Config "UNIX98_PTYS && DEVPTS_MULTIPLE_INSTANCES" (2nd degree)
C-features FunctionPointers
Fix-in code
Location drivers/tty/
__attribute__ ((noinline)) int nondet() { return 42; }

int some_int = 1;

void pts_sb_from_inode(int *inode)
{
#ifdef CONFIG_DEVPTS_MULTIPLE_INSTANCES
  int x = *inode; // ERROR (7)
#endif
}

void devpts_pty_kill(int *inode)
{
  pts_sb_from_inode(inode); // (6)
}

void pty_close(int *driver_data)
{
#ifdef CONFIG_UNIX98_PTYS
  devpts_pty_kill(driver_data); // (5)
#endif
}

int tty_release(int *driver_data)
{
  pty_close(driver_data); // (4)
  return 0;
}

#ifdef CONFIG_UNIX98_PTYS
int ptmx_open()
{
  int *driver_data;

  if (nondet()) {
    goto err_release; // (2)
  }

  driver_data = &some_int;

  return 0;

err_release:
  tty_release(driver_data); // (3)
  return -1;
}
#endif

int main()
{
#ifdef CONFIG_UNIX98_PTYS
  ptmx_open(); // (1)
#endif
  return 0;
}
diff --git a/simple/7acf6cd.c b/simple/7acf6cd.c
--- a/simple/7acf6cd.c
+++ b/simple/7acf6cd.c
@@ -18,7 +18,8 @@
 void pty_close(int *driver_data)
 {
 #ifdef CONFIG_UNIX98_PTYS
-  devpts_pty_kill(driver_data); // (5)
+  if(driver_data)
+    devpts_pty_kill(driver_data); // (5)
 #endif
 }

@@ -32,12 +33,12 @@
 int ptmx_open()
 {
   int *driver_data;
+
+  driver_data = &some_int;

   if (nondet()) {
     goto err_release; // (2)
   }
-
-  driver_data = &some_int;

   return 0;
#ifdef UNK_TRUE
#define unk() 1
#else
#include <stdlib.h>
#define unk() (rand() % 2)
#endif

int some_int = 1;

int main()
{
#ifdef CONFIG_UNIX98_PTYS
//  ptmx_open();
  int *driver_data;

  if (unk()) {
    goto err_release;
  }

  driver_data = &some_int;
  
  return 0;

err_release:
#ifdef CONFIG_DEVPTS_MULTIPLE_INSTANCES
  if (*driver_data)
    ;
#endif
  return -1;
#endif
}

. // setup
. call drivers/tty/pty.c:807:pty_init()
.. call drivers/tty/pty.c:739:unix98_pty_init()
.. 785: tty_set_operations(pts_driver, &pty_unix98_ops);

. call drivers/tty/pty.c:669:ptmx_open()
. 671: struct tty_struct *tty;
. // 694: tty = tty_init_dev(ptm_driver, index);
. // will not set tty->link->driver_data
. 707: tty_add_file(tty, filp);
. // now filp->private_data->tty points to tty
. 709: slave_inode = devpts_pty_new(inode, ..., tty->link);
. // now inode->i_private points to tty->link
. 712: if (IS_ERR(slave_inode)) {
. 714: goto err_release;
. // tty->link->driver_data is not set, remains undefined
. 727: tty_release(inode, filp);
.. call drivers/tty/tty_io.c:1625:tty_release()
.. 1627: struct tty_struct *tty = file_tty(filp);
.. // tty_release.tty points to ptmx_open.tty
.. 1658: tty->ops->close(tty, filp);
... dyn-call drivers/tty/pty.c:35:pty_close()
... 58: devpts_pty_kill(tty->link->driver_data);
.... call fs/devpts/inode.c:629:devpts_pty_kill()
.... // inode points to ptmx_open.tty->link->driver_data
.... 631: struct super_block *sb = pts_sb_from_inode(inode);
..... call fs/devpts/inode.c:137:pts_sb_from_inode()
..... ERROR 140: if (inode->i_sb->s_magic == DEVPTS_SUPER_MAGIC)
..... // tty->link->driver_data, holding an undefined value, is dereferenced