aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLAN-TW <lantw44@sonytest.tfcis.org>2012-11-12 12:22:12 +0800
committerLAN-TW <lantw44@sonytest.tfcis.org>2012-11-12 12:22:12 +0800
commitd7f706956e0c4914879d2d08c24227ba0bb6ef0f (patch)
tree4ca7a46f180ebbf13d26aa32f643d3867b45bbb1
parentcfa4b4203be3761bf37ec8cf7d394028ebd24e82 (diff)
downloadsctjudge-d7f706956e0c4914879d2d08c24227ba0bb6ef0f.tar.gz
sctjudge-d7f706956e0c4914879d2d08c24227ba0bb6ef0f.tar.zst
sctjudge-d7f706956e0c4914879d2d08c24227ba0bb6ef0f.zip
修正在 #undef _POSIX_SAVED_IDS 的環境下發生的問題
原先使用 getuid() 判斷 UID 會導致在 disable_setuid() 後 real UID 有誤,導致只 有 root 可以強制執行這支程式。
-rw-r--r--src/common.c4
-rw-r--r--src/common.h6
-rw-r--r--src/main.c18
-rw-r--r--src/mkchild.c4
4 files changed, 19 insertions, 13 deletions
diff --git a/src/common.c b/src/common.c
index 3bc7cdb..241d2fd 100644
--- a/src/common.c
+++ b/src/common.c
@@ -9,8 +9,8 @@
#include <sys/types.h>
#ifndef HAVE_CONF_CAP
-static uid_t procrealuid = 0;
-static uid_t proceffuid = 0;
+uid_t procrealuid = 0;
+uid_t proceffuid = 0;
#endif
void checktimespec(struct timespec* arg){
diff --git a/src/common.h b/src/common.h
index a5317ba..ca1f5f2 100644
--- a/src/common.h
+++ b/src/common.h
@@ -17,5 +17,11 @@ void disable_setuid(void);
void enable_setuid(void);
#endif
+#ifndef _POSIX_SAVED_IDS
+/* 避免 disable_setuid() 之後 getuid() 得到錯誤的值,所以用這個變數來取代 */
+extern uid_t procrealuid;
+extern uid_t proceffuid;
+#endif
+
#endif
diff --git a/src/main.c b/src/main.c
index 3c9212b..b873ae7 100644
--- a/src/main.c
+++ b/src/main.c
@@ -83,6 +83,13 @@ int main(int argc, char* argv[]){
struct group* grinfo;
#endif
+#ifndef HAVE_CONF_CAP
+ /* 即使有 setuid root,還是不能讓每個使用者拿到 root 權限
+ * 所以說只有在 fork 的時候才要把這個權限開起來,其他就關掉吧 */
+ save_uids();
+ disable_setuid();
+#endif
+
/* 預設值當然都是 0 */
memset(&mcopt, 0 ,sizeof(mcopt));
/* 據說有些 NULL 不是 0,所以還是設定一下比較保險 */
@@ -349,13 +356,6 @@ int main(int argc, char* argv[]){
puts(SCTJUDGE_TITLEBAR"\n");
}
-#ifndef HAVE_CONF_CAP
- /* 即使有 setuid root,還是不能讓每個使用者拿到 root 權限
- * 所以說只有在 fork 的時候才要把這個權限開起來,其他就關掉吧 */
- save_uids();
- disable_setuid();
-#endif
-
/* 檢查與修正設定值 */
if(verbose){
puts("正在檢查設定值是否正確......");
@@ -382,14 +382,14 @@ int main(int argc, char* argv[]){
stderr);
exit(SCTEXIT_BADID);
}else{
- if(getuid() != 0){
+ if(procrealuid != 0){
fputs("只有 root 可以將 UID 設定 0\n", stderr);
exit(SCTEXIT_BADID);
}
}
}
}else{
- if(getuid() == 0 && !force){
+ if(procrealuid == 0 && !force){
fputs("不允許以 root 身份執行本程式(加上 -f 來強制執行)\n",
stderr);
exit(SCTEXIT_BADID);
diff --git a/src/mkchild.c b/src/mkchild.c
index 2876a92..3325632 100644
--- a/src/mkchild.c
+++ b/src/mkchild.c
@@ -539,7 +539,7 @@ void* sctjudge_makechild(void* arg){
#ifndef HAVE_CONF_CAP
enable_setuid();
#endif
- fchown(fdoutput, getuid(), -1);
+ fchown(fdoutput, procrealuid, -1);
/* 再來就是 stderr 了 */
if(mcopt.flags & SCTMC_REDIR_STDERR){
@@ -619,7 +619,7 @@ void* sctjudge_makechild(void* arg){
#ifndef HAVE_CONF_CAP
else{
/* 確保 setuid 可執行檔所造成的 effective UID 改變不會傳給子程序 */
- setuid(getuid());
+ setuid(procrealuid);
}
#endif