CS3130 Spring 2025 quizzes KEY



quiz for week 2

Question 1 (4 pt; mean 4)

Consider the following C declarations:

int a[4] = {1,1,2,2};
int b[4] = {2,2,3,3};

int *p[4] = {&a[0], &b[0], &a[2], &b[2]};

Given these declarations and initial values, which of the following snippets will not access out-of-bounds memory, create a pointer to out-of-bounds memory, or otherwise cause an error? Select all that apply.

This was originally erronenously not a select-all-that-apply question, so dropped.

Regrade request

Consider the following Makefile:

all: a b c

a: e f g
    buildA

b: a
    buildB

c: a b d
    buildC

Assume:

Question 2 (4 pt; mean 3.87) (see above)

Which of the following executions are valid after running make? Select all that apply.

Regrade request

Consider the file /etc/config.txt which has owner 10, group 134, and permissions (represented in octal) 000.

The system storing that file has the following group membership table:

group id user id
13410
13499
1451311
14510

User 10 runs the following commands:

$ chmod 640 /etc/config.txt
$ chmod u+w /etc/config.txt
$ chmod g-e /etc/config.txt
Question 3 (4 pt; mean 3.92) (see above)

Which of the following executions are possible? Select all that are possible.

Regrade request
Question 4 (4 pt; mean 3.57)

Suppose one is using a single-core Linux system and running the following C snippet in process A:

unsigned int x = fgetc(stdin);
unsigned int y = fgetc(stdin);
for (int i = 0; i < 100000000; i += 1) {
    x += y;
}
printf("%u\n", x);

After one provides input to the program and before it computes the final value of x, another process, process B, on the system outputs a message to the terminal and exits. Then, process A finishes its computation and outputs the final value of x.

Which of the following is true about this situation? Select all that apply.

Regrade request
Return to course pageReturn to index 

quiz for week 3

Question 1 (4 pt; mean 3.55)

Consider a single-core system, running two processes A and B. Process A runs

fgets(buffer, sizeof buffer, stdin);

to read in the input line "1234\n" from the keyboard.

The user using this program types "12" well before the program calls fgets, and then the user waits a while, then types "34" and presses enter.

Meanwhile, process B tries to perform as many calculations as possible when it gets to run. The OS contexts switches to process B whenever the process A does not need the processor. The OS also uses hardware exceptions to learn about keyboard input.

Which of the following is true about this scenario? Select all that apply.

Regrade request

Suppose two processes, one with PID 1000 and one with PID 2001 are running the same program and both running as the same user. In both processes, the function handle_usr1 below is setup as a signal handler for SIGUSR1 and handle_usr2 is setup as a signal handler for SIGUSR2:

1.  void handle_usr1(int signum) {
2.      write(STDOUT_FILENO, "A", 1);
3.  }

4.  void handle_usr2(int signum) {
5.      write(STDOUT_FILENO, "B", 1);
6.      kill(1000, SIGUSR1);
7.      write(STDOUT_FILENO, "C", 1);
8.  }

Assume all relevant header files are included, no signals are blocked except as noted below, and that no other code in the program will write output or cause the programs to exit.

write(STDOUT_FILENO, "X", 1) outputs the character X to stdout.

Question 2 (5 pt; mean 4.82) (see above)

If SIGUSR2 is sent to PID 2001, which of the following are possible outcomes? Select all that apply.

Regrade request
Question 3 (4 pt; mean 2.86) (see above)

Assume there is a helper function called mask_sigusr1 in the program that adds SIGUSR1 to the signal mask for the process so that SIGUSR1 is blocked. Where can mask_sigusr1(); be added to the program so that A is not output when SIGUSR2 is sent to PID 2001?

Regrade request
Question 4 (4 pt; mean 3.92)

Consider the following code that uses fork():

pid_t pid;

char str[20] = "foo";
pid = fork();
if (pid == 0) {
    strcat(str, "bar");
    printf("%s\n", str);
    exit(0);
} else {
    strcat(str, "quux");
    printf("%s\n", str);
}
printf("%s\n", str);

(Assume all required header files are included.)

Which of the following are possible outputs? Select all that apply.

