From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=-3.4 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED,RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL autolearn=ham autolearn_force=no version=3.4.4 Received: (qmail 17947 invoked from network); 27 Aug 2021 13:15:20 -0000 Received: from mother.openwall.net (195.42.179.200) by inbox.vuxu.org with ESMTPUTF8; 27 Aug 2021 13:15:20 -0000 Received: (qmail 1855 invoked by uid 550); 27 Aug 2021 13:15:18 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Reply-To: musl@lists.openwall.com Received: (qmail 1837 invoked from network); 27 Aug 2021 13:15:17 -0000 X-Virus-Scanned: Debian amavisd-new at disroot.org Mime-Version: 1.0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=disroot.org; s=mail; t=1630070103; bh=PiRzn3k+94ok8+LPhwjK+scBQ/ABsOV+3BWymIUhqw4=; h=To:Subject:From:Date:In-Reply-To; b=lci/wuP2d/UfphKG+eCzzwaDw+iXO+0kdOl/0s1Fb9Xq8h5FWmUelWCOo6iBe1EmB X+UKGksVi+D/z51iiV0oOCF/ZY7xg3xdPq2XQosCOEDLOuttIFQFuiNXEANY+KzLvi DleBvlWR0/mbzVtnJW6Xjm7dTItbL8pkPst44Jf2xgMjaFieG0GMcG4A9kNmt3I19g h0Cf/5YbyyI12i0upoFZ4TBkhQSbyLRZNcmKmop9KAAs5DB7ogsBdGwUvQVE4FaAv7 VEHI1E+cGA/+90a7essazLDl4cvqnybfAhWptgrVRNIA01IFCXUT4jGVk6HeSv+z/Y xuRIBOUo+1lTQ== Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=UTF-8 To: From: =?utf-8?q?=C3=89rico_Nogueira?= Date: Fri, 27 Aug 2021 10:05:21 -0300 Message-Id: In-Reply-To: Subject: Re: [musl] What if the line in /proc/mounts is too long when calling getmntent_r? Unfortunately your message was sent all garbled (please try to stick to plain text email ;), so I'm reproducing it cleanly underneath with my answer: >Hi! > I want to get cgroups mount information from /proc/mounts, but when i ca= lling struct mntent *getmntent_r(FILE *f, struct mntent *mnt, char *linebuf= , int buflen), i got nothing... > I run the program in a container. > > alpine docker image: amd64/alpine:3.14 > musl: 1.2.2 > program: =20 > > #include > > #include > > #include > > > #define CGROUP_MAX_VAL 512 > > > int main(void) > > { > > struct mntent ent; > > FILE *f; > > char buf[CGROUP_MAX_VAL]; > > > f =3D setmntent("/proc/mounts", "r"); > > if (f =3D=3D NULL) { > > perror("setmntent"); > > exit(1); > > } > > > while (getmntent_r(f, &ent, buf, sizeof(buf)) !=3D NULL) { > > printf("%s %s\n", ent.mnt_type, ent.mnt_opts); > > } The man page specifies that getmntent_r can return NULL on error, you should check errno to see if anything happened. In this case, it would be ERANGE, which tells you your buffer was too small. > > > endmntent(f); > > } > > contents of file "/proc/mounts" > > overlay / overlay rw,relatime,lowerdir=3D/var/lib/containerd/io.contai= nerd.snapshotter.v1.overlayfs/snapshots/955/fs:/var/lib/containerd/io.conta= inerd.snapshotter.v1.overlayfs/snapshots/954/fs:/var/lib/containerd/io.cont= ainerd.snapshotter.v1.overlayfs/snapshots/953/fs:/var/lib/containerd/io.con= tainerd.snapshotter.v1.overlayfs/snapshots/952/fs:/var/lib/containerd/io.co= ntainerd.snapshotter.v1.overlayfs/snapshots/941/fs:/var/lib/containerd/io.c= ontainerd.snapshotter.v1.overlayfs/snapshots/940/fs:/var/lib/containerd/io.= containerd.snapshotter.v1.overlayfs/snapshots/879/fs:/var/lib/containerd/io= .containerd.snapshotter.v1.overlayfs/snapshots/325/fs,upperdir=3D/var/lib/c= ontainerd/io.containerd.snapshotter.v1.overlayfs/snapshots/956/fs,workdir= =3D/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/956= /work 0 0 > > proc /proc proc rw,nosuid,nodev,noexec,relatime 0 0 > > tmpfs /dev tmpfs rw,nosuid,size=3D65536k,mode=3D755 0 0 > > devpts /dev/pts devpts rw,nosuid,noexec,relatime,gid=3D5,mode=3D620,pt= mxmode=3D666 0 0 > > mqueue /dev/mqueue mqueue rw,nosuid,nodev,noexec,relatime 0 0 > > sysfs /sys sysfs ro,nosuid,nodev,noexec,relatime 0 0 > > tmpfs /sys/fs/cgroup tmpfs rw,nosuid,nodev,noexec,relatime,mode=3D755 = 0 0 > > cgroup /sys/fs/cgroup/systemd cgroup rw,nosuid,nodev,noexec,relatime,x= attr,release_agent=3D/usr/lib/systemd/systemd-cgroups-agent,name=3Dsystemd = 0 0 > > cgroup /sys/fs/cgroup/net_cls,net_prio cgroup rw,nosuid,nodev,noexec,r= elatime,net_prio,net_cls 0 0 > > cgroup /sys/fs/cgroup/pids cgroup rw,nosuid,nodev,noexec,relatime,pids= 0 0 > > cgroup /sys/fs/cgroup/hugetlb cgroup rw,nosuid,nodev,noexec,relatime,h= ugetlb 0 0 > > cgroup /sys/fs/cgroup/cpuset cgroup rw,nosuid,nodev,noexec,relatime,cp= uset 0 0 > > cgroup /sys/fs/cgroup/blkio cgroup rw,nosuid,nodev,noexec,relatime,blk= io 0 0 > > cgroup /sys/fs/cgroup/devices cgroup rw,nosuid,nodev,noexec,relatime,d= evices 0 0 > > cgroup /sys/fs/cgroup/freezer cgroup rw,nosuid,nodev,noexec,relatime,f= reezer 0 0 > > cgroup /sys/fs/cgroup/cpu,cpuacct cgroup rw,nosuid,nodev,noexec,relati= me,cpuacct,cpu 0 0 > > cgroup /sys/fs/cgroup/memory cgroup rw,nosuid,nodev,noexec,relatime,me= mory 0 0 > > cgroup /sys/fs/cgroup/perf_event cgroup rw,nosuid,nodev,noexec,relatim= e,perf_event 0 0 > > ... > > > I find the first line of the file /proc/mounts has 822 characters(In the= ory the 'overlay' could be even longer), more than CGROUP_MAX_VAL(512) defi= ned in the proagram. Function fget in getmntent_r cann't get the whole line= into linebuf, neither the character '\n'. And the function strchr(linebuf,= '\n') returns false, causing program returnd.=20 > The function struct mntent *getmntent(FILE *f) is a good chioce to deal = this. But it can not be used in multiple threads, right? Correct, getmntent isn't thread safe. > Maybe the implementation of GNU libc struct mntent *__getmntent_r (FILE = *stream, struct mntent *mp, char *buffer, int bufsiz) can be referenced. >From what I can see, glibc silently throws away any and all chars that don't fit in the provided buffer until it finds a newline. getmntent_r isn't actually specified, so I guess its behavior is a bit up to the implementation. Anyhow, musl's reports ERANGE properly (maybe the man page can be fixed to mention it?) and you should use a dynamic buffer in your program if you expect to deal with huge entries, and resize it if getmntent_r fails with ERANGE. > > thanks!