[Anthy-dev 615] Re: uim-xim and uim-helper-server problem on Mac OS X

Back to archive index

Etsushi Kato ekato****@ees*****
2004年 2月 27日 (金) 20:22:32 JST


反応がないので、いちおう補足と訂正です。

On Tue, Feb 24, 2004 at 08:32:09PM +0900,
Etsushi Kato <ekato****@ees*****> wrote:

> On Tue, Feb 17, 2004 at 11:52:34PM +0900,
> yusuk****@cheru***** wrote:
> 
> > ちょっと考えて見たのですが、Linuxの場合にst_uidが0になってたら
> > rootに攻撃されているというどうしようもない状況なので、あまり
> > 気にせずに接続することにしようと思います。
> > 
> > 一応ダメ押しで、次のようなコードにするつもりです。
> > stat(st);
> > st.st_uidが自分でなければ失敗
> > connect();
> > fstat(st);
> > st.st_uidが自分でなくて、rootでもなければ切断
> > --
> 

まず補足ですが、/tmp/uim-helper-user という socket を誰でも rw できる
ように、あるサーバが作ったとした場合、client が現状のように fstat(st) 
をチェックしても何の意味がないと思うのですがどうでしょう? 
uim-helper-client.c が現在行なっているのは、 サーバが動いている uid で
はなく 自分の st_uid をチェックしているだけだと思います。実際試してみ
ると、現在のコードでは他のユーザーが誰でも rw できるサーバを立ち上げて
しまえば、そのまま他のユーザーがconnect できてしまい、セキュリティ的に
は意味が無いと思います。

getpeereid() を使えば、接続先の euid が得られます。

> 少し調べてみましたが、getpeereid() を使えば、Unix ドメインソケットの 
> uid をチェックできそうな感じがするのですがどうでしょう? openssh の
> ssh-agent を参考にしてみました。

皆さんには書くまでもないと思いますが、getpeereid() に関しては、
http://cr.yp.to/docs/secureipc.html がある程度参考になるかもしれません 
(僕は MacOSX で uim が動かないばっかりに読んだだけですが…)。

> OpenBSD, FreeBSD には getpeereid() がありますし、Linux では
> getsockopt() で SO_PEERCRED を使うような簡単なラッパーを作ればいいよう
> です。
> 
> ただ残念ながら、Mac OS X 10.3 では getpeereid() も SO_PEERCRED も使え
> ないようなのでソケットの認証はできなさそうですが、いちおう geteuid() 
> を fallback としているようです。
> 
> NetBSD ではおそらく、setsockopt() に LOCAL_CREDS を使うようなコードが
> 必要みたいですが、試すことができないので ssh-agent と同様に fallback 
> しています。どなたかコードを付け足してください。

NetBSD のほうのサポートはどなたかNetBSD を使っている人にまかせるとして、
Mac OS X (darwin) のほうでも getpeereid 相当のものをインプルメントして
もらえばそのうち何とかなるとは思います (良く知りませんが、まあそれなり
にコンタクトはしてみようかと思います)。

現状の fstat() のチェックではどの OS でも何の意味も持たないように見え
ますが、getpeereid() を使えば、Linux, FreeBSD、OpenBSD で変換状態に関
するセキュリティが保てますし、NetBSD でも少しの変更で問題ないと思いま
す (postresql の Unix ドメンインソケットの認証が参考にできると思います)。

それでは、もういちど少し訂正の入ったパッチを送ります。

-- 
Etsushi Kato
ekato****@ees*****
-------------- next part --------------
diff -uNr uim-0.3.0.1.orig/configure.ac uim-0.3.0.1/configure.ac
--- uim-0.3.0.1.orig/configure.ac	2004-02-23 06:33:08.000000000 +0900
+++ uim-0.3.0.1/configure.ac	2004-02-27 19:59:51.000000000 +0900
@@ -125,6 +125,8 @@
 AC_FUNC_SELECT_ARGTYPES
 AC_TYPE_SIGNAL
 
+AC_CHECK_FUNCS(getpeereid)
+
 SRCDIR=$srcdir
 AC_SUBST(SRCDIR)
 
diff -uNr uim-0.3.0.1.orig/uim/Makefile.am uim-0.3.0.1/uim/Makefile.am
--- uim-0.3.0.1.orig/uim/Makefile.am	2004-02-23 04:22:19.000000000 +0900
+++ uim-0.3.0.1/uim/Makefile.am	2004-02-27 19:59:51.000000000 +0900
@@ -15,7 +15,8 @@
 		skk-dic.c anthy.c \
 		prime.c canna.c \
 		slib.c sliba.c siod.h context.h gettext.h \
-		uim-ipc.c uim-table.c
+		uim-ipc.c uim-table.c \
+		bsd-getpeereid.c
 
 
 libuimincludedir =  $(includedir)/uim
diff -uNr uim-0.3.0.1.orig/uim/Makefile.in uim-0.3.0.1/uim/Makefile.in
--- uim-0.3.0.1.orig/uim/Makefile.in	2004-02-23 06:34:19.000000000 +0900
+++ uim-0.3.0.1/uim/Makefile.in	2004-02-27 19:59:51.000000000 +0900
@@ -200,7 +200,8 @@
 		skk-dic.c anthy.c \
 		prime.c canna.c \
 		slib.c sliba.c siod.h context.h gettext.h \
-		uim-ipc.c uim-table.c
+		uim-ipc.c uim-table.c \
+		bsd-getpeereid.c
 
 
 libuimincludedir = $(includedir)/uim
@@ -226,7 +227,8 @@
 libuim_la_DEPENDENCIES =
 am_libuim_la_OBJECTS = uim.lo uim-func.lo uim-key.lo uim-util.lo \
 	uim-helper.lo uim-helper-client.lo skk-dic.lo anthy.lo prime.lo \
-	canna.lo slib.lo sliba.lo uim-ipc.lo uim-table.lo
+	canna.lo slib.lo sliba.lo uim-ipc.lo uim-table.lo \
+	bsd-getpeereid.lo
 libuim_la_OBJECTS = $(am_libuim_la_OBJECTS)
 bin_PROGRAMS = uim-helper-server$(EXEEXT)
 PROGRAMS = $(bin_PROGRAMS)
@@ -241,10 +243,11 @@
 DEFAULT_INCLUDES =  -I. -I$(srcdir) -I.
 depcomp = $(SHELL) $(top_srcdir)/depcomp
 am__depfiles_maybe = depfiles
- @ AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/anthy.Plo ./$(DEPDIR)/canna.Plo \
- @ AMDEP_TRUE@	./$(DEPDIR)/prime.Plo ./$(DEPDIR)/skk-dic.Plo \
- @ AMDEP_TRUE@	./$(DEPDIR)/slib.Plo ./$(DEPDIR)/sliba.Plo \
- @ AMDEP_TRUE@	./$(DEPDIR)/uim-func.Plo \
+ @ AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/anthy.Plo \
+ @ AMDEP_TRUE@	./$(DEPDIR)/bsd-getpeereid.Plo \
+ @ AMDEP_TRUE@	./$(DEPDIR)/canna.Plo ./$(DEPDIR)/prime.Plo \
+ @ AMDEP_TRUE@	./$(DEPDIR)/skk-dic.Plo ./$(DEPDIR)/slib.Plo \
+ @ AMDEP_TRUE@	./$(DEPDIR)/sliba.Plo ./$(DEPDIR)/uim-func.Plo \
 @AMDEP_TRUE@	./$(DEPDIR)/uim-helper-client.Plo \
 @AMDEP_TRUE@	./$(DEPDIR)/uim-helper.Plo ./$(DEPDIR)/uim-ipc.Plo \
 @AMDEP_TRUE@	./$(DEPDIR)/uim-key.Plo ./$(DEPDIR)/uim-table.Plo \
@@ -362,6 +365,7 @@
 	-rm -f *.tab.c
 
 @AMDEP_TRUE@@am__include@ @am__quote @ ./$(DEPDIR)/anthy.Plo @ am__quote@