Regrade request
Return to course pageReturn to index 

quiz for week 4

Consider the following C code:

pid_t p1, p2;
p1 = fork();
p2 = fork();
int status;
if (p1 == 0 && p2 == 0) {
    write(STDOUT_FILENO, "A", 1);
    exit(1);
} else if (p1 == 0 || p2 == 0) {
    write(STDOUT_FILENO, "B", 1);
    exit(2);
} else {
    int status;
    write(STDOUT_FILENO, "C", 1);
    waitpid(p1, &status, 0);
    write(STDOUT_FILENO, "D", 1);
    waitpid(p2, &status, 0);
    write(STDOUT_FILENO, "E", 1);
}

Assume appropriate header files are included and the code is placed in a function and that fork, exit, and printf do not fail.

Question 1 (4 pt; mean 3.6) (see above)

How many of the processes created by the above code (if any) are not waitpid'd for by the above code?

Answer:
Key: 1
Regrade request
Question 2 (4 pt; mean 3.82) (see above)

One possible output of the above code is BBACDE. Which, if any, of the following is another? Select all that apply.

Regrade request
Question 3 (4 pt; mean 3.2)

Consider the following C code:

int fds[2];
pid_t pids[2];

pipe(fds);

for (int i = 0; i < 2; i += 1) {
    pids[i] = fork();
    if (pids[i] == 0) {
        char c;
        read(fds[0], &c, 1);
        write(STDOUT_FILENO, &c, 1);
        exit(0);
    }
}

write(fds[1], "AB", 2);
write(STDOUT_FILENO, "C", 1);
for (int i = 0; i < 2; i += 1) {
    int status;
    waitpid(pids[i], &status, 0);
}

One possible output of the above code is CAB. Which, if any of the following are additional possible outputs of the above code? Select all that apply.

Regrade request
Question 4 (4 pt; mean 3.76)

Consider the following C code:

int fd1 = 100;
pid_t pid;

pid = fork();
if (pid == 0) {
    int fd2 = open("newfile.txt", O_CREAT | O_RDWR | O_TRUNC);
    dup2(fd2, 100);
    close(fd2);
}
write(fd1, "hello", 5);
if (pid != 0) {
    waitpid(pid, NULL, 0);
}

Assume fork() and open() are successful, and that only stdin, stdout, and stderr are open before the code snippet starts. After the code finishes, what are possible contents of newfile.txt? Select all that apply.

Regrade request
Return to course pageReturn to index 

quiz for week 5

Consider a system with 1024-byte pages and the following page table:

virtual page number (in binary)validphysical page number (in binary)
0000----
00111000
01011010
0110----
10011001
10111111
1100----
11110011
Question 1 (4 pt; mean 3.16) (see above)

What is a virtual address that maps to the physical address 0x3C0F? Write your answer as a hexadecimal number. If there is no such virtual address write "impossible".

Answer:
Key: 0x140f

0x3C0f = [PPN: 11 11][page offset: 00 0000 1111]; want VPN 101 + same page offset: [VPN: 1 01][00 0000 1111]

Regrade request
Question 2 (4 pt; mean 3.73) (see above)

The total number of bytes of memory that the program running with this page table can access without an exception occurring is _____.

Answer:
Key: 1024 * 5 = 5120
Regrade request

Suppose we had a system with a 32-bit virtual addresses, 32768-byte pages, and (single-level) page tables containing 4-byte page table entries.

Suppose a process is running on this system and can access memory at addresses 0x0-0x1FFFFF and 0xF000000-0xF00FFFFF without an exception occurring.

Question 3 (4 pt; mean 3.85) (see above)

The process attempts to access addresses 0x200000-0x2FFFFF and the operating system uses the allocate-on-demand strategy we discussed in lecture to populate this memory as the process accesses it.

Suppose that each time page fault (an exception triggered when a program tries to access a page which is not valid in the page table) occurs, the operating system does the minimum modification to the page tables needed to make the access that triggered the page fault work. How many page faults will occur as part of the allocate-on-demand operation?

Answer:
Key: 32
Regrade request

Consider a system with a (single-level) page table stored in memory as an array, where:

