/* * rstsmack - Restore smack attributes on files * * Copyright (c) 2000 - 2017 Samsung Electronics Co., Ltd. * * Contact: MyoungJune Park * Created by Wonil Choi * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include #include #include #include #include #include #include #include #include #ifdef DEBUG # define LOGINFO(fmt, arg...) printf(fmt, ##arg) #else # define LOGINFO(fmt, arg...) #endif void print_help(const char *cmd) { printf("Usage: %s \n", cmd); printf(" INPUT FILE should be same format as generated by" " chsmack.\n\n"); printf(" Ex) # chsmack /usr/bin/* > /tmp/rstsmack_input.txt\n"); } static inline int abandonqm(char *label) { int ret = 0; /* ignore last character which must be a quotation mark */ ret = (int) strlen(label); ret--; if (ret > SMACK_LABEL_LEN || ret <= 0) return -1; label[ret] = '\0'; return 0; } static void set_label(const char *pathname, char *label, int type) { int ret = -1; if (abandonqm(label) == 0) { ret = smack_lsetlabel(pathname, label, type); if (ret < 0) perror(pathname); } else fprintf(stderr, "The input file has wrong format, %s\n", pathname); } static int parse_and_set(const char *srcfile) { /* We assume the text format of input file is same as chsmack output */ FILE *fp; int ret = 0; char linebuf[PATH_MAX + 5 * SMACK_LABEL_LEN], pathname[PATH_MAX]; char label[SMACK_LABEL_LEN + 1]; char *plabel; /* pointer of beginning smack label */ fp = fopen(srcfile, "r"); if (fp == NULL) return -1; while (fgets(linebuf, sizeof(linebuf), fp)) { plabel = strstr(linebuf, " access="); if (plabel && linebuf != plabel) { *plabel = '\0'; strncpy(pathname, linebuf, sizeof(pathname)); pathname[sizeof(pathname) - 1] = '\0'; plabel++; } else { linebuf[strlen(linebuf) - 1] = '\0'; LOGINFO("no label, set label: %s, access=\"_\"(floor)\n", linebuf); strncpy(label, "_\"", SMACK_LABEL_LEN); set_label(linebuf, label, SMACK_LABEL_ACCESS); /* TODO: If file name contains " access=" then it would * not be processed */ continue; } LOGINFO("set label: %s,", pathname); ret = sscanf(plabel, "access=\"%s", label); if (ret > 0) { LOGINFO(" access: \"%s", label); set_label(pathname, label, SMACK_LABEL_ACCESS); plabel = plabel + sizeof(" access=\"") + strlen(label); } ret = sscanf(plabel, "execute=\"%s", label); if (ret > 0) { LOGINFO(", exec: \"%s", label); set_label(pathname, label, SMACK_LABEL_EXEC); plabel = plabel + sizeof(" execute=\"") + strlen(label); } ret = sscanf(plabel, "mmap=\"%s", label); if (ret > 0) { LOGINFO(", mmap: \"%s", label); set_label(pathname, label, SMACK_LABEL_MMAP); plabel = plabel + sizeof(" mmap=\"") + strlen(label); } ret = sscanf(plabel, "transmute=\"%s", label); if (ret > 0) { LOGINFO(", transmute: \"%s", label); strncpy(label, "1\"", SMACK_LABEL_LEN); set_label(pathname, label, SMACK_LABEL_TRANSMUTE); } LOGINFO("\n"); } fclose(fp); return 0; } int main(int argc, char *argv[]) { if (argc < 2) { print_help(argv[0]); return -1; } if (parse_and_set(argv[1]) < 0) { print_help(argv[0]); return -1; } return 0; }