1212#include "cgroup-util.h"
1313#include "dirent-util.h"
1414#include "env-util.h"
15+ #include "errno-util.h"
1516#include "fd-util.h"
1617#include "fileio.h"
1718#include "macro.h"
@@ -791,10 +792,7 @@ int detect_virtualization(void) {
791792
792793static int userns_has_mapping (const char * name ) {
793794 _cleanup_fclose_ FILE * f = NULL ;
794- _cleanup_free_ char * buf = NULL ;
795- size_t n_allocated = 0 ;
796- ssize_t n ;
797- uint32_t a , b , c ;
795+ uid_t a , b , c ;
798796 int r ;
799797
800798 f = fopen (name , "re" );
@@ -803,19 +801,17 @@ static int userns_has_mapping(const char *name) {
803801 return errno == ENOENT ? false : - errno ;
804802 }
805803
806- n = getline (& buf , & n_allocated , f );
807- if (n < 0 ) {
808- if (feof (f )) {
809- log_debug ("%s is empty, we're in an uninitialized user namespace" , name );
810- return true;
811- }
804+ errno = 0 ;
805+ r = fscanf (f , UID_FMT " " UID_FMT " " UID_FMT "\n" , & a , & b , & c );
806+ if (r == EOF ) {
807+ if (ferror (f ))
808+ return log_debug_errno (errno_or_else (EIO ), "Failed to read %s: %m" , name );
812809
813- return log_debug_errno (errno , "Failed to read %s: %m" , name );
810+ log_debug ("%s is empty, we're in an uninitialized user namespace" , name );
811+ return true;
814812 }
815-
816- r = sscanf (buf , "%" PRIu32 " %" PRIu32 " %" PRIu32 , & a , & b , & c );
817- if (r < 3 )
818- return log_debug_errno (errno , "Failed to parse %s: %m" , name );
813+ if (r != 3 )
814+ return log_debug_errno (SYNTHETIC_ERRNO (EBADMSG ), "Failed to parse %s: %m" , name );
819815
820816 if (a == 0 && b == 0 && c == UINT32_MAX ) {
821817 /* The kernel calls mappings_overlap() and does not allow overlaps */
@@ -840,19 +836,18 @@ int running_in_userns(void) {
840836 if (r != 0 )
841837 return r ;
842838
843- /* "setgroups" file was added in kernel v3.18-rc6-15-g9cc46516dd. It is also
844- * possible to compile a kernel without CONFIG_USER_NS, in which case "setgroups"
845- * also does not exist. We cannot distinguish those two cases, so assume that
846- * we're running on a stripped-down recent kernel, rather than on an old one,
847- * and if the file is not found, return false.
848- */
849- r = read_one_line_file ("/proc/self/setgroups" , & line );
839+ /* "setgroups" file was added in kernel v3.18-rc6-15-g9cc46516dd. It is also possible to compile a
840+ * kernel without CONFIG_USER_NS, in which case "setgroups" also does not exist. We cannot
841+ * distinguish those two cases, so assume that we're running on a stripped-down recent kernel, rather
842+ * than on an old one, and if the file is not found, return false. */
843+ r = read_virtual_file ("/proc/self/setgroups" , SIZE_MAX , & line , NULL );
850844 if (r < 0 ) {
851845 log_debug_errno (r , "/proc/self/setgroups: %m" );
852846 return r == - ENOENT ? false : r ;
853847 }
854848
855- truncate_nl (line );
849+ strstrip (line ); /* remove trailing newline */
850+
856851 r = streq (line , "deny" );
857852 /* See user_namespaces(7) for a description of this "setgroups" contents. */
858853 log_debug ("/proc/self/setgroups contains \"%s\", %s user namespace" , line , r ? "in" : "not in" );
0 commit comments