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;