diff options
author | fujiwarat <takao.fujiwara1@gmail.com> | 2021-07-26 22:53:34 +0900 |
---|---|---|
committer | fujiwarat <takao.fujiwara1@gmail.com> | 2021-07-26 22:53:34 +0900 |
commit | 17ae266cade41e795534532acefc85716bb309ef (patch) | |
tree | e682002a665d45c9e971cecb95a29d26f744cf30 /src/ibusbus.c | |
parent | 4259f16324d578aa2505cf50f2f23923d8d87e76 (diff) | |
download | ibus-17ae266cade41e795534532acefc85716bb309ef.tar.gz |
Code reviews
- Use fstat() and fchmod() but not stat() and chmod() to
fix race conditions
- Avoid to use after free
- Fix dereference of IBusComposeTable->priv
- Fix to divide by zero
Diffstat (limited to 'src/ibusbus.c')
-rw-r--r-- | src/ibusbus.c | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/src/ibusbus.c b/src/ibusbus.c index e9b0bcbb..47400cb8 100644 --- a/src/ibusbus.c +++ b/src/ibusbus.c @@ -21,13 +21,14 @@ * USA */ -#include "ibusbus.h" #include <errno.h> +#include <fcntl.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <glib/gstdio.h> #include <gio/gio.h> +#include "ibusbus.h" #include "ibusmarshalers.h" #include "ibusinternal.h" #include "ibusshare.h" @@ -537,7 +538,8 @@ static void ibus_bus_init (IBusBus *bus) { struct stat buf; - gchar *path; + char *path; + int fd; bus->priv = IBUS_BUS_GET_PRIVATE (bus); @@ -562,20 +564,31 @@ ibus_bus_init (IBusBus *bus) return; } - if (stat (path, &buf) == 0) { + errno = 0; + if ((fd = open (path, O_RDONLY | O_DIRECTORY, S_IRWXU)) == -1) { + g_warning ("open %s failed: %s", path, g_strerror (errno)); + g_free (path); + return; + } + /* TOCTOU: Use fstat() and fchmod() but not stat() and chmod(). + * because it can cause a time-of-check, time-of-use race condition. + */ + if (fstat (fd, &buf) == 0) { if (buf.st_uid != getuid ()) { g_warning ("The owner of %s is not %s!", path, ibus_get_user_name ()); + close (fd); g_free (path); return; } if (buf.st_mode != (S_IFDIR | S_IRWXU)) { errno = 0; - if (g_chmod (path, 0700)) - g_warning ("chmod failed: %s", errno ? g_strerror (errno) : ""); + if (fchmod (fd, S_IRWXU)) + g_warning ("chmod failed: %s", g_strerror (errno)); } } + close (fd); g_free (path); } |