muyinliu / cl-cpus

A Common Lisp feature to get number of CPUs on Linux/Mac/Windows
ISC License
29 stars 3 forks source link

Fix #4 #5

Open LdBeth opened 2 years ago

LdBeth commented 2 years ago

oldlenp was not correctly initialized according to man 3 sysctl.

The information is copied into the buffer specified by oldp. The size of the buffer is given by the location specified by oldlenp before the call, and that location gives the amount of data copied after a successful call and after a call that returns with the error code ENOMEM.

This should fix the problem on macOS/OS X, and potentially other BSDs.

CatherineTower commented 2 years ago

This will work, but at least on FreeBSD hw.ncpu is currently specified to return an int, not a uint. There is also theoretically a potential buffer overflow vulnerability if you only allocate a single int for oldp; the number of elements -- that is, the value that goes in oldlenp -- is put there by a sysctl call where oldp is null, and you can use that number to allocate space for oldp. Because of this, I'd recommend something like:

(cffi:with-foreign-object (oldlenp :size)
      (sysctl name-pointer 2 (cffi:null-pointer) oldlenp (cffi:null-pointer) 0)
      (cffi:with-foreign-object (oldp :int (cffi:mem-ref oldlenp :size))
        (let ((result (sysctl name-pointer 2 oldp oldlenp (cffi:null-pointer) 0)))

From a practical standpoint, the above almost definitely isn't necessary, it's a mostly safe assumption that the result will fit in a single int. But the above conforms to the sysctl documentation on FreeBSD

The change also makes CL-CPUS work under CCL and ECL on FreeBSD, by my testing