[SCM] A client for connecting to 3D metaverses such as Linden Labs Secondlife(tm) and OpenSim grids branch, master, updated. upstream/1.21.3-92-gf6831f2
Robin Cornelius
robin.cornelius at gmail.com
Tue Oct 7 18:11:08 UTC 2008
The following commit has been merged in the master branch:
commit 2ca025f3cef09198de320f4ad78857243afbac09
Author: Robin Cornelius <robin.cornelius at gmail.com>
Date: Tue Oct 7 16:42:20 2008 +0100
Bump version and import security patch DEV-21775
diff --git a/debian/patches/DEV-21775.patch b/debian/patches/DEV-21775.patch
new file mode 100755
index 0000000..4b28241
--- /dev/null
+++ b/debian/patches/DEV-21775.patch
@@ -0,0 +1,253 @@
+Index: indra/llcommon/llversionviewer.h
+===================================================================
+--- indra/llcommon/llversionviewer.h (revision 97603)
++++ indra/llcommon/llversionviewer.h (revision 98760)
+@@ -34,7 +34,7 @@
+
+ const S32 LL_VERSION_MAJOR = 1;
+ const S32 LL_VERSION_MINOR = 21;
+-const S32 LL_VERSION_PATCH = 4;
++const S32 LL_VERSION_PATCH = 5;
+ const S32 LL_VERSION_BUILD = 0;
+
+ const char * const LL_CHANNEL = "Second Life Release";
+Index: indra/newview/llfloaterregioninfo.cpp
+===================================================================
+--- indra/newview/llfloaterregioninfo.cpp (revision 97603)
++++ indra/newview/llfloaterregioninfo.cpp (revision 98760)
+@@ -1318,6 +1318,7 @@
+ return;
+ }
+ std::string filepath = picker.getFirstFile();
++ gXferManager->expectFileForRequest(filepath);
+
+ LLPanelRegionTerrainInfo* self = (LLPanelRegionTerrainInfo*)data;
+ strings_t strings;
+@@ -1337,6 +1338,7 @@
+ return;
+ }
+ std::string filepath = picker.getFirstFile();
++ gXferManager->expectFileForTransfer(filepath);
+
+ LLPanelRegionTerrainInfo* self = (LLPanelRegionTerrainInfo*)data;
+ strings_t strings;
+Index: indra/newview/llviewermessage.cpp
+===================================================================
+--- indra/newview/llviewermessage.cpp (revision 97603)
++++ indra/newview/llviewermessage.cpp (revision 98760)
+@@ -5172,6 +5172,11 @@
+ msg->getString("FileData", "SimFilename", MAX_PATH, sim_filename);
+ msg->getString("FileData", "ViewerFilename", MAX_PATH, viewer_filename);
+
++ if (!gXferManager->validateFileForRequest(viewer_filename))
++ {
++ llwarns << "SECURITY: Unauthorized download to local file " << viewer_filename << llendl;
++ return;
++ }
+ gXferManager->requestFile(viewer_filename,
+ sim_filename,
+ LL_PATH_NONE,
+Index: indra/llmessage/llxfermanager.h
+===================================================================
+--- indra/llmessage/llxfermanager.h (revision 97603)
++++ indra/llmessage/llxfermanager.h (revision 98760)
+@@ -108,6 +108,8 @@
+ // implementation methods
+ virtual void startPendingDownloads();
+ virtual void addToList(LLXfer* xferp, LLXfer*& head, BOOL is_priority);
++ std::multiset<std::string> mExpectedTransfers; // files that are authorized to transfer out
++ std::multiset<std::string> mExpectedRequests; // files that are authorized to be downloaded on top of
+
+ public:
+ LLXferManager(LLVFS *vfs);
+@@ -168,6 +170,20 @@
+ const LLHost& remote_host,
+ void (*callback)(void**,S32,LLExtStat), void** user_data,
+ BOOL is_priority = FALSE);
++ /**
++ When arbitrary files are requested to be transfered (by giving a dir of LL_PATH_NONE)
++ they must be "expected", but having something pre-authorize them. This pair of functions
++ maintains a pre-authorized list. The first function adds something to the list, the second
++ checks if is authorized, removing it if so. In this way, a file is only authorized for
++ a single use.
++ */
++ virtual void expectFileForTransfer(const std::string& filename);
++ virtual bool validateFileForTransfer(const std::string& filename);
++ /**
++ Same idea, but for the viewer about to call InitiateDownload to track what it requested.
++ */
++ virtual void expectFileForRequest(const std::string& filename);
++ virtual bool validateFileForRequest(const std::string& filename);
+
+ /*
+ // xfer request (may be memory or file)
+Index: indra/llmessage/llxfermanager.cpp
+===================================================================
+--- indra/llmessage/llxfermanager.cpp (revision 97603)
++++ indra/llmessage/llxfermanager.cpp (revision 98760)
+@@ -713,11 +713,83 @@
+
+ ///////////////////////////////////////////////////////////
+
++static bool find_and_remove(std::multiset<std::string>& files,
++ const std::string& filename)
++{
++ std::multiset<std::string>::iterator ptr;
++ if ( (ptr = files.find(filename)) != files.end())
++ {
++ //erase(filename) erases *all* entries with that key
++ files.erase(ptr);
++ return true;
++ }
++ return false;
++}
++
++void LLXferManager::expectFileForRequest(const std::string& filename)
++{
++ mExpectedRequests.insert(filename);
++}
++
++bool LLXferManager::validateFileForRequest(const std::string& filename)
++{
++ return find_and_remove(mExpectedRequests, filename);
++}
++
++void LLXferManager::expectFileForTransfer(const std::string& filename)
++{
++ mExpectedTransfers.insert(filename);
++}
++
++bool LLXferManager::validateFileForTransfer(const std::string& filename)
++{
++ return find_and_remove(mExpectedTransfers, filename);
++}
++
++static bool remove_prefix(std::string& filename, const std::string& prefix)
++{
++ if (std::equal(prefix.begin(), prefix.end(), filename.begin()))
++ {
++ filename = filename.substr(prefix.length());
++ return true;
++ }
++ return false;
++}
++
++static bool verify_cache_filename(const std::string& filename)
++{
++ //NOTE: This routine is only used to check file names that our own
++ // code places in the cache directory. As such, it can be limited
++ // to this very restrictive file name pattern. It does not need to
++ // handle other characters.
++
++ size_t len = filename.size();
++ //const boost::regex expr("[a-zA-Z0-9][-_.a-zA-Z0-9]<0,49>");
++ if (len < 1 || len > 50)
++ {
++ return false;
++ }
++ for(unsigned i=0; i<len; ++i)
++ {
++ char c = filename[i];
++ bool ok = isalnum(c);
++ if (!ok && i > 0)
++ {
++ ok = '_'==c || '-'==c || '.'==c;
++ }
++ if (!ok)
++ {
++ return false;
++ }
++ }
++ return true;
++}
++
+ void LLXferManager::processFileRequest (LLMessageSystem *mesgsys, void ** /*user_data*/)
+ {
+
+ U64 id;
+- std::string local_filename;
++ std::string local_filename;
+ ELLPath local_path = LL_PATH_NONE;
+ S32 result = LL_ERR_NOERR;
+ LLUUID uuid;
+@@ -732,18 +804,17 @@
+ llinfos << "xfer request id: " << U64_to_str(id, U64_BUF, sizeof(U64_BUF))
+ << " to " << mesgsys->getSender() << llendl;
+
+- mesgsys->getStringFast(_PREHASH_XferID, _PREHASH_Filename, local_filename);
++ {
++ char buffer[MAX_STRING]; /* Flawfinder : ignore */
++ mesgsys->getStringFast(_PREHASH_XferID, _PREHASH_Filename, MAX_STRING, buffer);
++ local_filename = buffer;
++ }
+
+- U8 local_path_u8;
+- mesgsys->getU8("XferID", "FilePath", local_path_u8);
+- if( local_path_u8 < (U8)LL_PATH_LAST )
+ {
++ U8 local_path_u8;
++ mesgsys->getU8("XferID", "FilePath", local_path_u8);
+ local_path = (ELLPath)local_path_u8;
+ }
+- else
+- {
+- llwarns << "Invalid file path in LLXferManager::processFileRequest() " << (U32)local_path_u8 << llendl;
+- }
+
+ mesgsys->getUUIDFast(_PREHASH_XferID, _PREHASH_VFileID, uuid);
+ mesgsys->getS16Fast(_PREHASH_XferID, _PREHASH_VFileType, type_s16);
+@@ -780,8 +851,45 @@
+ llerrs << "Xfer allcoation error" << llendl;
+ }
+ }
+- else if (!local_filename.empty())
++ else if (!local_filename.empty())
+ {
++ // See DEV-21775 for detailed security issues
++
++ if (local_path == LL_PATH_NONE)
++ {
++ // this handles legacy simulators that are passing objects
++ // by giving a filename that explicitly names the cache directory
++ static const std::string legacy_cache_prefix = "data/";
++ if (remove_prefix(local_filename, legacy_cache_prefix))
++ {
++ local_path = LL_PATH_CACHE;
++ }
++ }
++
++ switch (local_path)
++ {
++ case LL_PATH_NONE:
++ if(!validateFileForTransfer(local_filename))
++ {
++ llwarns << "SECURITY: Unapproved filename '" << local_filename << llendl;
++ return;
++ }
++ break;
++
++ case LL_PATH_CACHE:
++ if(!verify_cache_filename(local_filename))
++ {
++ llwarns << "SECURITY: Illegal cache filename '" << local_filename << llendl;
++ return;
++ }
++ break;
++
++ default:
++ llwarns << "SECURITY: Restricted file dir enum: " << (U32)local_path << llendl;
++ return;
++ }
++
++
+ std::string expanded_filename = gDirUtilp->getExpandedFilename( local_path, local_filename );
+ llinfos << "starting file transfer: " << expanded_filename << " to " << mesgsys->getSender() << llendl;
+
+@@ -861,6 +969,7 @@
+ }
+ }
+
++
+ ///////////////////////////////////////////////////////////
+
+ void LLXferManager::processConfirmation (LLMessageSystem *mesgsys, void ** /*user_data*/)
--
A client for connecting to 3D metaverses such as Linden Labs Secondlife(tm) and OpenSim grids
More information about the Pkg-games-commits
mailing list