aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLAN-TW <lantw44@gmail.com>2012-09-20 08:58:08 +0800
committerLAN-TW <lantw44@gmail.com>2012-09-20 08:58:08 +0800
commit2c3b537131707a966abdb1a79ba203f14cbade4b (patch)
treefa38b2d05ed1e4760237ac9ad5e92fc25ebc0c4b
parentfae3bd51ccf149bca7beaa81bc63727cf5a46562 (diff)
downloadsctjudge-2c3b537131707a966abdb1a79ba203f14cbade4b.tar.gz
sctjudge-2c3b537131707a966abdb1a79ba203f14cbade4b.tar.zst
sctjudge-2c3b537131707a966abdb1a79ba203f14cbade4b.zip
修改檢查 UID/GID 是否合理的部分
-rw-r--r--src/config2.h14
-rw-r--r--src/core.h3
-rw-r--r--src/main.c55
-rw-r--r--src/mkchild.c4
4 files changed, 44 insertions, 32 deletions
diff --git a/src/config2.h b/src/config2.h
index ba798eb..822ebdb 100644
--- a/src/config2.h
+++ b/src/config2.h
@@ -5,9 +5,13 @@
#define SCT_CHECKTLE_INTERVAL 128000000
#define SCT_DISPTIME_INTERVAL 384000000
+/* XXX 這個看能不能用 GNU autotool 取代,我可不確定 /dev/null 永遠存在!*/
+#define NULL_DEVICE "/dev/null"
+
/* sctjudge 這個程式的 exit status */
-#define SCTJUDGE_EXIT_SUCCESS 0 /* 當然就是正常結束 */
-#define SCTJUDGE_EXIT_SYNTAX 1 /* 命令列語法錯誤 */
-#define SCTJUDGE_EXIT_TOOFEW 2 /* 少了一些必須的選項 */
-#define SCTJUDGE_EXIT_MALLOC 3 /* 配置記憶體發生錯誤 */
-#define SCTJUDGE_EXIT_THREAD 4 /* pthread_create 以後才發生錯誤 */
+#define SCTEXIT_SUCCESS 0 /* 當然就是正常結束 */
+#define SCTEXIT_SYNTAX 1 /* 解析階段:命令列語法錯誤 */
+#define SCTEXIT_TOOFEW 2 /* 檢查階段:少了一些必須的選項 */
+#define SCTEXIT_BADID 3 /* 檢查階段:錯誤或不允許的 uid/gid */
+#define SCTEXIT_THREAD 4 /* 實作階段:thread 回傳錯誤 */
+#define SCTEXIT_MALLOC 5 /* 配置記憶體發生錯誤,這個可能發生在程式任何地方 */
diff --git a/src/core.h b/src/core.h
index 0778597..75d8bc2 100644
--- a/src/core.h
+++ b/src/core.h
@@ -9,9 +9,6 @@
#include <pthread.h>
#include <semaphore.h>
-#define NULL_DEVICE "/dev/null"
-
-
/* mkchild.c */
/* 子程序 PID 和對應的 mutex */
diff --git a/src/main.c b/src/main.c
index e8782ed..da40b8f 100644
--- a/src/main.c
+++ b/src/main.c
@@ -30,7 +30,7 @@
i++; \
if(i >= argc){ \
fprintf(stderr, SCTMAIN_ERRNOARG, argv[0], argv[i-1]); \
- exit(SCTJUDGE_EXIT_TOOFEW); \
+ exit(SCTEXIT_SYNTAX); \
} \
}while(0)
@@ -39,7 +39,7 @@
if(!l4qarg_hasvalue(qarglist[j])){ \
fprintf(stderr, SCTMAIN_ERRNOQARG, \
argv[0], qarglist[j].arg_name); \
- exit(SCTJUDGE_EXIT_TOOFEW); \
+ exit(SCTEXIT_SYNTAX); \
} \
}while(0)
@@ -48,7 +48,7 @@
if(l4qarg_hasvalue(qarglist[j])){ \
fprintf(stderr, SCTMAIN_ERREXTRAQARG, \
argv[0], qarglist[j].arg_name); \
- exit(SCTJUDGE_EXIT_SYNTAX); \
+ exit(SCTEXIT_SYNTAX); \
} \
}while(0)
@@ -143,12 +143,12 @@ int main(int argc, char* argv[]){
" 原有的 supplementry GIDs 會被清空,只剩下這裡指"
"定的數值\n\n"
, argv[0]);
- return SCTJUDGE_EXIT_SUCCESS;
+ return SCTEXIT_SUCCESS;
}else if(!strcmp(&argv[i][1], "V") ||
!strcmp(&argv[i][1], "version") ||
!strcmp(&argv[i][1], "-version")){
puts(SCTJUDGE_TITLEBAR);
- exit(SCTJUDGE_EXIT_SUCCESS);
+ exit(SCTEXIT_SUCCESS);
}else if(!strcmp(&argv[i][1], "v") ||
!strcmp(&argv[i][1], "verbose")){
verbose++;
@@ -171,7 +171,7 @@ int main(int argc, char* argv[]){
if(mcopt.exectime <= 0){
fprintf(stderr, "%s: 「%s」不是正確的時間設定值\n",
argv[0], argv[i]);
- exit(SCTJUDGE_EXIT_SYNTAX);
+ exit(SCTEXIT_SYNTAX);
}
}else if(!strcmp(&argv[i][1], "e") ||
!strcmp(&argv[i][1], "exec")){
@@ -200,7 +200,7 @@ int main(int argc, char* argv[]){
qarglist = l4qarg_parse(argv[i]);
if(qarglist == NULL){
fprintf(stderr, "%s: 記憶體配置發生錯誤\n", argv[0]);
- exit(SCTJUDGE_EXIT_MALLOC);
+ exit(SCTEXIT_MALLOC);
}
for(j=0; !l4qarg_end(qarglist[j]); j++){
if(!strcmp(qarglist[j].arg_name, "mem") ||
@@ -211,7 +211,7 @@ int main(int argc, char* argv[]){
fprintf(stderr, "%s: 「%s」不是正確的記憶體限制"
"設定值\n", argv[0],
qarglist[j].arg_value);
- exit(SCTJUDGE_EXIT_SYNTAX);
+ exit(SCTEXIT_SYNTAX);
}
}else if(!strcmp(qarglist[j].arg_name, "outlimit") ||
!strcmp(qarglist[j].arg_name, "outlim")){
@@ -220,7 +220,7 @@ int main(int argc, char* argv[]){
if(mcopt.outlimit <= 0){
fprintf(stderr, "%s: 「%s」不是正確的輸出限制"
"設定\n", argv[0], qarglist[j].arg_value);
- exit(SCTJUDGE_EXIT_SYNTAX);
+ exit(SCTEXIT_SYNTAX);
}
}else if(!strcmp(qarglist[j].arg_name, "stderr")){
SCTMAIN_CHECKQARGNOVALUE;
@@ -232,38 +232,38 @@ int main(int argc, char* argv[]){
!strcmp(qarglist[j].arg_name, "user")){
SCTMAIN_CHECKQARGHAVEVALUE;
mcopt.flags |= SCTMC_SETUID;
- if(sscanf(qarglist[j].arg_value, "%d", &mcopt.uid)
+ if(sscanf(qarglist[j].arg_value, "%u", &mcopt.uid)
<= 0){
fprintf(stderr, "%s: 「%s」並不是整數\n",
argv[0], qarglist[j].arg_value);
- exit(SCTJUDGE_EXIT_SYNTAX);
+ exit(SCTEXIT_SYNTAX);
}
}else if(!strcmp(qarglist[j].arg_name, "gid") ||
!strcmp(qarglist[j].arg_name, "group")){
SCTMAIN_CHECKQARGHAVEVALUE;
mcopt.flags |= SCTMC_SETGID;
- if(sscanf(qarglist[j].arg_value, "%d", &mcopt.gid)
+ if(sscanf(qarglist[j].arg_value, "%u", &mcopt.gid)
<= 0){
fprintf(stderr, "%s: 「%s」並不是整數\n",
argv[0], qarglist[j].arg_value);
- exit(SCTJUDGE_EXIT_SYNTAX);
+ exit(SCTEXIT_SYNTAX);
}
}else{
fprintf(stderr, "%s: 「%s」是不明的選項\n", argv[0],
qarglist[j].arg_name);
- exit(SCTJUDGE_EXIT_SYNTAX);
+ exit(SCTEXIT_SYNTAX);
}
}
l4qarg_free(qarglist);
}else{
fprintf(stderr, "%s: 不明的選項「%s」\n", argv[0], argv[i]);
- return SCTJUDGE_EXIT_SYNTAX;
+ return SCTEXIT_SYNTAX;
}
}else{
fprintf(stderr, "%s: 參數 %d「%s」是多餘的\n"
"請嘗試執行 %s -help 來取得說明\n"
, argv[0], i, argv[i], argv[0]);
- return SCTJUDGE_EXIT_SYNTAX;
+ return SCTEXIT_SYNTAX;
}
}
/* 至此可以進入主程式了 */
@@ -284,18 +284,29 @@ int main(int argc, char* argv[]){
}
if(mcopt.executable == NULL){
fputs("受測程式可執行檔名稱為必要參數,不可為空白\n", stderr);
- exit(SCTJUDGE_EXIT_TOOFEW);
+ exit(SCTEXIT_TOOFEW);
}
if(mcopt.inputfile == NULL){
mcopt.inputfile = NULL_DEVICE;
}
if(mcopt.outputfile == NULL){
fputs("輸出檔案名稱必要參數,不可為空白\n", stderr);
- exit(SCTJUDGE_EXIT_TOOFEW);
+ exit(SCTEXIT_TOOFEW);
}
if(mcopt.exectime <= 0){
fputs("執行時間限制為必要參數,不可為空白!\n", stderr);
- exit(SCTJUDGE_EXIT_TOOFEW);
+ exit(SCTEXIT_TOOFEW);
+ }
+ if((mcopt.flags & SCTMC_SETUID) && (mcopt.uid == 0)){
+ if(!force){
+ fputs("將 UID 設為 0 並不安全!(加上 -f 來強制執行)\n", stderr);
+ exit(SCTEXIT_BADID);
+ }else{
+ if(getuid() != 0){
+ fputs("只有 root 可以將 UID 設定 0\n", stderr);
+ exit(SCTEXIT_BADID);
+ }
+ }
}
/* 現在開始建立 thread 了!*/
@@ -342,7 +353,7 @@ int main(int argc, char* argv[]){
pthread_mutex_destroy(&tdisplay_mx);
if(dryrun){
- return SCTJUDGE_EXIT_SUCCESS;
+ return SCTEXIT_SUCCESS;
}
/* 這裡就要顯示結果了 */
@@ -350,7 +361,7 @@ int main(int argc, char* argv[]){
fprintf(stderr, "%s: 因錯誤發生而結束程式\n", argv[0]);
free((void*)mtreturn);
sem_destroy(&mcthr);
- exit(SCTJUDGE_EXIT_THREAD);
+ exit(SCTEXIT_THREAD);
}else{
if(verbose){
putchar('\r');
@@ -397,5 +408,5 @@ int main(int argc, char* argv[]){
}
free((void*)mtreturn);
}
- return SCTJUDGE_EXIT_SUCCESS;
+ return SCTEXIT_SUCCESS;
}
diff --git a/src/mkchild.c b/src/mkchild.c
index 772dbbe..4404793 100644
--- a/src/mkchild.c
+++ b/src/mkchild.c
@@ -238,12 +238,12 @@ static void sctjudge_list_settings(const struct makechildopt* mcopt){
puts("無限制");
}
if(mcopt->flags & SCTMC_SETUID){
- printf("\t設定受測程式執行時的 UID 為 %d\n", mcopt->uid);
+ printf("\t設定受測程式執行時的 UID 為 %u\n", mcopt->uid);
}else{
puts("\t執行受測程式時維持原有的 real UID 和 effective UID");
}
if(mcopt->flags & SCTMC_SETGID){
- printf("\t設定受測程式執行時的 GID 為 %d\n", mcopt->gid);
+ printf("\t設定受測程式執行時的 GID 為 %u\n", mcopt->gid);
}else{
puts("\t執行受測程式時維持原有的 real GID、effective GID "
"和 supplementary GID");