+ @ AMDEP_TRUE@@am__include@ @am__quote @ ./$(DEPDIR)/bsd-getpeereid.Plo @ am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote @ ./$(DEPDIR)/canna.Plo @ am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote @ ./$(DEPDIR)/prime.Plo @ am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote @ ./$(DEPDIR)/skk-dic.Plo @ am__quote@
diff -uNr uim-0.3.0.1.orig/uim/bsd-getpeereid.c uim-0.3.0.1/uim/bsd-getpeereid.c
--- uim-0.3.0.1.orig/uim/bsd-getpeereid.c	1970-01-01 09:00:00.000000000 +0900
+++ uim-0.3.0.1/uim/bsd-getpeereid.c	2004-02-27 20:10:25.000000000 +0900
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2002,2004 Damien Miller <djm****@mindr*****>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "config.h"
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#if !defined(HAVE_GETPEEREID)
+
+#if defined(SO_PEERCRED)
+int
+getpeereid(int s, uid_t *euid, gid_t *gid)
+{
+	struct ucred cred;
+	socklen_t len = sizeof(cred);
+
+	if (getsockopt(s, SOL_SOCKET, SO_PEERCRED, &cred, &len) < 0)
+		return (-1);
+	*euid = cred.uid;
+	*gid = cred.gid;
+
+	return (0);
+}
+#else
+int
+getpeereid(int s, uid_t *euid, gid_t *gid)
+{
+	*euid = geteuid();
+	*gid = getgid();
+
+	return (0);
+}
+#endif /* defined(SO_PEERCRED) */
+
+#endif /* !defined(HAVE_GETPEEREID) */
diff -uNr uim-0.3.0.1.orig/uim/config.h.in uim-0.3.0.1/uim/config.h.in
--- uim-0.3.0.1.orig/uim/config.h.in	2004-02-23 06:34:22.000000000 +0900
+++ uim-0.3.0.1/uim/config.h.in	2004-02-27 19:59:51.000000000 +0900
@@ -44,6 +44,9 @@
 /* Define to 1 if you have the `getpagesize' function. */
 #undef HAVE_GETPAGESIZE
 
+/* Define to 1 if you have the `getpeereid' function. */
+#undef HAVE_GETPEEREID
+
 /* Define if the GNU gettext() function is already present or preinstalled. */
 #undef HAVE_GETTEXT
 
diff -uNr uim-0.3.0.1.orig/uim/uim-helper-client.c uim-0.3.0.1/uim/uim-helper-client.c
--- uim-0.3.0.1.orig/uim/uim-helper-client.c	2004-02-23 04:21:34.000000000 +0900
+++ uim-0.3.0.1/uim/uim-helper-client.c	2004-02-27 20:00:13.000000000 +0900
@@ -33,10 +33,12 @@
 
 int uim_helper_init_client_fd(void (*disconnect_cb)(void))
 {
-  struct stat lst, fst;
+  struct stat lst;
   int fd;
   struct sockaddr_un server;
   char *path = uim_helper_get_pathname();
+  uid_t euid;
+  gid_t egid;
   
   uim_fd = -1;
   
@@ -55,15 +57,6 @@
     return -1;
   }
   
-  if (fstat(fd, &fst) != 0) {
-    close(fd);
-    return -1;
-  }  
-  if (fst.st_uid != getuid()) {
-    close(fd);
-    return -1;
-  }
-  
   if(connect(fd, (struct sockaddr *)&server,sizeof(server)) == -1){
     int serv_pid = 0;
     FILE *serv_r = NULL, *serv_w = NULL;
@@ -85,6 +78,17 @@
     }
   }
 
+  if (getpeereid(fd, &euid, &egid) < 0) {
+    perror("getpeereid failed");
+    close(fd);
+    return -1;
+  }
+  if ((euid != 0) && (euid != getuid())) {
+    fprintf(stderr, "uid mismatch\n");
+    close(fd);
+    return -1;
+  }
+ 
   uim_disconnect_cb = disconnect_cb;
   uim_read_buf_count = 0;
   uim_read_buf_error = 0;


Anthy-dev メーリングリストの案内
Back to archive index