Uploaded image for project: 'Moodle'
  1. Moodle
  2. MDL-71777

scanner::get_incident_details() fatal error calling file_get_contents()

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: 3.10.4, 3.11, 4.0
    • Fix Version/s: 3.10.5, 3.11.1
    • Component/s: Antivirus
    • Labels:
    • Affected Branches:
      MOODLE_310_STABLE, MOODLE_311_STABLE, MOODLE_400_STABLE
    • Fixed Branches:
      MOODLE_310_STABLE, MOODLE_311_STABLE
    • Pull 3.10 Branch:
      MDL-71777-310
    • Pull 3.11 Branch:
      MDL-71777-311
    • Pull Master Branch:
    • Difficulty:
      Easy
    • Testing Instructions:
      Hide

      Setup

      1. Install clamav. In Ubuntu, for instance, you can run the following command: 

        sudo apt-get install clamav clamav-daemon

      2. Enable clamav on Moodle site: Site administration > Plugins > Antivirus plugins > Manage antivirus plugins 
      3. Specify path to clamscan: Site administration > Plugins > Antivirus plugins > ClamAV antivirus 
      4. Access to "Site administration > Server > PHP info" and check the values for memory_limit and upload_max_filesize parameters. You'll need to annotate both and find a file bigger than memory_limit and smaller than upload_max_filesize. For instance, if memory_limit=128MB and upload_max_filesize=200MB, the file you'll need later could be one of 150MB.

      Testing instructions

      1. In lib/classes/antivirus/manager.php, change the code for the method scan_file() in the try{} block (at or about line 75) to:

        try {
            throw new \core\antivirus\scanner_exception("test");
            $result = $antivirus->scan_file($file, $filename);
        }
        

      2. Log in as admin
      3. Select 'Private files' from the sliding side menu (this will avoid the quota imposed on regular users).
      4. Upload a file larger than the memory_limit setting (but smaller than the upload_max_filesize).
      5. Check the filepicker dialog appears and displays an exception.
      6. Open the server log file (for instance, in Apache it's located in /var/log/apacher/error.log).
      7. Check no "PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 154348408 bytes)" error is displayed (number might change depending on your configuration)

       

      Technical details about this test (not required for testing the issue):

      The two code files of concern are both in the lib/classes/antivirus directory. The code change to be tested is in scanner.php::get_incident_details, however for that code to be called you need to generate or simulate an exception in mananger.php::scan_file().

      The focus of this test is not whether the antivirus detects an infected or problematic file, but rather when it does, it can generate a content hash for that file to include in the notification.

      The bug manifested as a memory exhaustion fatal error when large files were scanned and failed. It will be practical to use a very large file to test, one that is larger than the max. allowed memory setting. If for example, your max memory is 256MB, use a file that is 300MB or larger. Running the fixed code, it is not so important, but for comparison to the unfixed code where you want to exhibit the bug, the file needs to be larger than the max. memory setting.

      Show
      Setup Install clamav. In Ubuntu, for instance, you can run the following command:  sudo apt-get install clamav clamav-daemon Enable clamav on Moodle site:  Site administration > Plugins > Antivirus plugins > Manage antivirus plugins   Specify path to clamscan:  Site administration > Plugins > Antivirus plugins > ClamAV antivirus   Access to " Site administration > Server > PHP info " and check the values for memory_limit and upload_max_filesize parameters. You'll need to annotate both and find a file bigger than memory_limit and smaller than upload_max_filesize. For instance, if memory_limit=128MB and upload_max_filesize=200MB, the file you'll need later could be one of 150MB. Testing instructions In lib/classes/antivirus/manager.php, change the code for the method scan_file() in the try{} block (at or about line 75) to: try { throw new  \core\antivirus\scanner_exception( "test" ); $result = $antivirus->scan_file($file, $filename); } Log in as admin Select 'Private files' from the sliding side menu (this will avoid the quota imposed on regular users). Upload a file larger than the memory_limit setting (but smaller than the upload_max_filesize). Check the filepicker dialog appears and displays an exception. Open the server log file (for instance, in Apache it's located in /var/log/apacher/error.log). Check no "PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 154348408 bytes)" error is displayed (number might change depending on your configuration)   Technical details about this test (not required for testing the issue): The two code files of concern are both in the lib/classes/antivirus directory. The code change to be tested is in scanner.php::get_incident_details, however for that code to be called you need to generate or simulate an exception in mananger.php::scan_file(). The focus of this test is not whether the antivirus detects an infected or problematic file, but rather when it does, it can generate a content hash for that file to include in the notification. The bug manifested as a memory exhaustion fatal error when large files were scanned and failed. It will be practical to use a very large file to test, one that is larger than the max. allowed memory setting. If for example, your max memory is 256MB, use a file that is 300MB or larger. Running the fixed code, it is not so important, but for comparison to the unfixed code where you want to exhibit the bug, the file needs to be larger than the max. memory setting.

      Description

      get_incident_details() is called as a result of scanner_exception being thrown. When attempting to get the file content hash, rather than use sha1_file() as is done in the file_storage class, the routine calls file_get_contents() to pass the entirety of the file as a single string to the hash_from_string() function.

      Any file with a size exceeding the configured memory limit will generate the fatal error: "Allowed memory size of XXXXXXXXX bytes exhausted"

      Routine should use the sha1_file() to prevent exhausting memory since scanned files can be anticipated to be extremely large.

      Introduced in MDL-66222 antivirus: Added antivirus failure reporting, commit adbe92c, which looks like 3.10 and forward.

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              woolardfa@appstate.edu Fred Woolard
              Reporter:
              woolardfa@appstate.edu Fred Woolard
              Peer reviewer:
              Dongsheng Cai Dongsheng Cai
              Integrator:
              Sara Arjona (@sarjona) Sara Arjona (@sarjona)
              Tester:
              Gladys Basiana Gladys Basiana
              Participants:
              Component watchers:
              Ruslan Kabalin
              Votes:
              1 Vote for this issue
              Watchers:
              7 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved:
                Fix Release Date:
                12/Jul/21

                  Time Tracking

                  Estimated:
                  Original Estimate - 0 minutes
                  0m
                  Remaining:
                  Remaining Estimate - 0 minutes
                  0m
                  Logged:
                  Time Spent - 2 hours, 5 minutes
                  2h 5m