inotify, faccessat2, fsync for Linux programs, and D-Bus credentials
What installing and starting Epiphany ran into: - inotify: inotify_init/init1, add_watch, rm_watch, as a new kind of event descriptor. The filesystem reports creates, deletes, renames (with a cookie pairing MOVED_FROM and MOVED_TO), writes, close-after-write, truncation and attribute changes, to watches on the inode and on its directory with the name. ONESHOT, MASK_ADD, MASK_CREATE, ONLYDIR, DONT_FOLLOW, IGNORED on removal, Q_OVERFLOW, and Linux's coalescing of repeated events. The hooks cost one load when nothing is watched. Without it GLib found no file monitor and GNOME programs aborted. - FIONREAD on inotify descriptors and pipes (inotifywait sizes its buffer by it). - fsync and fdatasync had no Linux numbers since the first commit: GLib's atomic writes, gtk-update-icon-cache and dbus-uuidgen all got ENOSYS. - faccessat2, the flags-taking faccessat musl uses for any flags. - sendmsg accepts SCM_CREDENTIALS when they are the sender's own, as Linux checks; GDBus sends them in every handshake and was refused with EINVAL. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S1giNvrHTrPMPw7V6x1kQ4
This commit is contained in:
parent
c77841ce3d
commit
3113eff7fe
9 changed files with 590 additions and 9 deletions
|
|
@ -900,10 +900,31 @@ scm_gather(struct msghdr *m, struct file **fs, int *nfp)
|
|||
}
|
||||
fs[(*nfp)++] = filedup(f);
|
||||
}
|
||||
} else if (c->cmsg_level == SOL_SOCKET && c->cmsg_type == 2 /* SCM_CREDENTIALS */) {
|
||||
// Credentials, which GDBus sends with the first byte of every
|
||||
// D-Bus connection. Checked as Linux checks them -- they must be
|
||||
// the sender's own, or the sender root -- and then not delivered:
|
||||
// nothing here sets SO_PASSCRED to receive them, and the D-Bus
|
||||
// daemon asks SO_PEERCRED instead, which answers the same question
|
||||
// from the kernel's side. Refusing them made every GNOME program
|
||||
// fail its D-Bus handshake ("Error sending credentials").
|
||||
struct { int pid; uint uid, gid; } cr;
|
||||
struct proc *me = myproc();
|
||||
if (c->cmsg_len < CMSG_LEN(sizeof(cr))) {
|
||||
r = -EINVAL;
|
||||
goto fail;
|
||||
}
|
||||
memmove(&cr, CMSG_DATA(c), sizeof(cr));
|
||||
if (me->euid != 0 &&
|
||||
(cr.pid != me->tgid ||
|
||||
(cr.uid != me->uid && cr.uid != me->euid) ||
|
||||
(cr.gid != me->gid && cr.gid != me->egid))) {
|
||||
r = -EPERM;
|
||||
goto fail;
|
||||
}
|
||||
} else if (c->cmsg_level == SOL_SOCKET) {
|
||||
// SCM_CREDENTIALS and friends. Refused rather than ignored: a
|
||||
// caller that asked to pass credentials and was told yes would
|
||||
// believe the receiver got them.
|
||||
// Anything else. Refused rather than ignored: a caller that asked
|
||||
// for something and was told yes would believe it happened.
|
||||
r = -EINVAL;
|
||||
goto fail;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue