title: Reading data from the end of disk in C
body: <p>I try to use crypto key for decrypting disk in Ubuntu 16 and I want read it from the end of disk just as raw data without creating any file for security reason, i.e. like dd does in way</p>
  <pre><code>sudo dd if=some_disk bs=1 skip=end_of_disk - keysize count=keysize
  </code></pre>
  <p>So, I wrote a test program</p>
  <pre><code>#include &lt;fcntl.h&gt;
  #include &lt;linux/fs.h&gt;
  #include &lt;sys/ioctl.h&gt;
  #include &lt;stdio.h&gt;
  #include &lt;unistd.h&gt;
  #include &lt;stdio.h&gt;
  #include &lt;errno.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;string.h&gt;
  #include &lt;unistd.h&gt;
  #include &lt;sys/types.h&gt;
  #include &lt;sys/stat.h&gt;
  #include &lt;fcntl.h&gt;
  
  unsigned long long disksize(char *drivename)
  {
    int fd;
    unsigned long long numblocks=0;
  
    fd = open(drivename, O_RDONLY);
    ioctl(fd, BLKGETSIZE64, &amp;numblocks);
    close(fd);
    return numblocks;
  }
  
  int main(int argc, char **argv)
  {
    int fd;
    FILE *device;
    int keySize = 2048;
    int count;
    unsigned char *block;
    unsigned long long endOfDisk=disksize(argv[1]);
    unsigned long long startFrom = endOfDisk - keySize;
    block = calloc(keySize, sizeof(char));
  //  fd=open(argv[1], O_RDWR | O_DIRECT);
    device = fopen(argv[1], &quot;r&quot;);
    long res = fseek(device, startFrom, SEEK_SET);
    perror(&quot;\nSeeking error:&quot;);
    fread(block, 1, keySize, device);
    fclose(device);
    printf(&quot;\nDevice Size: %lld\n&quot;, endOfDisk);
    printf(&quot;\nReading data starting from: %lld\n&quot;, startFrom);
    for(count = 0; count &lt; keySize; count++){
        printf(&quot;%c&quot;, block[count]); 
    }
    free(block);
  }
  </code></pre>
  <p>It works good on small disks, say, on boot partition or USB stick with capacity of 1Gb, but when I try to get key from, say, 4Gb USB stick, I can't: program prints something beyond key area on disk and <strong>perror</strong> shows &quot;Invalid argument&quot; as result of <strong>fseek</strong>. It looks like <strong>fseek</strong> can't set pointer right and I don't understand why:</p>
  <pre><code>fdisk -l some_disk
  </code></pre>
  <p>shows exactly the same disk size as <strong>endOfDisk</strong> from given program.</p>
  <p>P.S. As someone can see from a couple of rudiments, I tried lseek too with exactly the same result printing exactly the same info instead of stored on disk key.</p>