Question 4 (4 pt; mean 3.5) (see above)

Suppose when a program attempts to read the value on top of its stack, the processor accesses a page table entry at address 0x100340 and finds the value 0x400000F. What is a possible value of the program's stack pointer? Write your answer as a hexadecimal number.

Answer:
Key: 0x68xxx (where 'x' is any hexadecimal digit)

0x340/8 = 0x68 = virtual page number

Regrade request
Return to course pageReturn to index 

quiz for week 6

Question 1 (4 pt; mean 2.84)

Suppose a system uses:

When accessing the virtual address 0x99120000, the system reads a first-level page table entry which contains physical page number 0x4000. (The physical page with page number 0x4000 starts at physical address 0x10000000.) Then, it will access a second-level page table entry at physical address ___.

If not enough information is given write "unknown" and explain briefly in the comments.

Answer:
Key: 0x10002240
Regrade request

Suppose a direct-mapped cache (with 8 sets and 2-byte blocks) has the following contents:

set indextag (written in binary)validdata bytes (in hexadecimal; lowest address first)
00
1111102 FF
2111101 11
3100133 55
40
50111AA BB
6110109 0C
7110119 2C
Question 2 (4 pt; mean 3.73) (see above)

The cache stores the byte 0xBB. What was its original memory address? Write your answer as hexadecimal or binary number.

Answer:
Key: 011 101 1 = 0x3B
Regrade request
Question 3 (4 pt; mean 3.86) (see above)

Accessing the byte at a memory address with tag 111, index 6, offset 1 using this cache would ____. Select all that apply.

Regrade request
Question 4 (4 pt; mean 3.35)

Suppose a system has two-level page tables with 4096-byte pages and 30-bit virtual addresses. Virtual addresses are divided into a 9-bit first virtual page number part, a 9-bit second virtual page number part, and a 12-bit page offset.

Suppose a program's page tables have valid entries for:

and does not have valid page table entries for any other pages.

What is the minimum number of second-level page tables stored for this program?

Answer:
Key: 3
Regrade request
Return to course pageReturn to index 

quiz for week 10

Question 1 (4 pt; mean 3.97)

Suppose array1 and array2 are arrays of 4-byte ints and we perform the following:

for (int i = 0; i < 10000; i += 1) {
    for (int j = 0; j < 4; j += 4) {
        array1[i] += array2[(i * 3 + j) % 10000];
    }
}

Assume that only accesses to array1 and array2 use the cache and the compiler does not omit any memory accesses to array1 and array2.

Suppose this code runs with a 128-byte 2-way set associative cache with 8-byte blocks that is initially empty.

Which of the following changes would be likely to increase the number of cache misses the code experiences?

  1. probably bad for miss rate, but not clearly so in this case. Would definitely would be true with j += 1.

  2. would be true with j += 1

[edited 25 March 4pm]: probably should have written j += 1 instead of j += 4; at a quick glance, it looked like this shouldn't affect answers, but it does.

Regrade request

Suppose a system uses a 2-way set associative write-back, write-allocate cache with 16 sets, 16-byte blocks, and a LRU replacement policy. The cache starts empty.

Question 2 (4 pt; mean 3.57) (see above)

The following one-byte reads and writes occur in order:

1. write to address  0x275
2. write to address  0xa39
3. write to address  0x079
4. read from address 0x670
5. write to address  0xa49
6. write to address  0x231
7. read from address 0x231
8. read from address 0x531
9. read from address 0x640

Which reads/writes will result in a write to main memory? (Write the numbers of the accesses above; for example if you think steps 1 and 4 trigger a write to main memory, write "14")

Answer:
Key: 48
Regrade request
Question 3 (4 pt; mean 3.65) (see above)

Assume the system uses 20 bit addresses. What is the total size of the cache metadata, in bits?

Answer:
Key: 464

per block: tag=12 bits, valid=1 bit, dirty=1 bit. per set: lru=1 bit. 32 blocks * 14 bits + 16 sets * 1 bit = 464 bits

Regrade request
Question 4 (4 pt; mean 4)

Suppose a system has a 4-way TLB with 128 entries on a system with 65536-byte pages.

