]> git.saurik.com Git - apt.git/commitdiff
Pass ExpectedSize to tthe backend method
authorMichael Vogt <mvo@debian.org>
Wed, 27 Aug 2014 02:08:37 +0000 (19:08 -0700)
committerMichael Vogt <mvo@debian.org>
Wed, 27 Aug 2014 02:08:37 +0000 (19:08 -0700)
This ensures that we can stop downloading if the server send
too much data by accident (or by a malicious attempt)

apt-pkg/acquire-method.cc
apt-pkg/acquire-method.h
apt-pkg/acquire-worker.cc
methods/http.cc
methods/http.h
methods/server.cc
methods/server.h

index e4a937d1dd6de8b363998a43b24abaf48e3a2a0a..9fc17674730f50fb66b1c2e7f4283e61d4a9986b 100644 (file)
@@ -360,6 +360,8 @@ int pkgAcqMethod::Run(bool Single)
               if (hash.empty() == false)
                  Tmp->ExpectedHashes.push_back(HashString(*t, hash));
            }
+            char *End;
+            Tmp->ExpectedSize = strtoll(LookupTag(Message, "Expected-Size", "0").c_str(), &End, 10);
            Tmp->Next = 0;
            
            // Append it to the list
index cbf79f8609be84b6d72e204e983095696f1ce258..8a680335e1bb20b8e38b4e26dc8bb68db6cd5e2f 100644 (file)
@@ -48,6 +48,7 @@ class pkgAcqMethod
       bool IndexFile;
       bool FailIgnore;
       HashStringList ExpectedHashes;
+      unsigned long long ExpectedSize;
    };
    
    struct FetchResult
index 54be8e99fbda4d63f95b5e620477287cadcf92f2..8bd1618f4b09efb69fd49f0029e88c6b43c426cb 100644 (file)
@@ -526,6 +526,9 @@ bool pkgAcquire::Worker::QueueItem(pkgAcquire::Queue::QItem *Item)
    if (OutFd == -1)
       return false;
    
+   string ExpectedSize;
+   strprintf(ExpectedSize, "%llu", Item->Owner->FileSize);
+
    string Message = "600 URI Acquire\n";
    Message.reserve(300);
    Message += "URI: " + Item->URI;
@@ -533,6 +536,7 @@ bool pkgAcquire::Worker::QueueItem(pkgAcquire::Queue::QItem *Item)
    HashStringList const hsl = Item->Owner->HashSums();
    for (HashStringList::const_iterator hs = hsl.begin(); hs != hsl.end(); ++hs)
       Message += "\nExpected-" + hs->HashType() + ": " + hs->HashValue();
+   Message += "\nExpected-Size: " + ExpectedSize;
    Message += Item->Owner->Custom600Headers();
    Message += "\n\n";
    
index c734d3799bca55cadf27aafce93fb4e3391289e1..916fa464f7d79c3c41cb5a1af5eb650eea14aa47 100644 (file)
@@ -63,7 +63,8 @@ const unsigned int CircleBuf::BW_HZ=10;
 // CircleBuf::CircleBuf - Circular input buffer                                /*{{{*/
 // ---------------------------------------------------------------------
 /* */
-CircleBuf::CircleBuf(unsigned long long Size) : Size(Size), Hash(0)
+CircleBuf::CircleBuf(unsigned long long Size) 
+   : Size(Size), Hash(0), TotalWriten(0)
 {
    Buf = new unsigned char[Size];
    Reset();
@@ -79,6 +80,7 @@ void CircleBuf::Reset()
    InP = 0;
    OutP = 0;
    StrPos = 0;
+   TotalWriten = 0;
    MaxGet = (unsigned long long)-1;
    OutQueue = string();
    if (Hash != 0)
@@ -216,6 +218,8 @@ bool CircleBuf::Write(int Fd)
         
         return false;
       }
+
+      TotalWriten += Res;
       
       if (Hash != 0)
         Hash->Add(Buf + (OutP%Size),Res);
@@ -649,6 +653,10 @@ bool HttpServerState::Go(bool ToFile, FileFd * const File)
         return _error->Errno("write",_("Error writing to output file"));
    }
 
+   if (ExpectedSize > 0 && In.TotalWriten > ExpectedSize)
+      return _error->Error("Writing more data than expected (%llu > %llu)",
+                           In.TotalWriten, ExpectedSize);
+
    // Handle commands from APT
    if (FD_ISSET(STDIN_FILENO,&rfds))
    {
index 5406ce4a7f438f9cd74b148f7d30de03826cd588..c98fe8e5fbfba2f5a4c07c88f5b7bd68aa9c7a57 100644 (file)
@@ -63,6 +63,8 @@ class CircleBuf
 
    public:
    Hashes *Hash;
+   // total amount of data that got written so far
+   unsigned long long TotalWriten;
 
    // Read data in
    bool Read(int Fd);
@@ -81,8 +83,8 @@ class CircleBuf
    bool ReadSpace() const {return Size - (InP - OutP) > 0;};
    bool WriteSpace() const {return InP - OutP > 0;};
 
-   // Dump everything
    void Reset();
+   // Dump everything
    void Stats();
 
    CircleBuf(unsigned long long Size);
index c91d3b21822f24c5a6515f548e65d290d4f60eb9..1b6511c59dc0525bc0b4e8ae116594a9c4bda42c 100644 (file)
@@ -531,6 +531,11 @@ int ServerMethod::Loop()
 
            // Run the data
            bool Result = true;
+
+            // ensure we don't fetch too much
+            if (Queue->ExpectedSize > 0)
+               Server->ExpectedSize = Queue->ExpectedSize;
+
             if (Server->HaveContent)
               Result = Server->RunData(File);
 
index 5299b3954f62d44c4ee8a1825fdd00194be9fef2..0d733314046093bbe8d1d0b0bb2043cf4d63746a 100644 (file)
@@ -49,6 +49,8 @@ struct ServerState
    URI Proxy;
    unsigned long TimeOut;
 
+   unsigned long long ExpectedSize;
+
    protected:
    ServerMethod *Owner;
 
@@ -73,7 +75,7 @@ struct ServerState
    bool Comp(URI Other) const {return Other.Host == ServerName.Host && Other.Port == ServerName.Port;};
    virtual void Reset() {Major = 0; Minor = 0; Result = 0; Code[0] = '\0'; Size = 0;
                 StartPos = 0; Encoding = Closes; time(&Date); HaveContent = false;
-                State = Header; Persistent = false; Pipeline = true;};
+                State = Header; Persistent = false; Pipeline = true; ExpectedSize = 0;};
    virtual bool WriteResponse(std::string const &Data) = 0;
 
    /** \brief Transfer the data from the socket */