mailing list of musl libc
 help / color / mirror / code / Atom feed
From: Rich Felker <dalias@libc.org>
To: "Érico Nogueira" <ericonr@disroot.org>
Cc: musl@lists.openwall.com, 2010267516@qq.com
Subject: Re: [musl] What if the line in /proc/mounts is too long when calling getmntent_r?
Date: Fri, 27 Aug 2021 09:43:03 -0400	[thread overview]
Message-ID: <20210827134302.GT13220@brightrain.aerifal.cx> (raw)
In-Reply-To: <CDUBVDODC5FS.34VW9LO9J3IAW@mussels>

On Fri, Aug 27, 2021 at 10:26:35AM -0300, Érico Nogueira wrote:
> Apparently I failed to CC you	in my original reply, sorry.
> 
> Forwarded message from Érico Nogueira on Fri Aug 27, 2021 at 10:05 AM:
> 
> 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 calling 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:  
> >
> >    #include <stdio.h>
> >
> >    #include <stdlib.h>
> >
> >    #include <mntent.h>
> >
> >
> >    #define CGROUP_MAX_VAL 512
> >
> >
> >    int main(void)
> >
> >    {
> >
> >      struct mntent ent;
> >
> >      FILE *f;
> >
> >      char buf[CGROUP_MAX_VAL];
> >
> >
> >      f = setmntent("/proc/mounts", "r");
> >
> >      if (f == NULL) {
> >
> >        perror("setmntent");
> >
> >        exit(1);
> >
> >      }
> >
> >
> >      while (getmntent_r(f, &ent, buf, sizeof(buf)) != 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=/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/955/fs:/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/954/fs:/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/953/fs:/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/952/fs:/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/941/fs:/var/lib/containerd/io.containerd.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=/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/956/fs,workdir=/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=65536k,mode=755 0 0
> >
> >    devpts /dev/pts devpts rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=666 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=755 0 0
> >
> >    cgroup /sys/fs/cgroup/systemd cgroup rw,nosuid,nodev,noexec,relatime,xattr,release_agent=/usr/lib/systemd/systemd-cgroups-agent,name=systemd 0 0
> >
> >    cgroup /sys/fs/cgroup/net_cls,net_prio cgroup rw,nosuid,nodev,noexec,relatime,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,hugetlb 0 0
> >
> >    cgroup /sys/fs/cgroup/cpuset cgroup rw,nosuid,nodev,noexec,relatime,cpuset 0 0
> >
> >    cgroup /sys/fs/cgroup/blkio cgroup rw,nosuid,nodev,noexec,relatime,blkio 0 0
> >
> >    cgroup /sys/fs/cgroup/devices cgroup rw,nosuid,nodev,noexec,relatime,devices 0 0
> >
> >    cgroup /sys/fs/cgroup/freezer cgroup rw,nosuid,nodev,noexec,relatime,freezer 0 0
> >
> >    cgroup /sys/fs/cgroup/cpu,cpuacct cgroup rw,nosuid,nodev,noexec,relatime,cpuacct,cpu 0 0
> >
> >    cgroup /sys/fs/cgroup/memory cgroup rw,nosuid,nodev,noexec,relatime,memory 0 0
> >
> >    cgroup /sys/fs/cgroup/perf_event cgroup rw,nosuid,nodev,noexec,relatime,perf_event 0 0
> >
> >    ...
> >
> >
> >  I find the first line of the file /proc/mounts has 822 characters(In theory the 'overlay' could be even longer), more than CGROUP_MAX_VAL(512) defined 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. 
> >  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.

I'm not sure what the right way to recover in that situation is
supposed to be, though... You can't just call it again with musl's
current implementation or you'll start in the middle of a line, which
is clearly wrong. But if you do the glibc thing and throw away the
rest of the line, you also lose a line of data.

Rich

  reply	other threads:[~2021-08-27 13:43 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-08-27 13:26 Érico Nogueira
2021-08-27 13:43 ` Rich Felker [this message]
2021-08-28  2:58   ` Érico Nogueira
2021-08-28  6:17     ` Markus Wichmann
  -- strict thread matches above, loose matches on Subject: below --
2021-08-27  4:48 care
2021-08-27 13:05 ` Érico Nogueira

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210827134302.GT13220@brightrain.aerifal.cx \
    --to=dalias@libc.org \
    --cc=2010267516@qq.com \
    --cc=ericonr@disroot.org \
    --cc=musl@lists.openwall.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/musl/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).