#29027: file_move_safe error with SELinux
------------------------------------------------+-------------------------
               Reporter:  bhargu                |          Owner:  nobody
                   Type:  Bug                   |         Status:  new
              Component:  File uploads/storage  |        Version:  1.11
               Severity:  Normal                |       Keywords:  selinux
           Triage Stage:  Unreviewed            |      Has patch:  0
    Needs documentation:  0                     |    Needs tests:  0
Patch needs improvement:  0                     |  Easy pickings:  0
                  UI/UX:  0                     |
------------------------------------------------+-------------------------
 PermissionError on upload of large files (large enough to not use the in-
 memory file class) when SELinux is in enforce mode.

 The error happens after the file is copied to the destination folder. As
 seen in the trace below, when copystat is called from file_move_safe,
 shutil tries to set attributes with setxattr. But this is failing when
 SELinux is enabled. I noticed on temporarily disabling SELinux that the
 files which are successfully uploaded now have a context of 'httpd_tmp_t'
 as opposed to the context of 'httpd_sys_rw_content_t' which the directory
 is configured with.

 So, when SELinux is enabled, setxattr is failing when the context of the
 file is 'httpd_sys_rw_content_t'.

 {{{
 Traceback (most recent call last):
   File "/home/portal/venv/lib/python3.6/site-
 packages/django/core/handlers/exception.py", line 41, in inner
     response = get_response(request)
   File "/home/portal/venv/lib/python3.6/site-
 packages/django/core/handlers/base.py", line 249, in _legacy_get_response
     response = self._get_response(request)
   File "/home/portal/venv/lib/python3.6/site-
 packages/django/core/handlers/base.py", line 187, in _get_response
     response = self.process_exception_by_middleware(e, request)
   File "/home/portal/venv/lib/python3.6/site-
 packages/django/core/handlers/base.py", line 185, in _get_response
     response = wrapped_callback(request, *callback_args,
 **callback_kwargs)
   File "/home/portal/venv/lib/python3.6/site-
 packages/django/contrib/auth/decorators.py", line 23, in _wrapped_view
     return view_func(request, *args, **kwargs)
   File "/home/portal/project/assignments/views/views.py", line 270, in
 edit_answer
     instance.answerfile_set.create(file=upload, file_type=file)
   File "/home/portal/venv/lib/python3.6/site-
 packages/django/db/models/fields/related_descriptors.py", line 653, in
 create
     return super(RelatedManager, self.db_manager(db)).create(**kwargs)
   File "/home/portal/venv/lib/python3.6/site-
 packages/django/db/models/manager.py", line 85, in manager_method
     return getattr(self.get_queryset(), name)(*args, **kwargs)
   File "/home/portal/venv/lib/python3.6/site-
 packages/django/db/models/query.py", line 394, in create
     obj.save(force_insert=True, using=self.db)
   File "/home/portal/venv/lib/python3.6/site-
 packages/django/db/models/base.py", line 808, in save
     force_update=force_update, update_fields=update_fields)
   File "/home/portal/venv/lib/python3.6/site-
 packages/django/db/models/base.py", line 838, in save_base
     updated = self._save_table(raw, cls, force_insert, force_update,
 using, update_fields)
   File "/home/portal/venv/lib/python3.6/site-
 packages/django/db/models/base.py", line 924, in _save_table
     result = self._do_insert(cls._base_manager, using, fields, update_pk,
 raw)
   File "/home/portal/venv/lib/python3.6/site-
 packages/django/db/models/base.py", line 963, in _do_insert
     using=using, raw=raw)
   File "/home/portal/venv/lib/python3.6/site-
 packages/django/db/models/manager.py", line 85, in manager_method
     return getattr(self.get_queryset(), name)(*args, **kwargs)
   File "/home/portal/venv/lib/python3.6/site-
 packages/django/db/models/query.py", line 1076, in _insert
     return query.get_compiler(using=using).execute_sql(return_id)
   File "/home/portal/venv/lib/python3.6/site-
 packages/django/db/models/sql/compiler.py", line 1111, in execute_sql
     for sql, params in self.as_sql():
   File "/home/portal/venv/lib/python3.6/site-
 packages/django/db/models/sql/compiler.py", line 1064, in as_sql
     for obj in self.query.objs
   File "/home/portal/venv/lib/python3.6/site-
 packages/django/db/models/sql/compiler.py", line 1064, in <listcomp>
     for obj in self.query.objs
   File "/home/portal/venv/lib/python3.6/site-
 packages/django/db/models/sql/compiler.py", line 1063, in <listcomp>
     [self.prepare_value(field, self.pre_save_val(field, obj)) for field in
 fields]
   File "/home/portal/venv/lib/python3.6/site-
 packages/django/db/models/sql/compiler.py", line 1013, in pre_save_val
     return field.pre_save(obj, add=True)
   File "/home/portal/venv/lib/python3.6/site-
 packages/django/db/models/fields/files.py", line 296, in pre_save
     file.save(file.name, file.file, save=False)
   File "/home/portal/venv/lib/python3.6/site-
 packages/django/db/models/fields/files.py", line 94, in save
     self.name = self.storage.save(name, content,
 max_length=self.field.max_length)
   File "/home/portal/venv/lib/python3.6/site-
 packages/django/core/files/storage.py", line 54, in save
     return self._save(name, content)
   File "/home/portal/venv/lib/python3.6/site-
 packages/django/core/files/storage.py", line 338, in _save
     file_move_safe(content.temporary_file_path(), full_path)
   File "/home/portal/venv/lib/python3.6/site-
 packages/django/core/files/move.py", line 76, in file_move_safe
     copystat(old_file_name, new_file_name)
   File "/usr/lib64/python3.6/shutil.py", line 225, in copystat
     _copyxattr(src, dst, follow_symlinks=follow)
   File "/usr/lib64/python3.6/shutil.py", line 165, in _copyxattr
     os.setxattr(dst, name, value, follow_symlinks=follow_symlinks)
 PermissionError: [Errno 13] Permission denied:
 
'/home/portal/project/media/submission/8/69_424/10465_fxjc_1_27691_uljy_1_46853.png'
 }}}

-- 
Ticket URL: <https://code.djangoproject.com/ticket/29027>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/049.a282eb68d4e8370c75c35fc4857c749c%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to