Hi,

Has anyone noticed that you can easily provoke a kernel panic just by 
invoking the F_LOG2PHYS fcntl on any file residing on a MacFUSE mount?
Steps to reproduce:
- Mount a volume with your favorite MacFUSE driver (loopback.c is always 
a good one).
- Compile and run the included demo utility, log2phys.c, for any file on 
the MacFUSE mount.
- Voila, kernel panic. (Confirmed on Leopard and Snow Leopard with 
MacFUSE 2.0.3.)

Regards,

- Erik

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"MacFUSE" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/macfuse?hl=en
-~----------~----~----~----~------~----~------~--~---

/**
 * log2phys - Simple command line wrapper for the F_LOG2PHYS fcntl.
 *
 * Copyright (C) 2009 Erik Larsson, Tuxera Ltd.
 *
 * License: Do whatever you want. Just don't sue me. :)
 */

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <libgen.h>

static void print_usage(char *invoke_cmd, FILE *out_stream) {
  fprintf(out_stream, "usage: %s <filename> [<offset>]\n",
          basename(invoke_cmd));
}

static int report_error(const char *message, int errno_value) {
  fprintf(stderr, "ERROR: %s (errno: %d / \"%s\")\n",
          message, errno_value, strerror(errno_value));
  return 1;
}

int main(int argc, char **argv) {
  if(argc < 2 || argc > 3) {
    print_usage(argv[0], stderr);
    return 1;
  }
  else {
    char *file = argv[1];
    unsigned long long logical_offset = 0;

    if(argc == 3) {
      if(sscanf(argv[2], "%llu", &logical_offset) != 1) {
        fprintf(stderr, "Invalid offset: %s\n", argv[2]);
        print_usage(argv[0], stderr);
        return 1;
      }
    }
    
    int fd = open(file, O_RDONLY);
    if(fd == -1)
      return report_error("Failed to open file.", errno);
    
    if(lseek(fd, logical_offset, SEEK_SET) == -1)
      return report_error("Failed to seek to desired offset.", errno);
    
    struct log2phys data = {};
    if(fcntl(fd, F_LOG2PHYS, &data) == -1)
      return report_error("fcntl F_LOG2PHYS failed.", errno);

    printf("%lld\n", (long long) data.l2p_devoffset);

    if(close(fd) == -1)
      return report_error("Failed to close file.", errno);

    return 0;
  }
}

Reply via email to