1
0
Fork 0
mirror of https://github.com/ansible-collections/community.general.git synced 2024-09-14 20:13:21 +02:00

Try to get correct buffer size to avoid races (#53547)

* Try to get correct buffer size to avoid races

  fixes #51393

* fix test, mock buffer function since all is mocked
This commit is contained in:
Brian Coca 2019-03-14 11:04:56 -04:00 committed by GitHub
parent 86405b8fe4
commit e280f2f7b0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 37 additions and 18 deletions

View file

@ -0,0 +1,2 @@
bugfixes:
- Attempt to avoid race condition based on incorrect buffer size assumptions

View file

@ -47,25 +47,27 @@ PASS_BOOLS = ('no_log', 'debug', 'diff')
import __main__ import __main__
import atexit import atexit
import locale
import os
import re
import shlex
import signal
import subprocess
import sys
import types
import time
import select
import shutil
import stat
import tempfile
import traceback
import grp
import pwd
import platform
import errno import errno
import datetime import datetime
import grp
import fcntl
import locale
import os
import pwd
import platform
import re
import select
import shlex
import shutil
import signal
import stat
import subprocess
import sys
import tempfile
import time
import traceback
import types
from collections import deque from collections import deque
from itertools import chain, repeat from itertools import chain, repeat
@ -2584,7 +2586,7 @@ class AnsibleModule(object):
def _read_from_pipes(self, rpipes, rfds, file_descriptor): def _read_from_pipes(self, rpipes, rfds, file_descriptor):
data = b('') data = b('')
if file_descriptor in rfds: if file_descriptor in rfds:
data = os.read(file_descriptor.fileno(), 9000) data = os.read(file_descriptor.fileno(), self.get_buffer_size(file_descriptor))
if data == b(''): if data == b(''):
rpipes.remove(file_descriptor) rpipes.remove(file_descriptor)
@ -2905,6 +2907,20 @@ class AnsibleModule(object):
# In 2.0, moved from inside the module to the toplevel # In 2.0, moved from inside the module to the toplevel
is_executable = is_executable is_executable = is_executable
@staticmethod
def get_buffer_size(fd):
try:
# 1032 == FZ_GETPIPE_SZ
buffer_size = fcntl.fcntl(fd, 1032)
except Exception:
try:
# not as exact as above, but should be good enough for most platforms that fail the previous call
buffer_size = select.PIPE_BUF
except Exception:
buffer_size = 9000 # use sane default JIC
return buffer_size
def get_module_path(): def get_module_path():
return os.path.dirname(os.path.realpath(__file__)) return os.path.dirname(os.path.realpath(__file__))

View file

@ -83,6 +83,7 @@ def rc_am(mocker, am, mock_os, mock_subprocess):
am.fail_json = mocker.MagicMock(side_effect=SystemExit) am.fail_json = mocker.MagicMock(side_effect=SystemExit)
am._os = mock_os am._os = mock_os
am._subprocess = mock_subprocess am._subprocess = mock_subprocess
am.get_buffer_size = mocker.MagicMock(return_value=900)
yield am yield am