commit 48541eef38dca6be3dfaf02207888f57d608a1cb
parent 4992f130500c1d5bae8593427107336154ff0003
Author: ukai <ukai>
Date: Wed, 6 Nov 2002 03:50:48 +0000
[w3m-dev 03379] setuid w3mimgdisplay and check console tty
* XMakefile: w3mimgdisplay install by INSTALL_W3MIMGDISPLAY
* configure: ask setuid w3mimgdisplay
(w3mimgdisplay_setuid): added
(INSTALL_W3MIMGDISPLAY): added
* etc.c (mySystem): close until FOPEN_MAX
* image.c (openImgdisplay): setenv W3M_TTY
stderr to /dev/null
close until FOPEN_MAX
* install-sh: -o, -g for owner, group
* proto.h (ttyname_tty): added
* search.c (open_migemo): stderr to /dev/null
close until FOPEN_MAX
* terms.c (ttyname_tty): added
* w3mimgdisplay.c: include <sys/types.h>, <unistd.h>
W3MIMGDISPLAY_SETUID
stderr to /dev/null
* w3mimg/w3mimg.c: include <sys/types.h>, <unistd.h>
W3MIMGDISPLAY_SETUID
* w3mimg/fb/fb_w3mimg.c (check_tty_console): added
From: Fumitoshi UKAI <ukai@debian.or.jp>
Diffstat:
12 files changed, 140 insertions(+), 7 deletions(-)
diff --git a/ChangeLog b/ChangeLog
@@ -1,3 +1,26 @@
+2002-11-06 Fumitoshi UKAI <ukai@debian.or.jp>
+
+ * [w3m-dev 03379] setuid w3mimgdisplay and check console tty
+ * XMakefile: w3mimgdisplay install by INSTALL_W3MIMGDISPLAY
+ * configure: ask setuid w3mimgdisplay
+ (w3mimgdisplay_setuid): added
+ (INSTALL_W3MIMGDISPLAY): added
+ * etc.c (mySystem): close until FOPEN_MAX
+ * image.c (openImgdisplay): setenv W3M_TTY
+ stderr to /dev/null
+ close until FOPEN_MAX
+ * install-sh: -o, -g for owner, group
+ * proto.h (ttyname_tty): added
+ * search.c (open_migemo): stderr to /dev/null
+ close until FOPEN_MAX
+ * terms.c (ttyname_tty): added
+ * w3mimgdisplay.c: include <sys/types.h>, <unistd.h>
+ W3MIMGDISPLAY_SETUID
+ stderr to /dev/null
+ * w3mimg/w3mimg.c: include <sys/types.h>, <unistd.h>
+ W3MIMGDISPLAY_SETUID
+ * w3mimg/fb/fb_w3mimg.c (check_tty_console): added
+
2002-11-06 Hironori SAKAMOTO <hsaka@mth.biglobe.ne.jp>
* [w3m-dev 03377] sync_with_option
diff --git a/XMakefile b/XMakefile
@@ -131,7 +131,10 @@ install-core: $(TARGETS)
$(INSTALL_DATA) $(MAN1_JA) $(DESTDIR)$(MAN1_JA_DIR)/$(TARGET).1
for file in $(EXT_TARGETS); \
do \
- $(INSTALL_PROGRAM) $$file $(DESTDIR)$(LIB_DIR)/$$file; \
+ case $$file in \
+ $(IMGDISPLAY)) $(INSTALL_W3MIMGDISPLAY) $$file $(DESTDIR)$(LIB_DIR)/$$file;; \
+ *) $(INSTALL_PROGRAM) $$file $(DESTDIR)$(LIB_DIR)/$$file;; \
+ esac; \
done
install-helpfile:
diff --git a/configure b/configure
@@ -806,6 +806,14 @@ if [ "$use_image" = y ]; then
d_w3mimg_fb=y
fi
ask_param "Linux Framebuffer inline image support (you need Imlib2 or GdkPixbuf)" use_w3mimg_fb $d_w3mimg_fb
+ if [ "$use_w3mimg_fb" = y ]; then
+ ask_param "setuid w3mimgdisplay to open /dev/fb0?" w3mimgdisplay_setuid y
+ if [ "$w3mimgdisplay_setuid" = y ]; then
+ INSTALL_W3MIMGDISPLAY='$(INSTALL) -o root -m 4755 -s'
+ else
+ INSTALL_W3MIMGDISPLAY='$(INSTALL_PROGRAM)'
+ fi
+ fi
;;
esac
else
@@ -2319,6 +2327,7 @@ MKDIR=$MKDIR
PERL=$perl
VERSION=$w3mversion
MODEL=$sysname.$platform-$modelname-$lang
+INSTALL_W3MIMGDISPLAY=$INSTALL_W3MIMGDISPLAY
#else
$special_sys
@@ -2354,6 +2363,7 @@ $def_use_alarm
$def_use_image
$def_use_w3mimg_x11
$def_use_w3mimg_fb
+$def_w3mimgdisplay_setuid
$def_use_imlib
$def_use_gdkpixbuf
$def_use_imlib2
diff --git a/etc.c b/etc.c
@@ -1307,15 +1307,18 @@ mySystem(char *command, int background)
int pid;
flush_tty();
if ((pid = fork()) == 0) {
- int fd, i;
+ int i;
reset_signals();
SETPGRP();
close_tty();
dup2(open("/dev/null", O_RDONLY), 0);
dup2(open("/dev/null", O_WRONLY), 1);
- dup2(fd = open("/dev/null", O_WRONLY), 2);
+ dup2(open("/dev/null", O_WRONLY), 2);
+#ifndef FOPEN_MAX
+#define FOPEN_MAX 1024 /* XXX */
+#endif
/* close all other file descriptors (socket, ...) */
- for (i = 3; i <= fd; i++)
+ for (i = 3; i < FOPEN_MAX; i++)
close(i);
execl("/bin/sh", "sh", "-c", command, NULL);
exit(127);
diff --git a/image.c b/image.c
@@ -107,8 +107,10 @@ openImgdisplay()
goto err2;
if (Imgdisplay_pid == 0) {
/* child */
+ int i;
reset_signals();
signal(SIGINT, SIG_IGN);
+ set_environ("W3M_TTY", ttyname_tty());
#ifdef HAVE_SETPGRP
SETPGRP();
#endif
@@ -117,7 +119,13 @@ openImgdisplay()
close(fdw[1]);
dup2(fdw[0], 0);
dup2(fdr[1], 1);
- close(2);
+ dup2(open("/dev/null", O_WRONLY), 2);
+#ifndef FOPEN_MAX
+#define FOPEN_MAX 1024 /* XXX */
+#endif
+ /* close all other file descriptors (socket, ...) */
+ for (i = 3; i < FOPEN_MAX; i++)
+ close(i);
if (!strchr(Imgdisplay, '/'))
cmd = Strnew_m_charp(w3m_lib_dir(), "/", Imgdisplay, NULL)->ptr;
else
diff --git a/install-sh b/install-sh
@@ -18,6 +18,12 @@ do
fi
shift;
;;
+ -o) owner=$2
+ shift; shift
+ ;;
+ -g) group=$2
+ shift; shift
+ ;;
-*)
shift
;;
@@ -45,6 +51,12 @@ cp $file $dest
if [ -n "$strip" ]; then
$strip $dest
fi
+if [ -n "$owner" ]; then
+ chown $owner $dest
+fi
+if [ -n '$group" ]; then
+ chgrp $group $dest
+fi
if [ -n "$mode" ]; then
chmod $mode $dest
fi
diff --git a/proto.h b/proto.h
@@ -381,6 +381,7 @@ extern union frameset_element *search_frame(struct frameset *fset, char *name);
extern int set_tty(void);
extern void set_cc(int spec, int val);
extern void close_tty(void);
+extern char *ttyname_tty(void);
extern void reset_tty(void);
extern MySignalHandler reset_exit(SIGNAL_ARG);
extern MySignalHandler error_dump(SIGNAL_ARG);
diff --git a/search.c b/search.c
@@ -50,6 +50,7 @@ open_migemo(char *migemo_command)
goto err2;
if (migemo_pid == 0) {
/* child */
+ int i;
reset_signals();
#ifdef HAVE_SETPGRP
SETPGRP();
@@ -59,7 +60,13 @@ open_migemo(char *migemo_command)
close(fdw[1]);
dup2(fdw[0], 0);
dup2(fdr[1], 1);
- close(2);
+ dup2(open("/dev/null", O_WRONLY), 2);
+#ifndef FOPEN_MAX
+#define FOPEN_MAX 1024 /* XXX */
+#endif
+ /* close all other file descriptors (socket, ...) */
+ for (i = 3; i < FOPEN_MAX; i++)
+ close(i);
execl("/bin/sh", "sh", "-c", migemo_command, NULL);
exit(1);
}
diff --git a/terms.c b/terms.c
@@ -610,6 +610,12 @@ close_tty(void)
close(tty);
}
+char *
+ttyname_tty(void)
+{
+ return ttyname(tty);
+}
+
void
reset_tty(void)
{
diff --git a/w3mimg/fb/fb_w3mimg.c b/w3mimg/fb/fb_w3mimg.c
@@ -3,6 +3,10 @@
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
#include "w3mimg/fb/fb.h"
#include "w3mimg/fb/fb_img.h"
@@ -128,6 +132,24 @@ w3mfb_get_image_size(w3mimg_op * self, W3MImage * img,
return 1;
}
+#ifdef W3MIMGDISPLAY_SETUID
+static int
+check_tty_console(char *tty)
+{
+ if (tty == NULL || *tty == '\0')
+ return 0;
+ if (strncmp(tty, "/dev/", 5) == 0)
+ tty += 5;
+ if (strncmp(tty, "tty", 3) == 0 && isdigit(*(tty+3)))
+ return 1;
+ if (strncmp(tty, "vc/", 3) == 0 && isdigit(*(tty+3)))
+ return 1;
+ return 0;
+}
+#else
+#define check_tty_console(tty) 1
+#endif
+
w3mimg_op *
w3mimg_fbopen()
{
@@ -137,6 +159,11 @@ w3mimg_fbopen()
return NULL;
memset(wop, 0, sizeof(w3mimg_op));
+ if (! check_tty_console(getenv("W3M_TTY"))) {
+ fprintf(stderr, "w3mimgdisplay/fb: tty is not console\n");
+ goto error;
+ }
+
if (fb_open())
goto error;
diff --git a/w3mimg/w3mimg.c b/w3mimg/w3mimg.c
@@ -2,17 +2,31 @@
#include <stdio.h>
#include <stdlib.h>
+#include <sys/types.h>
+#include <unistd.h>
#include "w3mimg/w3mimg.h"
w3mimg_op *
w3mimg_open()
{
w3mimg_op *w_op = NULL;
+#ifdef W3MIMGDISPLAY_SETUID
+ uid_t runner_uid = getuid();
+ uid_t owner_uid = geteuid();
+#endif
#ifdef USE_W3MIMG_X11
+#ifdef W3MIMGDISPLAY_SETUID
+ /* run in user privileges */
+ setreuid(owner_uid, runner_uid);
+#endif
if (w_op == NULL)
w_op = w3mimg_x11open();
+#ifdef W3MIMGDISPLAY_SETUID
+ setreuid(runner_uid, owner_uid);
+#endif
#endif
#ifdef USE_W3MIMG_FB
+ /* run in setuid privileges */
if (w_op == NULL)
w_op = w3mimg_fbopen();
#endif
diff --git a/w3mimgdisplay.c b/w3mimgdisplay.c
@@ -3,6 +3,8 @@
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
#include "config.h"
#include "w3mimg/w3mimg.h"
@@ -25,12 +27,29 @@ main(int argc, char **argv)
{
int len;
char buf[1024 + 128];
+#ifdef W3MIMGDISPLAY_SETUID
+ uid_t runner_uid = getuid();
+ uid_t owner_uid = geteuid();
+ /* swap real and effective */
+ setreuid(owner_uid, runner_uid);
+#endif
GetOption(argc, argv);
if (!defined_debug)
- fclose(stderr);
+ freopen("/dev/null", "w", stderr);
+#ifdef W3MIMGDISPLAY_SETUID
+ /*
+ * back real and effective
+ * run w3mimg_open() in setuid privileges
+ */
+ setreuid(runner_uid, owner_uid);
+#endif
w_op = w3mimg_open();
+#ifdef W3MIMGDISPLAY_SETUID
+ /* make sure drop privileges now */
+ setreuid(runner_uid, runner_uid);
+#endif
if (w_op == NULL)
exit(1);
if (defined_x)