Intro
I am integrating EndpointSecurity Framework and observing ES_EVENT_TYPE_AUTH_EXEC event.
I able to see the command arguments, but I am not able to read the command input.
Assuming that the command is as follow:
thirdPartyApp do something < ~/Desktop/file.txt
My code is: (msg is a value of type es_event_exec_t *)
for (int i = 0; i < es_exec_arg_count(&msg->event.exec); i++) {
es_string_token_t arg = es_exec_arg(&msg->event.exec, i);
print("arg: %s",arg.data);
}
Challenge is
The code output is only:
thirdPartyApp do something , without < ~/Desktop/file.txt
The thing is, < ~/Desktop/file.txt is not an argument, its a redirect as described here
What did I try?
I tried to read the env arguments too, but they were not helpful at all.
I tried to read the file descriptors, and then to read the file using NSFileHandle but they all were empty, 0 bytes.
Waiting to here from you
Redirects work by the shell open(2)ing the files you redirected and dup(2)ing them onto 0,1,2 (depending on redirect) before fork(2)ing or posix_spawn(2)ing, and allowing the child (spawned command). That means that EPS will not be able to see them as es_exec_args - because (as you correctly say) they're not arguments.
If you use
const es_fd_t * _Nonnull
es_exec_fd(const es_event_exec_t * _Nonnull event, uint32_t index);
you should be able to get back an es_fd_t - however the only relevant field will be the fdtype:
typedef struct {
int32_t fd;
uint32_t fdtype;
union {
struct {
uint64_t pipe_id;
} pipe;
};
} es_fd_t;
A better option is to thus leave the comfort of EPS and use proc_info(2) (via libproc.h) which can get you the full FD information for any process and fd (much like supraudit from http://newosxbook.com/tools/supraudit.html does).
Note, that STILL won't get you the input itself. That input is consumed by the process using read(2) (and output using write(2), of course), and neither EPS nor BSM (auditing) offers hooks for that.
Related
In order to make my question easy to understand I want to use the following example:
The following code is called nonblock do-loop in fortran language
DO 20 I=1, N ! line 1
DO 20 J=1, N ! line 2
! more codes
20 CONTINUE ! line 4
Pay attention that the label 20 at line 4 means the end of both the inner do-loop and the outer do-loop.
I want my flex program to parse the feature correctly: when flex reads the label 20, it will return ENDDO terminal twice.
Firstly, because I also use bison, so every time bison calls yylex() to get one terminal. If I can ask bison to get terminals from yylex() in some cases, and from another function in other cases, maybe I could solve this problem, however, I got no idea here then.
Of course there are some workarounds, for eample, I can use flex's start condition but I don't think it is a good solution. So I ask if there's any way to solve my question without a workaround?
It is easy enough to modify the lexical scanner produced by (f)lex to implement a token queue, but that is not necessarily the optimal solution. (See below for a better solution.) (Also, it is really not clear to me that for your particular problem, fabricating the extra token in the lexer is truly appropriate.)
The general approach is to insert code at the top of the yylex function, which you can do by placing the code immediately after the %% line and before the first rule. (The code must be indented so that it is not interpreted as a rule.) For non-reentrant scanners, this will typically involve the use of a local static variable to hold the queue. For a simple but dumb example, using the C API but compiling with C++ so as to have access to the C++ standard library:
%%
/* This code will be executed each time `yylex` is called, before
* any generated code. It may include declarations, even if compiled
* with C89.
*/
static std::deque<int> tokenq;
if (!tokenq.empty()) {
int token = tokenq.front();
tokenq.pop_front();
return token;
}
[[:digit:]]+ { /* match a number and return that many HELLO tokens */
int n = atoi(yytext);
for (int i = 0; i < n; ++i)
tokenq.push_back(HELLO);
}
The above code makes no attempt to provide a semantic value for the queued tokens; you could achieve that using something like a std::queue<std::pair<int, YYSTYPE>> for the token queue, but the fact that YYSTYPE is typically a union will make for some complications. Also, if that were the only reason to use the token queue, it is obvious that it could be replaced with a simple counter, which would be much more efficient. See, for example, this answer which does something vaguely similar to your question (and take note of the suggestions in Note 1 of that answer).
Better alternative: Use a push parser
Although the token queue solution is attractive and simple, it is rarely the best solution. In most cases, code will be clearer and easier to write if you request bison to produce a "push parser". With a push parser, the parser is called by the lexer every time a token is available. This makes it trivial to return multiple tokens from a lexer action; you just call the parser for each token. Similarly, if a rule doesn't produce any tokens, it simply fails to call the parser. In this model, the only lexer action which actually returns is the <<EOF>> rule, and it only does so after calling the parser with the END token to indicate that parsing is complete.
Unfortunately, the interface for push parsers is not only subject to change, as that manual link indicates; it is also very badly documented. So here is a simple but complete example which shows how it is done.
The push parser keeps its state in a yypstate structure, which needs to be passed to the parser on each call. Since the lexer is called only once for each input file, it is reasonable for the lexer to own that structure, which can be done as above with a local static variable [Note 1]: the parser state is initialized when yylex is called, and the EOF rule deletes the parser state in order to reclaim whatever memory it is using.
It is usually most convenient to build a reentrant push parser, which means that the parser does not rely on the global yylval variable [Note 2]. Instead, a pointer to the semantic value must be provided as an additional argument to yypush_parse. If your parser doesn't refer to the semantic value for the particular token type, you can provide NULL for this argument. Or, as in the code below, you can use a local semantic value variable in the lexer. It is not necessary that every call to the push parser provide the same pointer. In all, the changes to the scanner definition are minimal:
%%
/* Initialize a parser state object */
yypstate* pstate = yypstate_new();
/* A semantic value which can be sent to the parser on each call */
YYSTYPE yylval;
/* Some example scanner actions */
"keyword" { /* Simple keyword which just sends a value-less token */
yypush_parse(pstate, TK_KEYWORD, NULL); /* See Note 3 */
}
[[:digit:]]+ { /* Token with a semantic value */
yylval.num = atoi(yytext);
yypush_parse(pstate, TK_NUMBER, &yylval);
}
"dice-roll" { /* sends three random numbers */
for (int i = 0; i < 2; ++i) {
yylval.num = rand() % 6;
yypush_parse(pstate, TK_NUMBER, &yylval);
}
<<EOF>> { /* Obligatory EOF rule */
/* Send the parser the end token (0) */
int status = yypush_parse(pstate, 0, NULL);
/* Free the pstate */
yypstate_delete(pstate);
/* return the parser status; 0 is success */
return status;
}
In the parser, not much needs to be changed at all, other than adding the necessary declarations: [Note 4]
%define api.pure full
%define api.push-pull push
Notes
If you were building a reentrant lexer as well, you would use the extra data section of the lexer state object instead of static variables.
If you are using location objects in your parser to track source code locations, this also applies to yylloc.
The example code does not do a good job of detecting errors, since it doesn't check return codes from the calls to yypush_parse. One solution I commonly use is some variant on the macro SEND:
#define SEND(token) do { \
int status = yypush_parse(pstate, token, &yylval); \
if (status != YYPUSH_MORE) { \
yypstate_delete(pstate); \
return status; \
} \
} while (0)
It's also possible to use a goto to avoid the multiple instances of the yypstate_delete and return. YMMV.
You may have to modify the prototype of yyerror. If you are using locations and/or providing extra parameters to the push_parser, the location object and/or the extra parameters will also be present in the yyerror call. (The error string is always the last parameter.) For whatever reason, the parser state object is not provided to yyerror, which means that the yyerror function no longer has access to variables such as yych, which are now members of the yypstate structure rather than being global variables, so if you use these variables in your error reporting (which is not really recommended practice), then you will have to find an alternative solution.
Thanks to one of my friends, he provide a way to achieve
If I can ask bison to get terminals from yylex() in some cases, and from another function in other cases
In flex generated flex.cpp code, there is a macro
/* Default declaration of generated scanner - a define so the user can
* easily add parameters.
*/
#ifndef YY_DECL
#define YY_DECL_IS_OURS 1
extern int yylex (void);
#define YY_DECL int yylex (void)
#endif /* !YY_DECL */
so I can "rename" flex's yylex() function to another function like pure_yylex().
So my problem is solved by:
push all terminals I want to give bison to a global vector<int>
implement a yylex() function by myself, when bison call yylex(), this function will firstly try to get terminals from a that global vector<int>
if vector<int> is empty, yylex() calls pure_yylex(), and flex starts to work
As I know, we can use ostream_iterator in c++11 to print a container.
For example,
std::vector<int> myvector;
for (int i=1; i<10; ++i) myvector.push_back(i*10);
std::copy ( myvector.begin(), myvector.end(), std::ostream_iterator<int>{std::cout, " "} );
I don't know when and why we use the code above, instead of traditional way, such as:
for(const auto & i : myvector) std::cout<<i<<" ";
In my opinion, the traditional way is faster because there is no copy, am I right?
std::ostream_iterator is a single-pass OutputIterator, so it can be used in any algorithms which accept such iterator. The use of it for outputing vector of int-s is just for presenting its capabilities.
In my opinion, the traditional way is faster because there is no copy, am I right?
You may find here: http://en.cppreference.com/w/cpp/algorithm/copy that copy is implemented quite similarly to your for-auto loop. It is also specialized for various types to work as efficient as possible. On the other hand writing to std::ostream_iterator is done by assignment to it, and you can read here : http://en.cppreference.com/w/cpp/iterator/ostream_iterator/operator%3D that it resolves to *out_stream << value; operation (if delimiter is ignored).
You may also find that this iterator suffers from the problem of extra trailing delimiter which is inserted at the end. To fix this there will be (possibly in C++17) a new is a single-pass OutputIterator std::experimental::ostream_joiner
A short (and maybe silly) example where using iterator is usefull. The point is that you can direct your data to any sink - a file, console output, memory buffer. Whatever output you choose, MyData::serialize does not needs changes, you only need to provide OutputIterator.
struct MyData {
std::vector<int> data = {1,2,3,4};
template<typename T>
void serialize(T iterator) {
std::copy(data.begin(), data.end(), iterator);
}
};
int main()
{
MyData data;
// Output to stream
data.serialize(std::ostream_iterator<int>(std::cout, ","));
// Output to memory
std::vector<int> copy;
data.serialize(std::back_inserter(copy));
// Other uses with different iterator adaptors:
// std::front_insert_iterator
// other, maybe custom ones
}
The difference is polymorphism vs. hardcoded stream.
std::ostream_iterator builds itself from any class which inherits from std::ostream, so in runtime, you can change or wire the iterator to write to difference output stream type based on the context on which the functions runs.
the second snippet uses a hardcoded std::cout which cannot change in runtime.
I am working on a Linux kernel module that needs to modify network packets and append an extra header. I already implemented the modification part, recomputed the check-sums and it worked nice. But I don't know how to safely append an extra header. If my input packet is something like:
ip-header / tcp-header / data
I would like to have an output packet like:
ip-header / tcp-header / my-header / data
For what I read, I think I need something like the following code. I wrote my specific questions on the code as comments. My general concern is if the code I am writing here is memory-safe or what should I do to have a memory-safe way to append the new header. Also, if I am doing something wrong or there is a better way to do it I will also appreciate the comment. I have tried to find examples but no luck so far. Here is the code:
static unsigned int my_iptables_target(struct sk_buff *skb, const struct xt_action_param *par) {
const struct xt_mytarget_info *info = par->targinfo;
/* Some code ... */
if (!skb_make_writable(skb, skb->len)) {
//Drop the packet
return NF_DROP;
}
struct newheader* myheader;
// Check if there is enough space and do something about it
if (skb_headroom(skb) < sizeof(struct newheader)) {
// So there is no enugh space.
/* I don't know well what to put here. I read that a function called pskb_expand_head might
* do the job. I do not understand very well how it works, or why it might fail (return value
* different from zero). Does this code work:
*/
if (pskb_expand_head(skb, sizeof(struct newheader) - skb_headroom(skb), 0, GPF_ATOMIC) != 0) {
// What does it mean if the code reaches this point?
return NF_DROP;
}
}
// At this point, there should be enough space
skb_push(skb, sizeof(struct newheader));
/* I also think that skb_push() creates space at the beggining, to open space between the header and
* the body I guess I must move the network/transport headers up. Perhaps something like this:
*/
memcpy(skb->data, skb->data + sizeof(struct newheader), size_of_all_headers - sizeof(struct newheader));
// Then set myheader address and fill data.
myheader = skb->data + size_of_all_headers;
//Then just set the new header, and recompute checksums.
return XT_CONTINUE;
}
I assumed that the variable size_of_all_headers contains the size in bytes of the network and transport headers. I also think that memcpy copies bytes in increasing order, so that call shouldn't be a problem. So does the above code works? It is all memory-safe? Are there better ways to do it? Are there examples (or can you provide one) that does something like this?
I used a code similar to the one in the question and so far it has worked very well for all the test I have done. To answer some of the specific questions, I used something like:
if (skb_headroom(skb) < sizeof(struct newheader)) {
printk("I got here!\n");
if (pskb_expand_head(skb, sizeof(struct newheader) - skb_headroom(skb), 0, GPF_ATOMIC) != 0) {
printk("And also here\n");
return NF_DROP;
}
}
But none of the print statements ever executed. I suppose that happens because the OS reserves enough space in memory such that there can be no problems given the limits of the IP header. But I think it is better to leave that if statement to grow the packet if necessary.
The other difference of the code that I tested and worked is that instead of moving all the other headers up to create a space for my header, I chose to move the body of the packet down.
I need to get user input (y/n) keypress in console.
How I can do it? I know that I can use readln, but is there any other way? I am trying to use getc()
import std.stdio;
import std.string;
import std.stream;
void main()
{
while (getc() != 'y')
{
writeln("try again");
}
}
but I am getting error:
source\app.d(6): Error: function core.stdc.stdio.getc (shared(_iobuf)* stream) is not callable using argument types (File)
next attempt:
char [] checkYesNo() #property
{
char [] key;
while(readln(key) != 'y')
{
}
return key;
}
This code compile, but failure at execution time with strange error "Error executing command run"
One library that does the single press is my terminal.d
https://github.com/adamdruppe/arsd/blob/master/terminal.d
It looks more complex than it is. Here's an example to get a single key:
import terminal;
void main() {
auto terminal = Terminal(ConsoleOutputType.linear);
auto input = RealTimeConsoleInput(&terminal, ConsoleInputFlags.raw);
terminal.writeln("Press any key to exit");
auto ch = input.getch();
terminal.writeln("Bye!");
}
To build, put terminal.d in your folder and then compile them together: dmd yourfile.d terminal.d.
First, you construct a terminal. The two types are linear or cellular. Linear outputs one line at a time, cellular goes "full screen" in the console.
Then, you make an input struct based on that terminal. The ConsoleInputFlags says what you want: do you want echo? Mouse input? etc. raw is the simplest one: it will send you plain keyboard input as they happen with relatively little else.
Then you can write to the terminal and get characters from the input. The input.getch() line fetches a single character, returning immediately when something is available without buffering. Other functions available on input include kbhit, which returns true if a key was hit so input is available, false if it isn't - useful for a real time game, being checked on a timer, or nextEvent, which gives full input support, including mouse events. The Demo in the terminal.d source code shows something with full support:
https://github.com/adamdruppe/arsd/blob/master/terminal.d#L2265
Another useful convenience function on terminal itself btw is getline, which grabs a full line at a time, but also lets the user edit it and offers history and autocomplete. terminal also offers a function called color to do colored output, and moveTo, useful in cellular mode, to move the cursor around the screen. Browse the code to learn more, if you're interested.
The error is because phobos is conflicting with the runtime.
std.stdio publicly imports core.stdc.stdio, and they both define stdin, but as different types. getc() really just calls fgetc( stdin ), so when the runtime tries calling getc(), it passes in the stdin from std.stdio instead of the correct one from core.stdc.stdio, resulting in the error.
The best way to get around the conflict is just to alias core.stdc.stdio as something else and then use the fully qualified name.
import std.stdio;
void main()
{
while (getc() != 'y')
{
writeln("try again");
}
}
auto getc()
{
import stdc = core.stdc.stdio;
return stdc.getc( stdc.stdin );
}
But beware that getc() uses a buffer internally, and won't return until the user presses the enter key, at which point it reads the first char from the buffer and returns that, and will continue to read the next char from the buffer for subsequent calls until it reaches the end. So entering nnn<enter> in the terminal window results in try again being printed 3 times. If you want a method that returns a single char without the need for the enter key, you'll need to look for a library solution, no standard functions for that exist in either C or D.
If you're not concerned with a cross-platform solution, there's a Windows-specific header that defines a getch() function which doesn't use a buffer and returns on every keystroke, rather than on enter. Just add this to your code and replace the call to getc() with a call to getch().
extern( C ) int getch();
How about:
import std.stdio;
void main(){
writefln("Enter something: ");
char entered;
do{
readf(" %c\n", &entered);
writefln("Entered: %s", entered);
}while(entered != 'y');
}
The important bit is the " %c\n".
%c tells readf to match a char rather than a string.
I want to send messages from a kernel extension into a userland program using kernel controls. I'm experiencing an EINVAL error when calling ctl_enqueuedata.
I've set up a Kernel Control and I'm trying to send messages through it using ctl_enqueuedata. I'm setting
ep_ctl.ctl_flags = 0
before passing to ctl_register, which, the documents suggest, should result in ctl_unit being automatically set.
To quote kern_control.h:
For a dynamically assigned control ID, do not set the CTL_FLAG_REG_ID_UNIT flag.
static struct kern_ctl_reg ep_ctl;
static kern_ctl_ref kctlref;
...
errno_t error;
bzero(&ep_ctl, sizeof(ep_ctl)); // sets ctl_unit to 0
ep_ctl.ctl_id = 0;
ep_ctl.ctl_unit = 0;
strncpy(ep_ctl.ctl_name, CONTROL_NAME, strlen(CONTROL_NAME));
ep_ctl.ctl_flags = 0x0; // not CTL_FLAG_REG_ID_UNIT so unit gets supplied. Not CTL_FLAG_PRIVILEGED either.
ep_ctl.ctl_send = EPHandleSend;
ep_ctl.ctl_getopt = EPHandleGet;
ep_ctl.ctl_setopt = EPHandleSet;
ep_ctl.ctl_connect = EPHandleConnect;
ep_ctl.ctl_disconnect = EPHandleDisconnect;
error = ctl_register(&ep_ctl, &kctlref);
printf("setupControl %d\n", error);
When I call ctl_register it returns 0 ok.
When I call ctl_enqueuedata, passing in my struct kern_ctl_reg I'm getting 22, which is EINVAL. One of those arguments appears to be incorrect. The other arguments I'm passing are a static test string and its length for data, and zero flags.
int result = ctl_enqueuedata(kctlref, ep_ctl.ctl_unit, filename, length, 0x0);
The value of my ep_ctl's .ctl_unit is 0, the value of .ctl_id is 6. Could it be that the ctl_unit value being passed to ctl_enqueuedata is invalid / un-initialized?
kern_control.h says of ctl_unit:
This field is ignored for a dynamically assigned control ID
Which suggests that it isn't required anyway?
Have I missed something in initializing my ep_ctl?
I believe you supply wrong value as the 2nd parameter of ctl_enqueuedata(). Instead of ep_ctl.ctl_unit, you have to remember struct sockaddr_ctl::sc_unit in the EPHandleConnect() callback and that's what you are supposed to pass into ctl_enqueuedata().
I suggest using OSX's kernel debugging facilities to figure out what's going on here. That will let you walk through the relevant kernel code, and should tell you where it's rejecting your input.