--- includes/file.inc.orig	2011-01-20 14:50:01.000000000 +0100
+++ includes/file.inc	2011-01-20 14:54:39.000000000 +0100
@@ -1523,13 +1523,22 @@ function file_save_upload($source, $vali
 
   // Move uploaded files from PHP's upload_tmp_dir to Drupal's temporary
   // directory. This overcomes open_basedir restrictions for future file
-  // operations.
-  $file->uri = $file->destination;
-  if (!move_uploaded_file($_FILES['files']['tmp_name'][$source], $file->uri)) {
+  // operations. If PHP is running under safe_mode and we are uploading
+  // files to a local directory, we first need to convert the path to a
+  // real path on the filesystem, else the security check for
+  // move_uploaded_file() will fail.
+  if (ini_get('safe_mode') && drupal_realpath($file->destination)) {
+    $real_destination = drupal_realpath($file->destination);
+  }
+  else {
+    $real_destination = $file->destination;
+  }
+  if (!move_uploaded_file($_FILES['files']['tmp_name'][$source], $real_destination)) {
     form_set_error($source, t('File upload error. Could not move uploaded file.'));
-    watchdog('file', 'Upload error. Could not move uploaded file %file to destination %destination.', array('%file' => $file->filename, '%destination' => $file->uri));
+    watchdog('file', 'Upload error. Could not move uploaded file %file to destination %destination.', array('%file' => $file->filename, '%destination' => $file->destination));
     return FALSE;
   }
+  $file->uri = $file->destination;
 
   // Set the permissions on the new file.
   drupal_chmod($file->uri);
