Ticket #5704: mythplugins_mythvideo-file-race.patch

File mythplugins_mythvideo-file-race.patch, 3.6 KB (added by Erik Hovland <erik@…>, 15 years ago)

Latest version of the patch against trunk as of 2008-12-06

  • mythplugins/mythvideo/mtd/dvdprobe.cpp

    stat() before open() makes it possible to introduce a file race.
    
    From: Erik Hovland <erik@hovland.org>
    
    
    ---
    
     mythplugins/mythvideo/mtd/dvdprobe.cpp |   55 ++++++++++++++++----------------
     1 files changed, 27 insertions(+), 28 deletions(-)
    
    
    diff --git a/mythplugins/mythvideo/mtd/dvdprobe.cpp b/mythplugins/mythvideo/mtd/dvdprobe.cpp
    index 0e9cb5a..21b1949 100644
    a b  
    1919#include <cmath>
    2020#include <climits> // for CDSL_CURRENT which is currently INT_MAX
    2121
     22// Qt
     23#include <QFile>
     24
    2225#include "dvdprobe.h"
    2326
    2427#include <mythtv/mythcontext.h>
    void DVDProbe::Reset(void) 
    425428
    426429bool DVDProbe::Probe(void)
    427430{
    428     //
    429431    //  Before touching libdvdread stuff
    430432    //  (below), see if there's actually
    431433    //  a drive with media in it
    432     //
    433 
    434     struct stat fileinfo;
    435 
    436     QByteArray dev = device.toLocal8Bit();
    437     int ret = stat(dev.constData(), &fileinfo);
    438     if (ret < 0)
     434    QFile dvdDevice(device);
     435    if (!dvdDevice.exists())
    439436    {
    440         //
    441         //  Can't even stat the device, it probably
    442         //  doesn't exist. Silly user
    443         //
     437        //  Device doesn't exist. Silly user
    444438        Reset();
    445439        return false;
    446440    }
    447441
    448 #if defined(__linux__) || defined(__FreeBSD__)
    449     //
    450     //  I have no idea if the following code block
    451     //  is anywhere close to the "right way" of doing
    452     //  this, but it seems to work.
    453     //
     442    if (!dvdDevice.open(QIODevice::ReadOnly))
     443    {
     444        // Can't open device.
     445        Reset();
     446        return false;
     447    }
    454448
    455     int drive_handle = open(dev.constData(), O_RDONLY | O_NONBLOCK);
     449    int drive_handle = dvdDevice.handle();
    456450
    457451    if (drive_handle == -1)
    458452    {
    459453        Reset();
    460454        return false;
    461455    }
     456#if defined(__linux__) || defined(__FreeBSD__)
     457    //  I have no idea if the following code block
     458    //  is anywhere close to the "right way" of doing
     459    //  this, but it seems to work.
    462460
    463461    // Sometimes the first result following an open is a lie. Often the
    464462    // first call will return 4, however an immediate second call will
    bool DVDProbe::Probe(void) 
    467465    // (in an admittedly small test number) seems to make it much more
    468466    // accurate (with only a 1 in 6 chance that the first result was more
    469467    // accurate than the second).
    470     ioctl(drive_handle, CDROM_DRIVE_STATUS, CDSL_CURRENT);
    471468    int status = ioctl(drive_handle, CDROM_DRIVE_STATUS, CDSL_CURRENT);
     469    if (status < 0)
     470    {
     471        Reset();
     472        return false;
     473    }
     474
     475    status = ioctl(drive_handle, CDROM_DRIVE_STATUS, CDSL_CURRENT);
    472476    if (status < 4)
    473477    {
    474478        //
    bool DVDProbe::Probe(void) 
    478482        //  3 = not ready
    479483        //
    480484        Reset();
    481         close(drive_handle);
    482485        return false;
    483 
    484486    }
    485487
    486488    status = ioctl(drive_handle, CDROM_MEDIA_CHANGED, NULL);
    487     close(drive_handle);
    488489
    489490    if (!status)
    490491    {
    491         //
    492492        //  the disc has not changed. but if this is our
    493493        //  first time running, we still need to check it
    494         //
    495 
    496494        if (!first_time)
    497495        {
    498             //
    499496            //  Return whatever we returned before
    500497            //
    501498
    bool DVDProbe::Probe(void) 
    503500        }
    504501    }
    505502#endif
     503    dvdDevice.close();
    506504
    507505    //
    508506    //  Try to open the disc
    509     //  (as far libdvdread is concerned, the argument
     507    //  (as far as libdvdread is concerned, the argument
    510508    //  could be a path, file, whatever).
    511509    //
    512510
    513511    Reset();
    514512    first_time = false;
     513    QByteArray dev = device.toAscii();
    515514    dvd = DVDOpen(dev.constData());
    516515    if (!dvd)
    517516        return false;