Skip to content

Pantum M6500: scanimage: sane_start: Out of memory

This is not a SANE bug and not a SANE backend bug. I'm creating this issue only for visibility, to make it indexable by the search engines.


Pantum M6500 proprietary scanner backend has a bug: it checks for free space on / (root) partition before scanning, and fails to scan if:

  • there's less than 300 MiB of free space
  • root is read-only image (squashfs)

It does not save anything to the / filesystem, but instread it creates temporary files in /tmp if there's a need.

This is what you get without debug logging enabled:

sane_pantum6500_start: dev->doc_source = 100, scanning = 0, reading = 0
scanimage: sane_start: Out of memory

And this is what you see with SANE_DEBUG_PANTUM6500=6:

sane_pantum6500_start: dev->doc_source = 100, scanning = 0, reading = 0
[17:56:03.461878] [pantum6500] bHave_enough_space: check if there is enough space available or not.
[17:56:03.478525] [pantum6500] bHave_enough_space: mount point is: /media/root_ro
[17:56:03.479397] [pantum6500] bHave_enough_space: mount point is: /conf
[17:56:03.479981] [pantum6500] bHave_enough_space: successfully get root mounting point.
[17:56:03.481521] [pantum6500] total image size = 1.60
[17:56:03.483584] [pantum6500] bHave_enough_space: available size is 83.58
[17:56:03.485390] [pantum6500] No enough space left at disk, return false.
scanimage: sane_start: Out of memory

Fix is either:

  • Do something to get more than 300 MB + total image size on the root partition
  • Patch the libsane-pantum6500.so.1.0.24 bHave_enough_space function with xor eax, eax; inc eax
Click to expand
int __cdecl bHave_enough_space(int a1)
{
  int result; // eax
  int v2; // kr00_4
  unsigned int v3; // kr08_4
  char v4; // [esp-8h] [ebp-B0h]
  double v5; // [esp-8h] [ebp-B0h]
  float v6; // [esp+18h] [ebp-90h]
  _BOOL4 spaceleft_err; // [esp+28h] [ebp-80h]
  FILE *stream; // [esp+2Ch] [ebp-7Ch]
  struct mntent *v9; // [esp+30h] [ebp-78h]
  char *s1; // [esp+38h] [ebp-70h]
  float v11; // [esp+3Ch] [ebp-6Ch]
  signed __int64 free_bytes; // [esp+40h] [ebp-68h]
  struct statfs v13; // [esp+4Ch] [ebp-5Ch] BYREF
  unsigned int v14; // [esp+8Ch] [ebp-1Ch]

  v14 = __readgsdword(0x14u);
  sanei_debug_pantum6500_call(
    4,
    (int)"%s: check if there is enough space available or not.\n",
    (char)"bHave_enough_space");
  spaceleft_err = 0;
  stream = setmntent("/etc/mtab", "r");
  if ( stream )
  {
    while ( 1 )
    {
      while ( 1 )
      {
        v9 = getmntent(stream);
        if ( !v9 )
        {
          sanei_debug_pantum6500_call(
            4,
            (int)"%s: get mount entty fails\n",
            (unsigned __int8)&aBhaveEnoughSpa[-131072] + (unsigned __int8)&off_20000);
          endmntent(stream);
          result = 1;
          goto LABEL_19;
        }
        s1 = v9->mnt_dir;
        if ( !strcmp(s1, "/") )
          break;
        sanei_debug_pantum6500_call(
          4,
          (int)"%s: mount point is: %s\n",
          (unsigned __int8)&aBhaveEnoughSpa[-131072] + (unsigned __int8)&off_20000);
      }
      sanei_debug_pantum6500_call(
        4,
        (int)"%s: successfully get root mounting point.\n",
        (unsigned __int8)&aBhaveEnoughSpa[-131072] + (unsigned __int8)&off_20000);
      if ( !statfs(s1, &v13) )
        break;
      sanei_debug_pantum6500_call(
        4,
        (int)"%s: statfs failed!\n",
        (unsigned __int8)&aBhaveEnoughSpa[-131072] + (unsigned __int8)&off_20000);
    }
    if ( v13.f_blocks )
    {
      v2 = v13.f_bsize;
      v3 = v13.f_bavail;
      free_bytes = v13.f_bsize * (unsigned __int64)v13.f_bavail;
      v6 = (float)(*(_DWORD *)(a1 + 516) * *(_DWORD *)(a1 + 524));
      v11 = v6 / (double)0x100000LL;
      v5 = v11;
      sanei_debug_pantum6500_call(4, (int)"total image size = %0.2f\n", SLOBYTE(v5));
      if ( is_mul_ok(v2, v3) && (unsigned int)free_bytes <= 1073741824 )
      {
        if ( (unsigned int)free_bytes <= 0x100000 )
        {
          spaceleft_err = 0;
        }
        else
        {
          sanei_debug_pantum6500_call(
            4,
            (int)"%s: available size is %0.2f\n",
            (unsigned __int8)&aBhaveEnoughSpa[-131072] + (unsigned __int8)&off_20000);
          spaceleft_err = (double)free_bytes / (double)0x100000LL > v11 + v11 + 300.0;
        }
      }
      else
      {
        sanei_debug_pantum6500_call(
          4,
          (int)"%s: available size is %0.2f GB\n",
          (unsigned __int8)&aBhaveEnoughSpa[-131072] + (unsigned __int8)&off_20000);
        spaceleft_err = 1;
      }
    }
    endmntent(stream);
    if ( !spaceleft_err )
      sanei_debug_pantum6500_call(4, (int)"No enough space left at disk, return false.\n", v4);
    result = spaceleft_err;
  }
  else
  {
    sanei_debug_pantum6500_call(
      4,
      (int)"%s: get mount table fails.\n",
      (unsigned __int8)&aBhaveEnoughSpa[-131072] + (unsigned __int8)&off_20000);
    result = 1;
  }
LABEL_19:
  if ( __readgsdword(0x14u) != v14 )
    sub_16BD0();
  return result;
}
Edited by ValdikSS
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information