Getrandom syscall in C not found

The problem was resolved by updating the C library.


I would like to use syscall getrandom ( http://man7.org/linux/man-pages/man2/getrandom.2.html )

gcc-5 -std = c11 test.c

#include <sys/types.h> #include <sys/stat.h> #include <sys/fcntl.h> #include <errno.h> #include <string.h> #include <signal.h> #include <linux/random.h> #include <sys/syscall.h> int main(void) { void *buf = NULL; size_t l = 5; unsigned int o = 1; int r = syscall(SYS_getrandom, buf, l, o); return 0; } 

or

  int main(void) { void *buf = NULL; size_t l = 5; unsigned int o = 1; int r = getrandom(buf, l, o); return 0; } 

Anyway, when I try to compile it with gcc-5:

 test.c: In function 'main': test.c:14:17: warning: implicit declaration of function 'getrandom' [-Wimplicit-function-declaration] int r = getrandom(buf, l, o); ^ /tmp/ccqFdJAJ.o: In function `main': test.c:(.text+0x36): undefined reference to `getrandom' collect2: error: ld returned 1 exit status 

I am using Ubuntu 14.04, what can I do to use getrandom? How is this a β€œnew” syscall, how can I use it?

edit:

 uname -r -> 4.0.3-040003-generic #201505131441 SMP Wed May 13 13:43:16 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux 

when I replace r with int r = syscall(SYS_getrandom, buf, l, o); or r = getrandom (buf, l, o) is the same.

+6
source share
5 answers

So it seems that getrandom is not a function, just syscall.

Therefore, it is necessary:

 /* Note that this define is required for syscalls to work. */ #define _GNU_SOURCE #include <unistd.h> #include <sys/syscall.h> #include <linux/random.h> int main(int arg, char *argv[]) { void *buf = NULL; size_t l = 5; unsigned int o = 1; int r = syscall(SYS_getrandom, buf, l, o); return 0; } 
+8
source

The getrandom() script was introduced in the linux 3.17 kernel. Ubuntu 14.04 ships with the 3.13 kernel, so you need to upgrade to a newer kernel to get syscall.

To get linux kernel .deb packages for Ubuntu, see kernel.ubuntu.com . This issue has also been discussed on askubuntu.com .

+5
source

getrandom and getentropy were added to glibc in version 2.25 . As of July 2017, most Linux distributions have not yet upgraded to this version (for example, the latest Debian release that has just been released has 2.24), but they should be soon.

Here's how to use glibc wrappers, if available, and return to the raw system call if not:

 #define _GNU_SOURCE 1 #include <sys/types.h> #include <unistd.h> #if defined __GLIBC__ && defined __linux__ # if __GLIBC__ > 2 || __GLIBC_MINOR__ > 24 # include <sys/random.h> int my_getentropy(void *buf, size_t buflen) { return getentropy(buf, buflen); } # else /* older glibc */ # include <sys/syscall.h> # include <errno.h> int my_getentropy(void *buf, size_t buflen) { if (buflen > 256) { errno = EIO; return -1; } return syscall(SYS_getrandom, buf, buflen, 0); } # endif #else /* not linux or not glibc */ #error "Need implementation for whatever operating system this is" #endif 

(As stated in other answers, you also need to make sure you have a kernel 3.17 or later. Both versions of my_getentropy will fail and set errno to ENOSYS if they run on an earlier kernel.)

+4
source

I think that with your program you will get a segmentation error. The following code should work:

 #include <iostream> #include <unistd.h> #include <sys/syscall.h> #include <linux/random.h> int main() { unsigned long int s; syscall(SYS_getrandom, &s, sizeof(unsigned long int), 0); std::cout << "The seed is: " << s << "." << std::endl; } 
+2
source

Here I compiled some code shown earlier and fixed the errors, including my output from gcc -v for comparison.

 // $ gcc -v // Using built-in specs. // COLLECT_GCC=gcc // COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/5/lto-wrapper // Target: x86_64-linux-gnu // Configured with: ../src/configure -v --with-pkgversion='Ubuntu // 5.4.0-6ubuntu1~16.04.9' --with-bugurl=file:///usr/share/doc/gcc-5/README.Bugs // --enable-languages=c,ada,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr // --program-suffix=-5 --enable-shared --enable-linker-build-id // --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix // --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu // --enable-libstdcxx-debug --enable-libstdcxx-time=yes // --with-default-libstdcxx-abi=new --enable-gnu-unique-object // --disable-vtable-verify --enable-libmpx --enable-plugin --with-system-zlib // --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo // --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-5-amd64/jre --enable-java-home // --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-5-amd64 // --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-5-amd64 // --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar // --enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686 // --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib // --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu // --host=x86_64-linux-gnu --target=x86_64-linux-gnu // Thread model: posix // gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.9) //#define _GNU_SOURCE #include <stdio.h> #include <unistd.h> #include <sys/syscall.h> #include <linux/random.h> int main (int arg, char **argv) { size_t length = 5; unsigned char buf[length]; int r = syscall(SYS_getrandom, buf, length, 0); if (r != 0) { int iIter; printf ("random %zu bytes = ",length); for (iIter = 0 ; iIter < length-1 ; iIter++) { printf ("%02x:", buf[iIter]); } printf ("%02x\n", buf[iIter]); } else { perror ("syscall (SYS_getrandom, ...)"); } return 0; } 
0
source

Source: https://habr.com/ru/post/988987/


All Articles