Replace FWRITE with a function

In a few places we use the FWRITE() macro to open a file, replace it's
contents with a given string and close it again.  There's no real
reason this needs to be a macro rather than just a function though.
Turn it into a function 'write_file()' and make some ancillary
cleanups while we're there:
  - Add a return code so the caller can handle giving a useful error message
  - Handle the case of short write()s (unlikely, but possible)
  - Add O_TRUNC, to make sure we replace the existing contents entirely

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
This commit is contained in:
David Gibson 2022-10-14 15:25:32 +11:00 committed by Stefano Brivio
parent 096e48669b
commit ea5936dd3f
4 changed files with 45 additions and 22 deletions

View file

@ -130,7 +130,8 @@ void isolate_initial(void)
*/ */
void isolate_user(uid_t uid, gid_t gid, bool use_userns, const char *userns) void isolate_user(uid_t uid, gid_t gid, bool use_userns, const char *userns)
{ {
char nsmap[BUFSIZ]; char uidmap[BUFSIZ];
char gidmap[BUFSIZ];
/* First set our UID & GID in the original namespace */ /* First set our UID & GID in the original namespace */
if (setgroups(0, NULL)) { if (setgroups(0, NULL)) {
@ -185,14 +186,14 @@ void isolate_user(uid_t uid, gid_t gid, bool use_userns, const char *userns)
} }
/* Configure user and group mappings */ /* Configure user and group mappings */
snprintf(nsmap, BUFSIZ, "0 %u 1", uid); snprintf(uidmap, BUFSIZ, "0 %u 1", uid);
FWRITE("/proc/self/uid_map", nsmap, "Cannot set uid_map in namespace"); snprintf(gidmap, BUFSIZ, "0 %u 1", gid);
FWRITE("/proc/self/setgroups", "deny", if (write_file("/proc/self/uid_map", uidmap) ||
"Cannot write to setgroups in namespace"); write_file("/proc/self/setgroups", "deny") ||
write_file("/proc/self/gid_map", gidmap)) {
snprintf(nsmap, BUFSIZ, "0 %u 1", gid); warn("Couldn't configure user namespace");
FWRITE("/proc/self/gid_map", nsmap, "Cannot set gid_map in namespace"); }
} }
/** /**

View file

@ -167,8 +167,8 @@ static int pasta_setup_ns(void *arg)
{ {
const struct pasta_setup_ns_arg *a; const struct pasta_setup_ns_arg *a;
FWRITE("/proc/sys/net/ipv4/ping_group_range", "0 0", if (write_file("/proc/sys/net/ipv4/ping_group_range", "0 0"))
"Cannot set ping_group_range, ICMP requests might fail"); warn("Cannot set ping_group_range, ICMP requests might fail");
a = (const struct pasta_setup_ns_arg *)arg; a = (const struct pasta_setup_ns_arg *)arg;
execvp(a->exe, a->argv); execvp(a->exe, a->argv);

33
util.c
View file

@ -449,3 +449,36 @@ int fls(unsigned long x)
return y; return y;
} }
/**
* write_file() - Replace contents of file with a string
* @path: File to write
* @buf: String to write
*
* Return: 0 on success, -1 on any error
*/
int write_file(const char *path, const char *buf)
{
int fd = open(path, O_WRONLY | O_TRUNC | O_CLOEXEC);
size_t len = strlen(buf);
if (fd < 0) {
warn("Could not open %s: %s", path, strerror(errno));
return -1;
}
while (len) {
ssize_t rc = write(fd, buf, len);
if (rc <= 0) {
warn("Couldn't write to %s: %s", path, strerror(errno));
break;
}
buf += rc;
len -= rc;
}
close(fd);
return len == 0 ? 0 : -1;
}

13
util.h
View file

@ -53,18 +53,6 @@
#define TMPDIR "/tmp" #define TMPDIR "/tmp"
#endif #endif
#define FWRITE(path, buf, str) \
do { \
int flags = O_WRONLY | O_CLOEXEC; \
int fd = open(path, flags); \
\
if (fd < 0 || \
write(fd, buf, strlen(buf)) != (int)strlen(buf)) \
warn(str); \
if (fd >= 0) \
close(fd); \
} while (0)
#define V4 0 #define V4 0
#define V6 1 #define V6 1
#define IP_VERSIONS 2 #define IP_VERSIONS 2
@ -212,5 +200,6 @@ int ns_enter(const struct ctx *c);
void write_pidfile(int fd, pid_t pid); void write_pidfile(int fd, pid_t pid);
int __daemon(int pidfile_fd, int devnull_fd); int __daemon(int pidfile_fd, int devnull_fd);
int fls(unsigned long x); int fls(unsigned long x);
int write_file(const char *path, const char *buf);
#endif /* UTIL_H */ #endif /* UTIL_H */