Bug 199673

Summary: sysctl(8) suffers a multiplication overflow when formatting vm.vmtotal
Product: Base System Reporter: Vitaly Magerya <vmagerya>
Component: binAssignee: Alan Somers <asomers>
Status: Closed FIXED    
Severity: Affects Only Me CC: asomers
Priority: --- Keywords: patch
Version: 10.0-RELEASEFlags: asomers: mfc-stable10+
Hardware: amd64   
OS: Any   
Attachments:
Description Flags
sysctl-overflow.diff none

Description Vitaly Magerya 2015-04-24 19:05:10 UTC
Created attachment 155955 [details]
sysctl-overflow.diff

Here's a part of 'sysctl vm.mvtotal' output on my 10.0/amd64
machine:

  % sysctl vm.vmtotal
  [...]
  Virtual Memory:         (Total: 1654588K Active: 1536668K)
  [...]

If on the other hand, when I try to retrieve the same data via
sysctl(3), I get different total virtual memory:

  % cat >test.c <<'EOF'
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/sysctl.h>
#include <sys/vmmeter.h>

int main() {
    struct vmtotal vt = {0};
    size_t vtlen = sizeof(vt);
    if (sysctlbyname("vm.vmtotal", &vt, &vtlen, NULL, 0) != 0)
        return -1;
    ssize_t pagesize = getpagesize()/1024;
    printf("vm.vmtotal.t_vm = %zd pages (%zd kB)\n",
            (ssize_t)vt.t_vm,
            pagesize*vt.t_vm);
    return 0;
}
'EOF'
  % c99 test.c && ./a.out
  vm.vmtotal.t_vm = 1074154446 pages (4296617784 kB)

As you can see, the actual data coming out of sysctl(3) is
4296617784K, not 1654588K as sysctl(8) says. This is because
sysctl(8) has a multiplication overflow in the 'S_vmtotal'
function [1] when the number of pages ('t_vm') is multiplied by
the page size ('pageKilo').

I'm attaching a (completely untested) patch to fix this problem;
apply this patch to 'sbin/sysctl/sysctl.c'.

[1] http://svnweb.freebsd.org/base/head/sbin/sysctl/sysctl.c?revision=278654&view=markup#l530
Comment 1 commit-hook freebsd_committer freebsd_triage 2016-06-24 14:58:52 UTC
A commit references this bug:

Author: asomers
Date: Fri Jun 24 14:58:38 UTC 2016
New revision: 302174
URL: https://svnweb.freebsd.org/changeset/base/302174

Log:
  Fix "sysctl vm.vmtotal" output on machines with > 2TB virtual memory

  sbin/sysctl/sysctl.c
  	Fix integer overflows in printf format strings

  PR:		199673
  Submitted by:	Vitaly Magerya
  Reviewed by:	cem
  Approved by:	re (marius)
  MFC after:	4 weeks
  Sponsored by:	Spectra Logic Corp
  Differential Revision:	https://reviews.freebsd.org/D6941

Changes:
  head/sbin/sysctl/sysctl.c
Comment 2 commit-hook freebsd_committer freebsd_triage 2016-07-12 22:20:09 UTC
A commit references this bug:

Author: asomers
Date: Tue Jul 12 22:19:25 UTC 2016
New revision: 302688
URL: https://svnweb.freebsd.org/changeset/base/302688

Log:
  MFC r302174

  Fix "sysctl vm.vmtotal" output on machines with > 2TB virtual memory

  sbin/sysctl/sysctl.c
          Fix integer overflows in printf format strings

  PR:		199673

Changes:
_U  stable/10/
  stable/10/sbin/sysctl/sysctl.c