Answer the following questions which are based on the lecture material for this week.
Using the distinction we made between viruses and worms in lecture, classify the following:
a screensaver program that automatically emails itself to everyone in the contact list of whoever runs it
also accepted last option because of ambiguity of how it runs; generally, we'd consider such things a worm.
a Microsoft Word file containing macros (scripting supported by Microsoft Word) that modifies other Microsoft Word files to contain the same macros
a program distributed with the installer for a free game that injects ads in webpages
a program that, when run by a user on a corporate network, installs a copy of itself to every machine that user can remote desktop into and which injects ads in webpages
a program that is installed by visiting a malicious webpage that exploits a bug in some webbrowsers that records the keystrokes of the current user
Consider the following x86-64 assembly snippet in AT&T syntax:
movq $0x400000, %rax
movq $0x480, %rbx
movq $0x100, %rcx
movb (%rax, %rbx), %cl
addq $1, %rcx
or the same snippet rewritten in Intel syntax:
mov rax,0x400000
mov rbx,0x480
mov rcx,0x100
mov cl,BYTE PTR [rax+rbx*1]
add rcx,0x1
After this runs the value of %rcx
will be equal to _______?
The following questions are about how the Linux x86-64 calling convention would apply to
the function foo
in
struct pair {
int a;
int b;
};
void foo(struct pair w, int x, int y, double z);
To help answer these questions, some possible strategies include:
gcc -S -Os
(on a Linux x86-64 system) will produce a reasonably readable assembly file;The argument w
will be passed:
I should have written (((long) w.b << 32) | (unsigned int) w.a)
or similar to prevent sign extension of w.a
causing the upper bits to be wrong; so accepted both the almost-right answer and none of the above
The argument x
will be passed:
The argument z
will be passed:
Answer the following questions which are based on the lecture material for this week.
In x86-64, there are at least two ways to encode addl %ecx, %eax
(Intel syntax: add EAX, ECX
).
One is 01 c8
(writing as a list of byte values in hexadecimal). What is another?
(You may want to refer to the Intel manuals' reference for the add instruction: encoding summary or page 133 135 [corrected late 14 Feb] of this PDF.)
Consider the following ELF program header as dumped by objdump ([...]
represents parts of the output
of objdump being omitted for brevity)
a.out: file format elf64-x86-64
a.out
architecture: i386:x86-64, flags 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
start address 0x0000000000401090
Program Header:
[...]
LOAD off 0x0000000000000000 vaddr 0x0000000000400000 paddr 0x0000000000400000 align 2**12
filesz 0x0000000000000528 memsz 0x0000000000000528 flags r--
LOAD off 0x0000000000001000 vaddr 0x0000000000401000 paddr 0x0000000000401000 align 2**12
filesz 0x0000000000000225 memsz 0x0000000000000225 flags r-x
LOAD off 0x0000000000002000 vaddr 0x0000000000402000 paddr 0x0000000000402000 align 2**12
filesz 0x0000000000000180 memsz 0x0000000000000180 flags r--
LOAD off 0x0000000000002e10 vaddr 0x0000000000403e10 paddr 0x0000000000403e10 align 2**12
filesz 0x0000000000000228 memsz 0x0000000000000230 flags rw-
[...]
STACK off 0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**4
filesz 0x0000000000000000 memsz 0x0000000000000000 flags rw-
RELRO off 0x0000000000002e10 vaddr 0x0000000000403e10 paddr 0x0000000000403e10 align 2**0
filesz 0x00000000000001f0 memsz 0x00000000000001f0 flags r--
[...]
Based on the program headers, how many bytes of possibly-executable machine code are in the executable?
(Write your answer as a base-10 number of bytes like 123
or a base-16 number of bytes prefixed by 0x
like 0x7b
.)
Based on the program headers, what is the minimum address to which part of the executable should be loaded? Write your answer as a base-16 number.
In lecture, we discussed how Vienna edited its code and data in memory before copying it into an executable to account for each executable having Vienna at a different location (depending on the size of the executable).
We mentioned that some of these modifications could have been avoided by replacing assembly instructions that encode an address directly with ones that encode an address relative to the current address. This would have further simplified Vienna's infection code.
Which of the following modifications to code and data that Vienna makes (to customize itself for a particular executable) could have been avoided using this strategy? Select all that apply.
Each of the following are features of ELF executables. Which of them would prevent Vienna's strategy of appending its code to the executable file and adding a jump to the executable to that code from working on an ELF executable (without Vienna doing substantial additional work to "fix" the executable file)? Select all that apply.
Answer the following questions which are based on the lecture material for this week.
We mentioned several techniques in lecture by which virus-like malware can embed itself in executables.
Which, if any, of the following techniques would likely be detected by anti-virus software that checked whether file lengths of executables changed? (In the options below, a segment refers to something like a ELF segment, like is specified by a LOAD operation in an ELF program header.) Select all that apply.
In lecture we mentioned that the CIH virus inserted its part of its code into "cavities" it found in an executable, and then had some code it inserted reassemble that code in memory and jump to the reassembled code. Which, if any, of the following were advantages of this approach over jumping to the location of the cavities? Select all that apply.
We discussed in lecture how executables often contain unused space. Probably a compiler and/or linker could avoid this unused space. Which, if any, of the following would be likely properties of the resulting executable (when compared to an executable generated without avoiding unused space)? Select all that apply.
Suppose a Linux program set one of the entries of its global offset table to point to
a function foo
while it was running. Which of the following would be likely
outcomes of this? Select all that apply.
Suppose a virus wanted to edit a dynamic linking stub like
0000000000001050 <puts@plt>:
1050: f3 0f 1e fa endbr64
1054: f2 ff 25 75 2f 00 00 bnd jmpq *0x2f75(%rip) # 3fd0 <puts@GLIBC_2.2.5>
(or in Intel syntax):
0000000000001050 <puts@plt>:
1050: f3 0f 1e fa endbr64
1054: f2 ff 25 75 2f 00 00 bnd jmp [RIP + 0x2f75] # 3fd0 <puts@GLIBC_2.2.5>
so that calls to puts@plt would call the virus code stealthily.
If it replaced the jmpq
instruction with a call to the virus code and make it unlikely
that the virus would be noticed, then
which would be the best way (of the choices below) to end the virus code?
To evade detection by pattern-matching like malware often tries to change their code each time they make a copy. Some of these techniques are readily detectable by regular-expression matching.
Suppose we start with self-replicating malware code matched using a signature for the following code:
0000000000000000 <loop>:
0: 48 31 24 c6 xor %rsp,(%rsi,%rax,8)
4: 48 ff c8 dec %rax
7: 7d f7 jge 0 <loop>
(or in Intel syntax:
0000000000000000 <loop>:
0: 48 31 24 c6 xor [rsi+rax*8],rsp
4: 48 ff c8 dec rax
7: 7d f7 jge 0 <loop>
)
Which can be matched using the flex
pattern \x48\x31\x24\xc6\x48\xff\xc8\x7d\xf7
Recall that in flex
:
\xAB
matches a byte with the hexadecimal value AB
..
matches a byte other a newline characterX|Y
matches either X
or Y
.X|Y|Z
matches either X
or Y
or Z
.(Q)*
matches Q repeated zero or more times(Q)+
matches Q repeated one or more timesSuppose to evade this kind of detection, the malware adds between 1 and 4 (chosen randomly) nops between the xor %rsp,(%rsi,%rax,8)
and dec %rax
instructions.
Assume all the inserted nops are one-byte instructions encoded using the byte 90
(which is written as hexadecimal).
Which of the following is a pattern that could match the modified malware without causing a very large number of false positives? Select all that apply.
Suppose to evade this kind of detection, the malware changes the register %rsp
in the xor
instruction
to %rbx
, %rcx
, %rdx
, or %rbp
(chosen at random).
Which of the following would be the best pattern for matching the modified malware without causing a very large number of false positives?
[Note that you can use an assembler to help answer this question.]
In lecture, we divided self-replicating malware that varies their machine code into three categories, which we will define as follows for the following two questions:
add
and sub
, or reordering some instructions), a random "encryption" key and some "encrypted" code that the decrypter executesSuppose antimalware software works by periodically scanning the memory of loaded programs for fixed strings (known to be present in malware). Which of these types of malware are likely to evade this antimalware software? Select all that apply.
I was thinking about looking for signatures based on machine code, but if we're thinking about data used at runtime, they'd likely be decoded and that's a potential avenue even for metamorphic malware. So accepted either answer for C.
Suppose rather than relying on signatures based on machine code, uses signatures based on the file accesses made by programs. Which of these types of malware are likely to evade this antimalware software? Select all that apply.
accepted "metamorphic" on the theory that metamorphic malware's mutations might add bogus file accesses, but that would not be typical
We mentioned in lecture that some malware uses stealth or rootkit-style techniques in an attempt to remain hidden from antimalware software and/or system administrators. Suppose, as part of this stealth strategy, such a malware overrode the operating system's function for listing the contents of directories. Which of the following would be the most likely behavior of the overriden function?
Sometimes malware computes a hash of its own machine code and data and compares it to a stored value. In which of the following circumstances would this check likely fail? Select all that apply.
Consider the following C function:
int example() {
char address[1000];
char name[100];
int points;
ReadInputInto(name);
points = LookupPointsFor(name);
ReadInputInto(address);
return Process(name, points, address);
}
where the ReadInputInto
copies a value from the input into its argument. If the value input is
too long, then ReadInputInto
will exceed the bounds of the buffer given as an argument.
Suppose when this is compiled, the compiler places:
address
at the stack pointer + 4name
at the stack pointer + 1004points
at the stack pointer + 1104example
at the stack pointer + 1108where "the stack pointer" refers to the stack pointer's value in the function's body, such
as just before the calls to scanf
.
An attacker who controls the input for address
could change the value for points
by putting their
desired value for points
_____ bytes into the input for address
. (Write your answer as a base 10 number.)
Answer the following questions about the lecture material for this week.
For the following questions, consider the following C function which is vulnerable to stack smashing:
int read_number() {
char buffer[20];
int ch; unsigned i = 0;
while (1) {
ch = getchar();
if (ch == '\n' || ch == EOF) break;
buffer[i] = ch;
i += 1;
}
buffer[i] = '\0';
return atoi(buffer);
}
which is compiled to the following (annotated) assembly:
read_number:
/* save old values of three registers used for temporaries
and local variables */
pushq %r12
pushq %rbp
pushq %rbx
/* i (%ebx) = 0 */
xorl %ebx, %ebx
/* allocate 32 bytes on the stack for buffer */
subq $32, %rsp /* Intel syntax: sub RSP, 32 */
/* buffer (%r12) = stack pointer */
movq %rsp, %r12 /* Intel syntax: mov R12, RSP */
jmp loop_entry
loop_top:
/* end of loop: */
/* buffer[i] = ch; */
movb %al, (%r12,%rbx)
/* i += 1 */
addq $1, %rbx
loop_entry:
/* start of loop */
call getchar@PLT /* ch (%eax) = getchar() */
/* if (ch == '\n' (10) || ch == EOF) break */
cmpl $10, %eax
je loop_end
cmpl $-1, %eax
jne loop_top
loop_end:
/* buffer[i] = '\0' */
movl %ebx, %ebp /* Intel syntax: mov EBP, EBX */
movb $0, (%rsp,%rbp) /* Intel syntax: mov [RSP + RBP], 0 */
/* atoi(buffer) */
movq %r12, %rdi /* Intel syntax: mov RDI, R12 */
call atoi@PLT
/* deallocate stack space, restore saved registers */
addq $32, %rsp /* Intel syntax: add RSP, 32 */
/* restore previously saved values */
popq %rbx
popq %rbp
popq %r12
ret
If the stack smashing technique discussed in lecture were used to exploit this function, then the attacker's malicious code would execute:
If the stack smashing technique discussed in lecture were used to exploit this function, then the attacker would make their pointer to the malicious code start at byte number ____ of input, considering the first byte of input to be byte number 0. (Write your answer as a decimal number.)
32 bytes allocated for buffer + 8 * 3 bytes for saved registers
Which of the following would be the most useful information that might be leaked by an information leak vulnerability for an attacker attempting to perform a buffer overflow despite stack canaries?
I decided to drop this quesiton giving everyone credit for it. The other answers are useful for avoiding address randomization (or the difficulty of predicting the location of things on the stack in general) if you already have an arbitrary memory overwrite, but not for defeating stack canaries in particular. I understand, however, the interpretation that that might give one the ability to sidestep the existence of stack canaries in the first place, and I should've explicitly mentioned doing a stack smashing attack.
Consider the following C function ReadAndProcess
:
void ReadAndProcess(FILE *in) {
const unsigned int MAX_DATA_ITEMS = 10000;
unsigned int size;
unsigned long tag;
int *data = malloc(MAX_DATA_ITEMS * sizeof(int));
fread(&size, 4, 1, in);
unsigned int data_count = size / sizeof(int);
if (data_count > MAX_DATA_ITEMS) {
fprintf(stderr, "TOO BIG!\n");
abort();
} else {
fread(&tag, 8, 1, in);
fread(&data[0], size - 8, 1, in);
DoSomethingWith(tag, data, data_count);
}
}
(The C standard library fread(p, S, N, i)
reads S*N
bytes from the file i
into the buffer pointed to by p
.)
This function is intended to read data in the following binary format:
size
size
bytes consisting of:
tag
data
But if the compiler performs arithmetic in the code above using 4-byte unsigned ints, then this code may
attempt to overflow the heap-allocated buffer data
. Give an example of a value for size
the attacker
could choose to trigger the overflow. Write your answer as a base-10 number.
Answer the following questions about the lecture material for this week.
Suppose a buffer vulnerable to overflow is stored in a struct like the following:
struct vulnerable_struct {
char buffer[128];
long *current;
};
void vulnerable(struct vulnerable_struct *s) {
scanf("%s", s->buffer); // <-- CAN OVERFLOW s->buffer
s->current = atol(s->buffer);
}
(atol
converts a string to an long
; if the string contains extra text after the integer (e.g. "102cf"), it returns the integer at the beginning.)
One way an attacker can exploit the buffer overflow is by overwritin the adjacent value of s->current
.
Which of the following values could be useful [not in original question, but should have been: to place in s->current
] as part of turning this exploit into something
that would trigger execution of code of the attacker's choice? Select all that apply.
Also accepted selecting everything. My intention was to ask specifically about values that would be useful to put into current
, but what I wrote could easily be interpreted as asking about values that would be nice to know for the exploit overall.
In lecture we mentioned relocation read-only (RELRO), in which information filled in by the dynamic linker, like global offset tables and virtual function tables, is configured to be read-only immediately after the program loads. Which of the following would be prevented by RELRO? Select all that apply.
Suppose a prorgam supports multiple user interfaces. To implement this functionality, it chooses between several different sets of user interface functions based on a configuration parameter. Each user interface is represented by a struct containing pointers to relevant functions:
struct ui_functions {
/* this declares a field 'DisplayString' which is a pointer to
function returning void and taking a const char * argument */
void (*DisplayString)(const char *);
void (*LocateFile)(const char*, const char *, int);
...
};
A global variable points to the currently active set of functions:
struct functions *current_ui_functions;
At program startup, the program allocates a new instance of this struct on the heap,
initializes its function pointers based on a configuration file, and then
sets current_ui_functions
to point to that new instance of the struct.
After startup, the program would call particular functions using this global variable using code like:
(current_ui_functions->DisplayString)(argument);
(which could also be written ((*current_ui_functions).DisplayString)(argument)
.)
Suppose that in order to prevent buffer overflow attacks from interfering
with this, the program arranged for guard pages to be placed on
either side of the pointer current_ui_functions
.
Which of the following operations would these guard pages be likely to prevent?
Select all that apply.
wrote current_functions
in place of current_ui_functions
in the part of the question text about guard page originally; I'm assuming studnets figured out what was meant.
Suppose we have discovered that a program contains the following gadgets at the following addresses:
popq %rcx; popq %rax; popq %rdi; ret
pushq %rax; push %rbx; cmp %rax, %rbx; ret
movl (%rax), %eax; ret
movl %edi, %esi; movl %eax, %edi; ret
pushq %rdi; pushq %rsi; ret
popq %rsi; ret
Suppose also that 0x300000
is the address of a writeable global variable.
Suppose we wanted to use these gadgets to call a function void foo(int x, int y)
located
at address 0x200000 as if it were called like:
foo(0x42, 0x43);
Which of the following are ROP chains (written with the overwritten return address first, followed by the other values that would be afterwards in memory) which would achieve this? Select all that apply.
Answer the following questions about the lecture material for this week.
For the following questions, suppose a program uses a function pointer to perform the following call:
(*function_pointer)(attacker_controlled_long, attacker_controlled_string);
on an x86-64 system and an attacker can control the value of function_pointer
,
and the argument types for this function pointer are long
and char*
.
Assume the program being attacked is configured so that all writeable memory is
not executable.
For each of the following questions,
the attacker's goal is to run a return-oriented programming chain by selecting
appropriate values for function_pointer
, attacker_controlled_int
,
and attacker_controlled_string
.
Which of the following gadgets would be most useful to point function_pointer
to in order to achieving the attacker's goal?
Suppose function_pointer
points to the gadget pushq %rdi; movq %rsi, %rsp; ret
.
Then the attacker should set attacker_controlled_long
and attacker_controlled_str
to:
Consider the following extract from objdump
output on an executable compiled and linked
to fully support ASLR.
000000000000116b <foo>:
116b: 50 push %rax
116c: 8b 3d ba 2e 00 00 mov 0x2eba(%rip),%edi # 402c <x>
1172: ff 15 98 2e 00 00 callq *0x2e98(%rip) # 4010 <f>
1178: 5a pop %rdx
1179: c3 retq
000000000000117a <quux>:
117a: 50 push %rax
117b: 48 8b 35 9e 2e 00 00 mov 0x2e9e(%rip),%rsi # 4020 <stderr@@GLIBC_2.2.5>
1182: 48 8d 3d 7b 0e 00 00 lea 0xe7b(%rip),%rdi # 2004 <_IO_stdin_used+0x4>
1189: e8 a2 fe ff ff callq 1030 <fputs@plt>
118e: 31 c0 xor %eax,%eax
1190: 5a pop %rdx
1191: c3 retq
The function foo
calls runs a function using a global variable f
that is a function pointer.
Since the application fully supports ASLR, when it is loaded, the actual memory addresses will not be the addresses chosen above, but will be selected randomly.
Suppose we discover that when quux
calls puts@plt
that:
%rsp
is 0x7fff98
%rsi
is 0x900030
%rdi
is 0x500004
%rax
is 0x500300
0x4ff18e
Based on the information above, what is the address of the function pointer f
used
by foo
? Write your answer as a hexedecimal number. If not enough information is provided,
write unknown
and explain in the comments.
In lecture, we discussed how an attacker might be able to take advantage of a bug that lets them write past the end of an object allocated on the heap with a particular kind of malloc/free implementation. In this attack, the malloc/free implementation kept a doubly linked list in free regions of the heap, and the attacker could overwrite the next and prev pointers for the following free region of the heap using their heap object overflow. As a result, the malloc/free implementation would write a value chosen by the attacker to a memory location chosen by the attacker.
Which of the following would prevent this attack strategy? Select all that apply.
Answer the following questions about the lecture material for this week
Consider the following C snippet:
struct Clipboard {
/* this declares a pointer to function called 'get'
returning a const char* and taking a
struct Clipboard* argument
*/
const char * (*get)(struct Clipboard*);
/* this declares a pointer to function called 'set'
taking a two arguments: a struct Clipboard*,
and a const char*
*/
void (*set)(struct Clipboard *, const char *);
...
};
struct Clipboard *current_clipboard;
...
void ReadToClipboard() {
char *buffer = malloc(1024);
fgets(buffer, sizeof(1024), stdin);
(current_clipboard->set)(current_clipboard, buffer);
free(buffer);
}
Suppose an attacker can trigger a use-after-free bug that erroneously frees
the object current_clipboard
points to and then calls ReadToClipboard()
.
Suppose the attacker can also arrange for buffer
to
be allocated memory at the same location as current_clipboard
.
Where in their input (that will be read with fgets
)
should the attacker place the address of code they would like run?
Which of the following would prevent use-after-free vulnerabilities? Select all that apply.
In lecture, we mentioned that the C standard library
functions strncpy
and strncat
can be nonintuitive
to use as replacements for strcpy
(string copy) and strcat
(string concatenate)
with bounds checking.
For example code, if an attacker could supply input of arbitrary length as the string
attacker_input
to code like:
char buffer[1024];
strncpy(buffer, attacker_input, sizeof buffer)
puts(buffer);
Then the attacker would likely be able to ___. Select all that apply.
Answer the following questions about the lecture material for week 10.
In lecture, we discussed how a "fat pointer" representation is one strategy to add bounds checking to existing C code.
Suppose we have such a "fat pointer" represented as:
struct MyPtr {
char *pointer;
char *minimum;
char *maximum;
}
as was shown in lecture. Code like
p[10] = 1;
would be converted to something like:
CHECK(p->pointer + 10 >= minimum && p-> pointer + 10 <= maximum);
p->pointer[10] = 1;
(where CHECK(x) is some function that will trigger a crash if x is false).
Similarly, we could convert code like:
memcpy(p, "ABCD", 4);
to code like:
CHECK(_________);
memcpy(p->pointer, "ABCD", 4);
where the blank in CHECK contains:
was originally miskeyed
Consider the following vulnerable C function:
char *vulnerable_copy(char *attacker_input) {
char *copy = malloc(sizeof(attacker_input) + 1);
char *in = &attacker_input[0];
char *out = ©[0];
do {
*out = *in; /* (1) */
in += 1; /* (2) */
out += 1; /* (3) */
} while (*in != '\0');
return copy;
}
Because sizeof(attacker_input)
is the size of a pointer attacker_input
(8 bytes
on x86-64) and [should have been included, but wasn't due to typo: not] the length of string pointed to by attacker_input
, this code will go
out of bounds of the heap object copy
.
Which of the following techniques we discussed in lecture would prevent this from being exploited by an attacker? Select all that apply.
For which of the following techniques we discussed in lecture would we expect the actual code
run to execute the line marked (1)
to include some sort of bounds or validity check?
Select all that apply.
Which of the following are advantages of using symbolic execution to produce test cases over using random testing to produce test cases? Select all that apply.
Answer the following questions about the lecture material for this week.
Consider the following function:
int example(int a, int b, int c) {
if (a > 10) {
if (b > 10) {
mystery1(a);
if (c > 10) {
mystery2(b);
} else if (c == 10) {
mystery3(b);
}
}
}
if (b == 20) {
mystery4(a);
}
}
If we were testing this function via coverage-guided fuzzing, than the fuzz tester would maintain a list of discovered distinct test cases, where a test case was considered distinct if it covered different path than any other test case.
Suppose this list initially contained:
a = 0, b = 0, c = 0
a = 0, b = 20, c = 0
a = 50, b = 50, c = 10
Which of the following variations would be considered new distint test cases? **Select all that apply.*
Consider the following C snippet:
int mystery;
void bar(char *p) {
if (p[0] == 'A') {
free(p)
} else {
strcat(p, "more example");
}
}
void foo() {
char *q = malloc(1024);
strcpy(q, "example");
bar(q);
strcat(q, "another example");
printf("q = %s\n", q);
free(q);
}
Suppose a static analysis tool warns that a use-after-free may occur when foo() runs,
but in the program in which this appears, that does not happen for any possible input.
The analysis determines that after bar
is
Which of the following changes to the static analysis tool would avoid this
false positive? Select all that apply.
dropped due to error in question
In lecture we mentioned that constructing an information flow graph might be used to identify probable cases of SQL injection by seeing whether user input flows into a library call that accepts SQL code.
Consider the following (Python-like) pseudocode:
class_id = input()
order = input()
student_id = input()
q = 'SELECT * FROM registrations WHERE class = ' + class_id
if student_id != '':
q += ' WHERE student_id = ?'
if order == 'id':
q = q + ' ORDER BY registeration_id ASC'
elif order == 'applied_date' or order == 'enrolled_date':
q = q + ' ORDER BY ' + order + ' ASC'
else:
raise Exception("Invalid order")
sql_prepare_query(q)
...
Assuming we used the version of the analysis that did not consider control flow (e.g. a value being used as an if statement condition) to create an edge in the graph, this would detect the value passed to sql_prepare_query came from ___? **Select all that apply.**
Consider a dynamic taint tracking system, which tracks, for every value, whether or not it is
tainted.
Suppose a malware author wanted to defeat this system by creating false positives
causing the value x
appear to be dependent on y
even though it is not really.
Which of the following are likely to achieve this goal, if converted
to unoptimized assembly (so expressions like y * 0
are not optimized into 0
, etc.)? Select all that apply.
Answer the following questions about the lecture material for week 12.
Consider the following noncompiling Rust code snippet (where ...
represents
code omitted for brevity):
struct Student {
name: String,
courses: Vec<String>,
}
fn do_something_with(arg: HashMap<String, &Student>) {...}
fn example() {
let mut first_student = Student {
name: ..., courses: ...,
};
let mut students: HashMap<String, &Student> = HashMap::new();
students.insert(String::from("Some Name"), &first_student); /* (A) */
first_student.courses.push(String::from("CS1110")); /* (B) */
do_something_with(students);
}
The Rust compiler will complain that this code violates the ownership and borrowing rules
we discussed in lecture. Specifically, the line labelled (B)
attempts to borrow
the value first_student
(to modify it by push
ing onto its courses
field)
while it is being borrowed because of the line labelled (A)
(to insert a reference to it
into the HashMap).
(In the interest of helping you understand the Rust code above, this Rust code is approximately equivalent to this C++ code:
struct Student { string name; vector<string> courses; };
void do_something_with(map<string, const Student*> arg) {...}
void example() {
Student first_student = ...;
map<string, const Student*> students;
students["Some Name"] = &first_student;
first_student.courses.push_back("CS1110");
do_something_with(students);
}
)
Does this compiler error represent a use-after-free bug that can occur when the above code is run in a particular way?
Which of the following would avoid this compiler error? Select all that apply.
Which of the following do Rust's compiler-enforced and standard-library-enforced
safety rules ensure (in the absence of
code explicitly marked unsafe
or bugs in the standard library code or compiler)? Select all that apply.
In lecture we mentioned the idea of privilege separation where an application is divided into multiple parts and some parts are sandboxed and run with fewer privilieges than the rest. Suppose we were adding privilege separation to a spreadsheet program. Which of the following components would be good candidates for functionality to implement in the less privilieged part of the spreadsheet program? Select all that apply.
Which of the following scenarios would using chroot
(which changes the effective root directory
for a process) and running a program within the chroot environment without system administrator/root
permissions be effective for? Assume that chroot
is not used in combination with
mount namespaces, bind mounts, etc. Select all that apply.
When using containers, such as implemented by docker using Linux's chroot and namespaces features, we would expect containers to protect against a compromised web server running in the container ____. Select all that apply.
Which of the following techniques for confining applications are likely to have the side effect of changing where the application's files are stored? Select all that apply.
According to the principles we discussed for permissions prompts in lecture, it would be best to ____.