Merge "init: harden socket creation against symlinks"
am: 0f565c1ea4
* commit '0f565c1ea48aa625d4a6b2c342fd61bcbc9ca868':
init: harden socket creation against symlinks
diff --git a/init/util.cpp b/init/util.cpp
index aefdf8f..84b4155 100644
--- a/init/util.cpp
+++ b/init/util.cpp
@@ -102,7 +102,7 @@
gid_t gid, const char *socketcon)
{
struct sockaddr_un addr;
- int fd, ret;
+ int fd, ret, savederrno;
char *filecon;
if (socketcon) {
@@ -140,16 +140,26 @@
}
ret = bind(fd, (struct sockaddr *) &addr, sizeof (addr));
- if (ret) {
- ERROR("Failed to bind socket '%s': %s\n", name, strerror(errno));
- goto out_unlink;
- }
+ savederrno = errno;
setfscreatecon(NULL);
freecon(filecon);
- chown(addr.sun_path, uid, gid);
- chmod(addr.sun_path, perm);
+ if (ret) {
+ ERROR("Failed to bind socket '%s': %s\n", name, strerror(savederrno));
+ goto out_unlink;
+ }
+
+ ret = lchown(addr.sun_path, uid, gid);
+ if (ret) {
+ ERROR("Failed to lchown socket '%s': %s\n", addr.sun_path, strerror(errno));
+ goto out_unlink;
+ }
+ ret = fchmodat(AT_FDCWD, addr.sun_path, perm, AT_SYMLINK_NOFOLLOW);
+ if (ret) {
+ ERROR("Failed to fchmodat socket '%s': %s\n", addr.sun_path, strerror(errno));
+ goto out_unlink;
+ }
INFO("Created socket '%s' with mode '%o', user '%d', group '%d'\n",
addr.sun_path, perm, uid, gid);