mirror of
https://gitlab.com/sortix/sortix.git
synced 2023-02-13 20:55:38 -05:00
Add scram(2).
This commit is contained in:
parent
f2eb347e9f
commit
4b6b06bbc8
9 changed files with 229 additions and 29 deletions
|
@ -134,6 +134,7 @@ ssize_t sys_readv(int, const struct iovec*, int);
|
||||||
ssize_t sys_recv(int, void*, size_t, int);
|
ssize_t sys_recv(int, void*, size_t, int);
|
||||||
ssize_t sys_recvmsg(int, struct msghdr*, int);
|
ssize_t sys_recvmsg(int, struct msghdr*, int);
|
||||||
int sys_renameat(int, const char*, int, const char*);
|
int sys_renameat(int, const char*, int, const char*);
|
||||||
|
void sys_scram(int, const void*);
|
||||||
int sys_sched_yield(void);
|
int sys_sched_yield(void);
|
||||||
ssize_t sys_send(int, const void*, size_t, int);
|
ssize_t sys_send(int, const void*, size_t, int);
|
||||||
ssize_t sys_sendmsg(int, const struct msghdr*, int);
|
ssize_t sys_sendmsg(int, const struct msghdr*, int);
|
||||||
|
|
|
@ -180,6 +180,14 @@
|
||||||
#define SYSCALL_CLOSEFROM 152
|
#define SYSCALL_CLOSEFROM 152
|
||||||
#define SYSCALL_RESERVED1 153
|
#define SYSCALL_RESERVED1 153
|
||||||
#define SYSCALL_PSCTL 154
|
#define SYSCALL_PSCTL 154
|
||||||
#define SYSCALL_MAX_NUM 155 /* index of highest constant + 1 */
|
#define SYSCALL_RESERVED2 155
|
||||||
|
#define SYSCALL_RESERVED3 156
|
||||||
|
#define SYSCALL_RESERVED4 157
|
||||||
|
#define SYSCALL_RESERVED5 158
|
||||||
|
#define SYSCALL_RESERVED6 159
|
||||||
|
#define SYSCALL_RESERVED7 160
|
||||||
|
#define SYSCALL_RESERVED8 161
|
||||||
|
#define SYSCALL_SCRAM 162
|
||||||
|
#define SYSCALL_MAX_NUM 163 /* index of highest constant + 1 */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <msr.h>
|
#include <msr.h>
|
||||||
|
#include <scram.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -1643,4 +1644,93 @@ mode_t sys_getumask(void)
|
||||||
return process->umask;
|
return process->umask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void GetAssertInfo(struct scram_assert* info,
|
||||||
|
const void* user_info_ptr)
|
||||||
|
{
|
||||||
|
memset(info, 0, sizeof(*info));
|
||||||
|
struct scram_assert user_info;
|
||||||
|
if ( !CopyFromUser(&user_info, user_info_ptr, sizeof(user_info)) )
|
||||||
|
return;
|
||||||
|
info->filename = GetStringFromUser(user_info.filename);
|
||||||
|
info->line = user_info.line;
|
||||||
|
info->function = GetStringFromUser(user_info.function);
|
||||||
|
info->expression = GetStringFromUser(user_info.expression);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void FreeAssertInfo(struct scram_assert* info)
|
||||||
|
{
|
||||||
|
delete[] (char*) info->filename;
|
||||||
|
delete[] (char*) info->function;
|
||||||
|
delete[] (char*) info->expression;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
void GetUndefinedBehaviorInfo(struct scram_undefined_behavior* info,
|
||||||
|
const void* user_info_ptr)
|
||||||
|
{
|
||||||
|
memset(info, 0, sizeof(*info));
|
||||||
|
struct scram_undefined_behavior user_info;
|
||||||
|
if ( !CopyFromUser(&user_info, user_info_ptr, sizeof(user_info)) )
|
||||||
|
return;
|
||||||
|
info->filename = GetStringFromUser(user_info.filename);
|
||||||
|
info->line = user_info.line;
|
||||||
|
info->column = user_info.column;
|
||||||
|
info->violation = GetStringFromUser(user_info.violation);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void FreeUndefinedBehaviorInfo(struct scram_undefined_behavior* info)
|
||||||
|
{
|
||||||
|
delete[] info->filename;
|
||||||
|
delete[] info->violation;
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((noreturn))
|
||||||
|
void sys_scram(int event, const void* user_info)
|
||||||
|
{
|
||||||
|
Process* process = CurrentProcess();
|
||||||
|
// TODO: Prohibit execve such that program_image_path is protected.
|
||||||
|
process->ExitThroughSignal(SIGABRT);
|
||||||
|
if ( event == SCRAM_ASSERT )
|
||||||
|
{
|
||||||
|
struct scram_assert info;
|
||||||
|
GetAssertInfo(&info, user_info);
|
||||||
|
Log::PrintF("%s[%ji]: Assertion failure: %s:%lu: %s: %s\n",
|
||||||
|
process->program_image_path,
|
||||||
|
(intmax_t) process->pid,
|
||||||
|
info.filename ? info.filename : "<unknown>",
|
||||||
|
info.line,
|
||||||
|
info.function ? info.function : "<unknown>",
|
||||||
|
info.expression ? info.expression : "<unknown>");
|
||||||
|
FreeAssertInfo(&info);
|
||||||
|
}
|
||||||
|
else if ( event == SCRAM_STACK_SMASH )
|
||||||
|
{
|
||||||
|
Log::PrintF("%s[%ji]: Stack smashing detected\n",
|
||||||
|
process->program_image_path,
|
||||||
|
(intmax_t) process->pid);
|
||||||
|
}
|
||||||
|
else if ( event == SCRAM_UNDEFINED_BEHAVIOR )
|
||||||
|
{
|
||||||
|
struct scram_undefined_behavior info;
|
||||||
|
GetUndefinedBehaviorInfo(&info, user_info);
|
||||||
|
Log::PrintF("%s[%ji]: Undefined behavior: %s at %s:%lu:%lu\n",
|
||||||
|
process->program_image_path,
|
||||||
|
(intmax_t) process->pid,
|
||||||
|
info.violation ? info.violation : "<unknown>",
|
||||||
|
info.filename ? info.filename : "<unknown>",
|
||||||
|
info.line,
|
||||||
|
info.column);
|
||||||
|
FreeUndefinedBehaviorInfo(&info);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log::PrintF("%s[%ji]: Unknown scram event %i\n",
|
||||||
|
process->program_image_path,
|
||||||
|
(intmax_t) process->pid,
|
||||||
|
event);
|
||||||
|
}
|
||||||
|
// TODO: Allow debugging this event.
|
||||||
|
kthread_exit();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Sortix
|
} // namespace Sortix
|
||||||
|
|
|
@ -190,6 +190,14 @@ void* syscall_list[SYSCALL_MAX_NUM + 1] =
|
||||||
[SYSCALL_CLOSEFROM] = (void*) sys_closefrom,
|
[SYSCALL_CLOSEFROM] = (void*) sys_closefrom,
|
||||||
[SYSCALL_RESERVED1] = (void*) sys_bad_syscall,
|
[SYSCALL_RESERVED1] = (void*) sys_bad_syscall,
|
||||||
[SYSCALL_PSCTL] = (void*) sys_psctl,
|
[SYSCALL_PSCTL] = (void*) sys_psctl,
|
||||||
|
[SYSCALL_RESERVED2] = (void*) sys_bad_syscall,
|
||||||
|
[SYSCALL_RESERVED3] = (void*) sys_bad_syscall,
|
||||||
|
[SYSCALL_RESERVED4] = (void*) sys_bad_syscall,
|
||||||
|
[SYSCALL_RESERVED5] = (void*) sys_bad_syscall,
|
||||||
|
[SYSCALL_RESERVED6] = (void*) sys_bad_syscall,
|
||||||
|
[SYSCALL_RESERVED7] = (void*) sys_bad_syscall,
|
||||||
|
[SYSCALL_RESERVED8] = (void*) sys_bad_syscall,
|
||||||
|
[SYSCALL_SCRAM] = (void*) sys_scram,
|
||||||
[SYSCALL_MAX_NUM] = (void*) sys_bad_syscall,
|
[SYSCALL_MAX_NUM] = (void*) sys_bad_syscall,
|
||||||
};
|
};
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
|
|
|
@ -401,6 +401,7 @@ pwd/getpwuid_r.o \
|
||||||
pwd/openpw.o \
|
pwd/openpw.o \
|
||||||
pwd/setpwent.o \
|
pwd/setpwent.o \
|
||||||
sched/sched_yield.o \
|
sched/sched_yield.o \
|
||||||
|
scram/scram.o \
|
||||||
signal/kill.o \
|
signal/kill.o \
|
||||||
signal/killpg.o \
|
signal/killpg.o \
|
||||||
signal/psiginfo.o \
|
signal/psiginfo.o \
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
Copyright(C) Jonas 'Sortie' Termansen 2012, 2013.
|
Copyright(C) Jonas 'Sortie' Termansen 2012, 2013, 2015.
|
||||||
|
|
||||||
This file is part of the Sortix C Library.
|
This file is part of the Sortix C Library.
|
||||||
|
|
||||||
|
@ -23,12 +23,9 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdint.h>
|
#include <scram.h>
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#if defined(__is_sortix_kernel)
|
#if defined(__is_sortix_kernel)
|
||||||
#include <sortix/kernel/decl.h>
|
|
||||||
#include <sortix/kernel/panic.h>
|
#include <sortix/kernel/panic.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -42,8 +39,11 @@ void __assert(const char* filename,
|
||||||
Sortix::PanicF("Assertion failure: %s:%lu: %s: %s", filename, line,
|
Sortix::PanicF("Assertion failure: %s:%lu: %s: %s", filename, line,
|
||||||
function_name, expression);
|
function_name, expression);
|
||||||
#else
|
#else
|
||||||
fprintf(stderr, "Assertion failure: %s:%lu: %s: %s\n", filename, line,
|
struct scram_assert info;
|
||||||
function_name, expression);
|
info.filename = filename;
|
||||||
abort();
|
info.line = line;
|
||||||
|
info.function = function_name;
|
||||||
|
info.expression = expression;
|
||||||
|
scram(SCRAM_ASSERT, &info);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
61
libc/include/scram.h
Normal file
61
libc/include/scram.h
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
|
||||||
|
Copyright(C) Jonas 'Sortie' Termansen 2015.
|
||||||
|
|
||||||
|
This file is part of the Sortix C Library.
|
||||||
|
|
||||||
|
The Sortix C Library is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
option) any later version.
|
||||||
|
|
||||||
|
The Sortix C Library is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||||
|
License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public License
|
||||||
|
along with the Sortix C Library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
scram.h
|
||||||
|
Emergency process shutdown.
|
||||||
|
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
#ifndef _SCRAM_H
|
||||||
|
#define _SCRAM_H
|
||||||
|
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
|
||||||
|
#define SCRAM_ASSERT 1
|
||||||
|
#define SCRAM_STACK_SMASH 2
|
||||||
|
#define SCRAM_UNDEFINED_BEHAVIOR 3
|
||||||
|
|
||||||
|
struct scram_assert
|
||||||
|
{
|
||||||
|
const char* filename;
|
||||||
|
unsigned long line;
|
||||||
|
const char* function;
|
||||||
|
const char* expression;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct scram_undefined_behavior
|
||||||
|
{
|
||||||
|
const char* filename;
|
||||||
|
unsigned long line;
|
||||||
|
unsigned long column;
|
||||||
|
const char* violation;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
__attribute__((noreturn))
|
||||||
|
void scram(int, const void*);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /* extern "C" */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
35
libc/scram/scram.cpp
Normal file
35
libc/scram/scram.cpp
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
|
||||||
|
Copyright(C) Jonas 'Sortie' Termansen 2015.
|
||||||
|
|
||||||
|
This file is part of the Sortix C Library.
|
||||||
|
|
||||||
|
The Sortix C Library is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
option) any later version.
|
||||||
|
|
||||||
|
The Sortix C Library is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||||
|
License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public License
|
||||||
|
along with the Sortix C Library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
scram/scram.cpp
|
||||||
|
Emergency process shutdown.
|
||||||
|
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
#include <sys/syscall.h>
|
||||||
|
|
||||||
|
#include <scram.h>
|
||||||
|
|
||||||
|
DEFN_SYSCALL2(void, sys_scram, SYSCALL_SCRAM, int, const void*);
|
||||||
|
|
||||||
|
extern "C" void scram(int event, const void* info)
|
||||||
|
{
|
||||||
|
sys_scram(event, info);
|
||||||
|
__builtin_unreachable();
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
Copyright(C) Jonas 'Sortie' Termansen 2013.
|
Copyright(C) Jonas 'Sortie' Termansen 2013, 2015.
|
||||||
|
|
||||||
This file is part of the Sortix C Library.
|
This file is part of the Sortix C Library.
|
||||||
|
|
||||||
|
@ -25,34 +25,30 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
#include <scram.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#ifdef PATH_MAX
|
||||||
|
#error "This realpath implementation assumes no PATH_MAX"
|
||||||
|
#endif
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
char* realpath(const char* restrict path, char* restrict resolved_path)
|
char* realpath(const char* restrict path, char* restrict resolved_path)
|
||||||
{
|
{
|
||||||
|
if ( resolved_path )
|
||||||
|
{
|
||||||
|
struct scram_undefined_behavior info;
|
||||||
|
info.filename = __FILE__;
|
||||||
|
info.line = __LINE__;
|
||||||
|
info.column = 0;
|
||||||
|
info.violation = "realpath call with non-null argument and PATH_MAX unset";
|
||||||
|
scram(SCRAM_UNDEFINED_BEHAVIOR, &info);
|
||||||
|
}
|
||||||
char* ret_path = canonicalize_file_name(path);
|
char* ret_path = canonicalize_file_name(path);
|
||||||
if ( !ret_path )
|
if ( !ret_path )
|
||||||
return NULL;
|
return NULL;
|
||||||
if ( !resolved_path )
|
return ret_path;
|
||||||
return ret_path;
|
|
||||||
#ifdef PATH_MAX
|
|
||||||
if ( PATH_MAX < strlen(ret_path) + 1 )
|
|
||||||
return errno = ENAMETOOLONG, (char*) NULL;
|
|
||||||
strcpy(resolved_path, ret_path);
|
|
||||||
free(ret_path);
|
|
||||||
return resolved_path;
|
|
||||||
#else
|
|
||||||
if ( !isatty(2) )
|
|
||||||
dup2(open("/dev/tty", O_WRONLY), 2);
|
|
||||||
fprintf(stderr, "%s:%u: %s(\"%s\", %p) = \"%s\": "
|
|
||||||
"This platform doesn't have PATH_MAX and the second argument "
|
|
||||||
"wasn't NULL - You cannot reliably allocate a sufficiently large "
|
|
||||||
"buffer and the POSIX standard specifies this as undefined "
|
|
||||||
"behavior, aborting.\n", __FILE__, __LINE__, __func__, path,
|
|
||||||
resolved_path, ret_path);
|
|
||||||
abort();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue