Hacker News new | ask | show | jobs
by pixdamix 5519 days ago
There's this patch from the linux-kernel:

- http://lkml.org/lkml/2009/7/17/187

- http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6...

I've put a gist file demonstrating the problem: https://gist.github.com/968723

  #include <stdio.h>
  
  struct agnx_priv {
      char demo;
  };
  
  struct ieee80211_hw {
      struct agnx_priv *priv;
  };
  
  struct pci_dev {
      struct ieee80211_hw* dev;
  };
  
  struct ieee80211_hw* pci_get_drvdata(struct pci_dev *pdev) {
  
      if(!pdev)
          return NULL;
  
      return pdev->dev;
  }
  
  static void agnx_pci_remove (struct pci_dev *pdev)
  {
      struct ieee80211_hw *dev = pci_get_drvdata(pdev);
      struct agnx_priv *priv = dev->priv;
  
      if (!dev) return;
  
      // This will segfault if the previous if is optimized
      printf("%c\n", priv->demo);
  }
  
  int main(int argc, char **argv)
  {
      // (struct pci_dev *)argv[1] is just to avoid compiler optimisations
      // =~ NULL if no args are passed.
      struct pci_dev * pdev = (struct pci_dev *)argv[1];
  
      agnx_pci_remove(pdev);
      return 0;
  }
Compile with:

  gcc -O2 -ggdb -Wall -Wundef -fno-strict-aliasing \
    -fno-common -fdelete-null-pointer-checks test-deref.c \
    -o test-deref
and

  gcc -O2 -ggdb -Wall -Wundef -fno-strict-aliasing \
    -fno-common -fno-delete-null-pointer-checks test-deref.c  \
    -o test-deref