A program accesses virtual address 0x123456 that, given the program's memory layout, corresponded to physical address 0x234567. When performing this access, the processor reads a TLB entry as part of completing the access and therefore avoids doing a page table lookup.

The processor might access a different TLB entry in the same set if the program accessed ___. Select all that apply.

We made an error in the information for this question since virtaul address 0x123456 can only correspond to a physical address with the same page offset, so we have dropped it.

Regrade request
Return to course pageReturn to index 

quiz for week 11

Consider the following code that uses the pthreads API. (Needed #includes and some similar other details are omitted.)

struct FileInfo {
    bool in_use;
    char *filename;
    bool readable;
    long num_lines;
};
pthread_mutex_t file_list_lock = PTHREAD_MUTEX_INITIALIZER;
struct FileInfo file_list[100];

int RecordFileInfo(char *filename, bool readable, long num_lines) {
    pthread_mutex_lock(&file_list_lock);
    for (int i = 0; i < 100; i += 1) {
        if (!file_list[i]->in_use) {
            file_list[i].in_use = true;
            file_list[i].filename = filename;
            file_list[i].readable = readable;
            file_list[i].num_lines = num_lines;
        }
    }
    pthread_mutex_unlock(&file_list_lock);
}

void *CountLinesAndRecordThread(void *arg) {
    char *filename = arg;
    FILE *fh = fopen(filename, "r");
    long num_lines = 0;
    bool readable;
    if (fh != NULL) {
        char temp[2048];
        while (fgets(temp, sizeof temp, fh)) {
            num_lines += 1;
        }
        readable = true;
    } else {
        readable = false;
    }
    RecordFileInfo(filename, readable, num_lines);
    fclose(fh);
    return NULL;
}

void ProcessFiles() {
    pthread_t t1, t2;
    pthread_create(&t1, NULL, CountLinesAndRecordThread, "file1");
    pthread_create(&t2, NULL, CountLinesAndRecordThread, "file2");
    pthread_join(t1);
    pthread_join(t2);
}
Question 1 (2 pt; mean 1.46) (see above)

When ProcessFiles is run, the function RecordFileInfo will run. In the function RecordFileInfo, the line file_list[i].filename = filename; will copy a value from _____ into a file_list[i].filename.

Regrade request
Question 2 (4 pt; mean 3.52) (see above)

When ProcessFiles is called, the line file_list[i].in_use = true could run at the same time as ____. (Assume initially only the thread running ProcessFiles exists.) Select all that apply.

Regrade request
Question 3 (6 pt; mean 5.72)

Consider the following pseudocode library for a game where players try to change count to equal goal and be the first to call check when count matches goal.

pthread_mutex_t count_lock = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t goal_lock = PTHREAD_MUTEX_INITIALIZER;

int goal = 10;
int count = 0;

void change_goal(int new_goal) {
  pthread_mutex_lock(&goal_lock);
  goal = new_goal;
  pthread_mutex_unlock(&goal_lock);
}

void increment() {
  pthread_mutex_lock(&count_lock);
  count += 1;
  pthread_mutex_unlock(&count_lock);
}

void decrement() {
  pthread_mutex_lock(&goal_lock);
  pthread_mutex_lock(&count_lock);
  count -= 1;
  pthread_mutex_unlock(&goal_lock);
  pthread_mutex_unlock(&count_lock);
}

bool check() {
  pthread_mutex_lock(&count_lock);
  pthread_mutex_lock(&goal_lock);
  if (goal == count) printf("Winner! Goal %d reached.\n", goal);
  pthread_mutex_unlock(&goal_lock);
  pthread_mutex_unlock(&count_lock);
}

Assume there are exactly three threads playing this game. The threads can only access count_lock, goal_lock, goal, and count using the functions listed. No other threads are accessing this library.

What is possible while this game is being played? Select all that apply.

Regrade request
Question 4 (4 pt; mean 3.92)

Consider the following program (assume all necessary headers are included).

size_t* weights[3];

void* A(void* argument) {
  int index = (int) argument;
  weights[index] = malloc(sizeof(size_t));
  return NULL;
}

void* B(void* argument) {
  int index = (int) argument;
  size_t val = 7;
  weights[index] = &val;
  return NULL;
}

void* C(void* argument) {
  int index = (int) argument;
  weights[index] = (size_t*) C;
  return NULL;
}

int main() {
  pthread_t p1, p2, p3;

  if (0 != pthread_create(&p1, NULL, A, 0)) handle_error();
  if (0 != pthread_create(&p2, NULL, B, 1)) handle_error();
  if (0 != pthread_create(&p3, NULL, C, 2)) handle_error();

  if (0 != pthread_join(p1, NULL)) handle_error();
  if (0 != pthread_join(p2, NULL)) handle_error();
  if (0 != pthread_join(p3, NULL)) handle_error();
}

At the end of main() (before main returns), which pointers are valid? (Consider a pointer valid if it points to accessible memory, even if interpreting that memory as a size_t might be dubious.) Select all that apply.

Regrade request
Return to course pageReturn to index 

quiz for week 12

Consider the following code that uses the pthreads API:

pthread_mutex_t lock;
bool seat_occupied[100];
pthread_cond_t cv;

void WaitForSeat(int index) {
    pthread_mutex_lock(&lock);
    while (seat_occupied[index]) {
        pthread_cond_wait(&cv, &lock);  /* PLACE A */
    }
    pthread_mutex_unlock(&lock);
}

void WaitForTwoSeats(int index1, int index2) {
    pthread_mutex_lock(&lock);
    while (seat_occupied[index1] || seat_occupied[index2]) {
        pthread_cond_wait(&cv, &lock);  /* PLACE B */
    }
    pthread_mutex_unlock(&lock);
}

bool FreeSeat(int index) {
    pthread_mutex_lock(&lock);
    seat_occupied[index] = false;
    pthread_cond_broadcast(&cv);       /* PLACE C */
    pthread_mutex_unlock(&lock);
}
Question 1 (4 pt; mean 3.89) (see above)

Which (if any) of the following could happen if we replaced the pthread_cond_broadcast (in FreeSeat) with a call to pthread_cond_signal?

Regrade request
Question 2 (6 pt; mean 5.77) (see above)

The above code uses one condition variable, even though, logically, we should have separate conditions for each seat.

To avoid this, we could replace

pthread_cond_t cv;

with an array

pthread_cond_t cvs[100];

and change the line marked PLACE A to

pthread_cond_wait(&cvs[index], &lock);

and change the line marked PLACE C to

pthread_cond_broadcast(&cvs[index]);

If we did this, which of the following are valid options to fix the code at PLACE B? Select all that apply.

  1. accepted not selecting on the basis of this not solving the "separate conditions" issue, even though it is functional [edited 2 May 2025]

Regrade request

Suppose two machines use the scheme of resending after a timeout if no acknowledgment is received we discussed in lecture to communicate reliably using the mailbox model.

Machine A is sending 150 messages with data to machine B. Assume machine A waits for a message with data to be acknowledged before sending the next message with data.

Suppose it takes 1 time unit to transmit a message (data or acknowledgment) from machine A to machine B or vice-versa, and machine A has a timeout of 4 time units.

Question 3 (4 pt; mean 3.69) (see above)

If no messages are lost, how many time units will it take until machine B receives all 150 messages?

Answer:
Key: 2 * 149 (send message + recv acknowledgement) + 1 (send last message, acknowledgment sent back after B receives last message) = 299
Regrade request
Question 4 (4 pt; mean 3.35) (see above)

If every 60th message B attempts to send starting with its first is lost, then how many more time units will it take until machine B receives all 150 messages compared to when no messages were lost?

Answer:
Key: 12

also accepted 8, because we don't care about differences related to which message is lost first

4 time units wasted each time; OR

was originally keyed off-by-one [accepted off-by-one number of lost ACKs answer];

B sends ACK for 1 (lost), then sends ACK for 1-60, then 61 (lost), then 60-120 (success), then 121 (lost). When no ACK is lost and we need to wait for the ACK to be received, it takes 2 time units to complete the transmission (data messages 2-60, 61-120, 122-149). When an ACK is lost, it takes 4 time units for the timeout to expire, plus 2 extra time units to complete the retransmission+ACK (data messages 1, 61, 121). For the last message, we don't need to count the time sending the ACK (data message 150). Total time is (59 + 59 + 28)2 + 3(4+2) + 1 = 311 versus 299 = 12

Regrade request
Return to course pageReturn to index 

quiz for week 13

Suppose we have a server to handle course registration that uses the following insecure protocol to communicate with clients run on behalf of registering students. Both the server and client have a keypair for asymmetric encryption and a keypair for digital signatures. In advance, the server and client share the public keys for each of these keypairs.

Question 1 (4 pt; mean 3.93) (see above)

A client attempts to add four courses, of which three are successfully added. Then the client drops two courses, which is successful.

An passive eavesdropping attacker could determine ____. Select all that apply.

Regrade request
Question 2 (4 pt; mean 3.63) (see above)

A client attempts to add two courses, then add two additional courses. Normally, adding the first two courses is successful, but one of the second two courses fails.

Assuming client and server always check digital signtures, an "machine-in-the-middle" attacker could manipulate these requests and the server response's so that ____.

  1. the MITM can make the server think the client attmpted to re-add the same courses in their second request that they asked to add in their first. This didn't match our intention of "add different courses than they actually requested", but we felt it was an acceptable interpretation.

Regrade request
Question 3 (4 pt; mean 3.93)

Suppose we have six-stage pipelined processor with a cycle time of 400 ps.

When running a function with 14 instructions, if we fetch the first instruction at time 0 ps, then the earliest time the last instruction could finish is in _____ ps. (Assume instructions do not finish until they complete their final stage.)

Answer:
Key: 400 * 14 + (6-1) * 400 = 7600 ps
Regrade request
Question 4 (4 pt; mean 3.78)

Suppose we take a single-cycle processor with a cycle time of 1 ns. It takes 1.00 s to run a program.

If we modify that processor by adding registers into a multi-cycle pipelined processor, then which of the following would be a plausible result when running the same program? Select all that apply.

Regrade request
Return to course pageReturn to index 

quiz for week 14

Consider a 7-stage pipelined processor that uses the same stages we discussed in lecture, except the decode and memory stages are split, so the stages are

The split stages need the same inputs near the beginning of the clock cycle and only make their outputs (the register values for decode and the value read from the data cache for memory) near the end of the clock cycle for part 2.

The processor uses forwarding in combination with, when necessary, stalling to resolve data hazards.

Also, the processor uses branch (jump target) prediction where it guesses that all conditional jumps are taken; on a misprediction, it fetches the correct target (and squashes the incorrectly fetched instructions) during the conditional jump's memory part 1 stage.

Question 1 (4 pt; mean 2.81) (see above)

Consider the following assembly code:

addq %r8, %r9
movq 8(%r9), %r13
subq %r13, %r8

If the addq instruction starts during cycle 0, then the subq will complete its writeback stage in cycle ___.

Answer:
Key: 6 (cycle addq does writeback) + 2 (writeback for two more instructions) + 2 (cycle delay between movq and subq waiting for memory part 2 to finish before starting subq's execute) = 10
Regrade request
Question 2 (6 pt; mean 5.61) (see above)

Consider the following assembly code:

addq %r8, %r9
xorq %r9, %r8
cmpq %r8, %r9
jle foo
subq %r9, %r8

Assume the comparison result is "greater than" so the next instruction that should complete after the jle is the subq. When the above code runs, which of the following forwarding is likely to occur? (It's possible that not all needed forwarding is listed.) **Select all that apply.*

Regrade request
Question 3 (4 pt; mean 3.61)

Suppose an out-of-order processor with many functional units executes the following assembly snippet:

addq %r10, %r11
subq %r11, %r12
movq (%r11), %r12
xorq %r12, %r11
movq %r10, (%r13)

The movq (%r11), %r12 instruction could execute (perform its data cache operation) at the same time as ____ executes (performs its data cache and/or arithmetic operation). Select all that apply.

Regrade request
Question 4 (3 pt; mean 2.94)

Suppose an out-of-order processor that uses register renaming is executing the following loop:

begin:  subq $1, %r8
        addq %r10, %r11
        cmpq %r8, %r9
        jle begin

Assuming this loop runs for many iterations, then most likely ___. Select all that apply.

Regrade request
Return to course pageReturn to index 

quiz for week 15

Question 1 (4 pt; mean 2.77)

Consider the following C function:

#define LEN 8
char hidden_string[LEN];

bool is_hidden_rotated(char *input_string) {
    for (int offset = 0; offset < LEN; offset += 1) {
        bool maybe_match = true;
        for (int i = 0; maybe_match && i < LEN; i += 1) {
            if (input_string[i] != hidden_string[(offset + i) % LEN]) {
                maybe_match = false;
            }
        }
        if (maybe_match) return true;
    }
    return false;
}

Assume that the compiler does not omit any of the comparison or array accesses shown above.

Suppose we can call this function and observe how long it takes and how fast cache accesses are after the function runs and know that an input of ABCDEFGH returns true. But we cannot directly observe the value of hidden_string.

What would be the best strategy to find out the value of hidden_string?

Regrade request
Question 2 (5 pt; mean 4.66)

Suppose we run the following pseudocode:

char array[CACHE_SIZE];
...
for (int i = 0; i < CACHE_SIZE; i += 1) {
    array[i] = 0;
}
*pointer += 1;
for (int i = 0; i < CACHE_SIZE: i += 1) {
    if (TimeToAccess(&array[i]) >= THRESHOLD) {
        WasSlow(i);
    }
}

If we have a system without virtual memory with a 4-way 512KB (524288 byte) cache with 256-byte blocks and an LRU replacement policy, the array is placed at address 0x14000000. If WasSlow is called with i set to 512, then which (if any) of the following are possible values of pointer? Select all that apply.

  1. we intended the array to be at 0x140 0000 not 0x1400 0000, which would make this and the next option false, but did not --- and it's more subtle an issue than we wanted to score on

Regrade request
Question 3 (4 pt; mean 3.1)

Consider the following C code:

int array[1000];
int some_value;

...

array[mystery * 2] += some_value;
array[mystery * 3] += some_value;

Suppose we run the above code on a system without virtual memory and with a 2-way 64KB (65536 byte) data cache with 32-byte cache blocks.

If array is located at address 0x10004000 and we discover that running the above += operations accesses data cache set indices 514, 515, and 739.

Based on this, what is a plausible value of mystery?

Answer:
Key: 8 or 9 or 10

array occupies cache indices 512 through 637; so 739 must be some_value and/or mystery

8 ints per cache block

need mystery * 2 to map to cache index 514 and mystery * 3 to cache index 515

2 * 8 <= mystery * 2 < 3 * 8; so mystery >= 8 and mystery < 3 * 8 / 2 = 12

3 * 8 <= mystery * 3 < 4 * 8; so mystery >= 8 and mystery < 4 * 8 / 3 = 10.6

Regrade request
Question 4 (4 pt; mean 0.38)

Consider the following C-like psuedocode:

struct FileInfo {
    int is_socket;
    int socket_index;
    ...
};
struct FileInfo all_files[4096];
...

struct SocketInfo {
    unsigned long local_address;
    unsigned long remote_address;
    unsigned short remote_port;
    unsigned short local_port;
    ...
};

struct SocketInfo all_sockets[4096];

int GetLocalPortFor(int file_number)  {
    if (file_number < 0 || file_number >= 4096) {
        return -1;
    } else if (!all_files[file_number].is_socket) {
        return -1;
    } else {
        int socket_index = all_files[file_number].socket_index;
        struct SocketInio *socket_info = &all_sockets[socket_index];
        return socket_info->local_port;
    }
}

Suppose the above code runs in an OS kernel in kernel mode and the GetLocalPortFor function is callable via a system call.

Assuming no mitigations are made to prevent it, this function could be vulnerable to a Spectre-style attack based on the memory access to local_port. In a successful attack, the attacker will learn about a value in memory at a target address of their choice.

When executing the Spectre-style attack, we should choose file_number such that the target address is located in the same place as the address that would be computed for ____.

Regrade request
Return to course pageReturn to index