java: max_mem_meminfo integer overflow

Hi,

we are using fabric8 images to run our spring-boot based java applications.

Since we updated to the latest version (44ef6f145b51 from dockerhub) we had problems with the container detecting & defining the right amount of memory. The container on startup does not include the XMX option.

Steps to reproduce

  1. Start container with docker run -m2G - to limit memory to 2G of RAM - on a machine which has at least 16G of RAM
  2. Run run-java.sh with arbitrary JAR
  3. Note that there is no XMX flag present in the startup options

Bug description

We think that the issue is caused by an integer overflow in method max_memory(), line:

    local max_mem_meminfo="$(cat /proc/meminfo | awk '/MemTotal/ {printf "%d\n", $2 * 1024}')"

If the system’s available memory is 16G then ‘MemTotal’ is:

/deployments # cat /proc/meminfo | grep 'MemTotal'
MemTotal:       16295228 kB

If you multiply that by 1024, it’s going to overflow to the negative range:

/deployments # cat /proc/meminfo | awk '/MemTotal/ {printf "%d\n", $2 * 1024'}
-2147483648

Then the condition expressed by:

if [ ${max_mem_cgroup:-0} != -1 ] && [ ${max_mem_cgroup:-0} -lt ${max_mem_meminfo:-0} ]

is not going to be true, so CONTAINER_MAX_MEMORY will not be set and exported, causing the exec line to contain no memory related options.

Also, thanks for @arnoldtempfli for investigating this.

System info:

[mate@devmate ~]$ uname -a
Linux devmate 4.14.6-1-ARCH #1 SMP PREEMPT Thu Dec 14 21:26:16 UTC 2017 x86_64 GNU/Linux

[mate@devmate ~]$ docker --version
Docker version 17.11.0-ce, build 1caf76ce6b

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 9
  • Comments: 20 (12 by maintainers)

Commits related to this issue

Most upvoted comments

Sorry, a release is already long outstanding. I hope I can get it in this week (although beeing on the road at the moment)

There are many ways to skin the cat:

maxmem_kb=$(cat /proc/meminfo | awk '/MemTotal/ { print $2 }')

# with bash builtin as in your example 
# (however the run scripts is supposed to work not only on bash, 
# so this solution is not possible for us)
maxmem=$(( $maxmem_kb * 1024 ))

# with expr:
maxmem=$(expr $maxmem_kb \* 1024)

# with good old dc:
maxmem=$(echo $maxmem_kb 1024 \* p | dc)

Actually I tend to the expr solution as this is the most straight forward one.